diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c index 3ea6662cc28..92f9bb2ce53 100644 --- a/ntoskrnl/mm/ARM3/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -879,7 +879,6 @@ MiSnapThunk(IN PVOID DllBase, Address->u1 = ForwardThunk.u1; break; } - /* Go to the next entry */ NextEntry = NextEntry->Flink; } @@ -992,8 +991,9 @@ MiResolveImageReferences(IN PVOID ImageBase, OUT PLOAD_IMPORTS *LoadImports) { static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\"); + static ANSI_STRING xboxkrnlSysName = RTL_CONSTANT_STRING("xboxkrnl.sys"); PCHAR MissingApiBuffer = *MissingApi, ImportName; - PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport; + IMAGE_IMPORT_DESCRIPTOR InnerImportDescriptor[2],*ImportDescriptor, *CurrentImport; ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize; PLOAD_IMPORTS LoadedImports, NewImports; ULONG GdiLink, NormalLink, i; @@ -1017,19 +1017,33 @@ MiResolveImageReferences(IN PVOID ImageBase, *LoadImports = MM_SYSLDR_NO_IMPORTS; /* Get the import descriptor */ - ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase, + PIMAGE_XBE_HEADER header = ImageBase; + if(header->dwMagic == IMAGE_XBE_SIGNATURE){ + MmEnforceWriteProtection = FALSE; + InnerImportDescriptor[0].Name = (ULONG_PTR)xboxkrnlSysName.Buffer - (ULONG_PTR)ImageBase; + InnerImportDescriptor[0].OriginalFirstThunk = (UINT_PTR)header->dwKernelImageThunkAddr - (ULONG_PTR)ImageBase; + InnerImportDescriptor[0].FirstThunk = InnerImportDescriptor[0].OriginalFirstThunk; + InnerImportDescriptor[1].OriginalFirstThunk = 0L; + InnerImportDescriptor[1].Name = 0L ; + + ImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)&InnerImportDescriptor; + ImportCount = 0; + } + else{ + ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportSize); + } + if (!ImportDescriptor) return STATUS_SUCCESS; /* Loop all imports to count them */ for (CurrentImport = ImportDescriptor; @@ -2768,6 +2785,9 @@ MmCheckSystemImage(IN HANDLE ImageHandle, goto Fail; } + if(((PIMAGE_XBE_HEADER)ViewBase)->dwMagic == IMAGE_XBE_SIGNATURE) + goto Fail; //NO NT headers on XBE + /* Make sure it's a real image */ NtHeaders = RtlImageNtHeader(ViewBase); if (!NtHeaders) @@ -2894,7 +2914,6 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName, HANDLE FileHandle = NULL; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - PIMAGE_NT_HEADERS NtHeader; UNICODE_STRING BaseName, BaseDirectory, PrefixName; PLDR_DATA_TABLE_ENTRY LdrEntry = NULL; ULONG EntrySize, DriverSize; @@ -3193,6 +3212,7 @@ LoaderScan: FileName, FALSE, NULL); + ASSERT(Status != STATUS_ALREADY_COMMITTED); /* Get the size of the driver */ @@ -3223,21 +3242,156 @@ LoaderScan: goto Quickie; } - /* Relocate the driver */ - Status = LdrRelocateImageWithBias(ModuleLoadBase, - 0, - "SYSLDR", - STATUS_SUCCESS, - STATUS_CONFLICTING_ADDRESSES, - STATUS_INVALID_IMAGE_FORMAT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status); - goto Quickie; - } - /* Get the NT Header */ - NtHeader = RtlImageNtHeader(ModuleLoadBase); + PVOID EntryPoint; + int MajorOperatingSystemVersion=5, MajorImageVersion=5,CheckSum; + + PIMAGE_XBE_HEADER pidhXbeHeader = (PIMAGE_XBE_HEADER)ModuleLoadBase; + if(pidhXbeHeader->dwMagic == IMAGE_XBE_SIGNATURE){ + UINT_PTR EntryPoint2 = ((UINT_PTR)(pidhXbeHeader->dwEntryAddr ^ 0x94859D4B)); // Debug + if(EntryPoint2 <= (UINT_PTR)pidhXbeHeader->dwBaseAddr || EntryPoint2 >= (UINT_PTR)(pidhXbeHeader->dwBaseAddr+pidhXbeHeader->dwSizeofImage)) + EntryPoint2 = ((UINT_PTR)(pidhXbeHeader->dwEntryAddr ^ 0xA8FC57AB)); // Retail + + + UINT* kernelImageThunk = (UINT*)(pidhXbeHeader->dwKernelImageThunkAddr ^ 0xEFB1F152); //DEBUG + if( (kernelImageThunk <= (UINT*)pidhXbeHeader->dwBaseAddr) || (kernelImageThunk >= (UINT*)(pidhXbeHeader->dwBaseAddr + pidhXbeHeader->dwSizeofImage))) + kernelImageThunk = (UINT*)(pidhXbeHeader->dwKernelImageThunkAddr ^ 0x5B6D40B6); //RETAIL + + pidhXbeHeader->dwEntryAddr = EntryPoint2 + (UINT_PTR)ModuleLoadBase; + + IMAGE_XBE_SECTION_HEADER* pishSectionHeaders = (PVOID)((UINT_PTR)pidhXbeHeader + pidhXbeHeader->dwSectionHeadersAddr - pidhXbeHeader->dwBaseAddr); + + UINT_PTR delta = (UINT_PTR)ModuleLoadBase - pidhXbeHeader->dwBaseAddr; + + for(int i = pidhXbeHeader->dwSections - 1; i>=0; i--) + { + pishSectionHeaders[i].dwSectionNameAddr = (UINT_PTR)pidhXbeHeader+pishSectionHeaders[i].dwSectionNameAddr-pidhXbeHeader->dwBaseAddr; + CHAR* sectionName = (CHAR*)pishSectionHeaders[i].dwSectionNameAddr; + if (!strcmp(".text",sectionName)){ + UINT8* Start=(UINT8*)((UINT_PTR)pidhXbeHeader+pishSectionHeaders[i].dwVirtualAddr); + UINT8* End=Start+pishSectionHeaders[i].dwVirtualSize; + for(UINT8* pAddr= Start;pAddr<=End;pAddr++){ + UINT* pAddrLong = (UINT*)pAddr; + + if(*pAddrLong >= pidhXbeHeader->dwBaseAddr && *pAddrLong <= (pishSectionHeaders[pidhXbeHeader->dwSections - 1].dwVirtualAddr+ pishSectionHeaders[pidhXbeHeader->dwSections - 1].dwVirtualSize) ){ + if ((DWORD)kernelImageThunk >= pishSectionHeaders[i].dwVirtualAddr && (DWORD)kernelImageThunk <= (pishSectionHeaders[i].dwVirtualAddr + pishSectionHeaders[i].dwVirtualSize) && *pAddrLong >= 0x80000000 && *pAddrLong <= 0x8000016E ) //imports - some xbe puts them in text segment. I.E. Dolphin demo + pAddr +=3; + else if( + //(*(pAddr-1) == 0x01) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x03) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x09) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x0b) || //check - INCOMPLETE encoding + //((*(pAddr-2) == 0x0f && //check - INCOMPLETE encoding + // ((*(pAddr-1) >= 0x40 && *(pAddr-1) <= 0x4F) || *(pAddr-1) == 0xa4 || *(pAddr-1) == 0xa5 || *(pAddr-1) == 0xac || *(pAddr-1) == 0xb1 || *(pAddr-1) == 0xb3 || (*(pAddr-1) >= 0xb8 && *(pAddr-1) <= 0xbf) || *(pAddr-1) == 0xd1) )) || + //(*(pAddr-1) == 0x11) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x13) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x19) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x1b) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x21) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x23) || //check - INCOMPLETE encoding + (*(pAddr-2) == 0x2b && + *(pAddr-1) == 0x05) || + (*(pAddr-1) == 0x2d) || //check + //(*(pAddr-1) == 0x31) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x38) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x39) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x3b) || //check - INCOMPLETE encoding+crash + //(*(pAddr-1) == 0x62) || //check - INCOMPLETE encoding + (*(pAddr-1) == 0x68) || + (*(pAddr-1) == 0x69) || //check + //(*(pAddr-1) == 0x6b) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x83) || //check - INCOMPLETE encoding+crash + //(*(pAddr-1) == 0x85) || //check - INCOMPLETE encoding+crash + //(*(pAddr-1) == 0x87) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0x89) || //check - INCOMPLETE crash + (*(pAddr-2) == 0x8b && + (*(pAddr-1) == 0x0d || + *(pAddr-1) == 0x1d || + *(pAddr-1) == 0x35 )) || + //(*(pAddr-1) == 0x8f) || //check - INCOMPLETE encoding + (*(pAddr-1) == 0xa1) || + (*(pAddr-1) == 0xa3) || + //(*(pAddr-1) == 0xa7) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xab) ||//check - INCOMPLETE encoding + //(*(pAddr-1) == 0xad) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xaf) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xc1) ||//check - INCOMPLETE crash + //(*(pAddr-1) == 0xc3) ||//check - INCOMPLETE crash + (*(pAddr-2) == 0xc7 && + *(pAddr-1) == 0x05) || + //(*(pAddr-1) == 0xd3) || //check - INCOMPLETE encoding+crash + //(*(pAddr-1) == 0xd8) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xd9) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xda) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xdb) || //check - INCOMPLETE encoding + //(*(pAddr-1) == 0xf7) || //check - INCOMPLETE encoding+crash + (*(pAddr-2) == 0xff && + (*(pAddr-1)==0x15 || + *(pAddr-1)==0x35)) + ){ + if(*pAddrLong <= (pidhXbeHeader->dwCertificateAddr + sizeof(IMAGE_XBE_CERTIFICATE_HEADER))){ + *pAddrLong += delta; + pAddr += 3; + } + else + { + for(int j = pidhXbeHeader->dwSections - 1; j>=0; j--){ + if(*pAddrLong >= pishSectionHeaders[j].dwVirtualAddr){ + *pAddrLong += -pishSectionHeaders[j].dwVirtualAddr + ALIGN_DOWN_BY(pishSectionHeaders[j].dwVirtualAddr,PAGE_SIZE) + (UINT_PTR)ModuleLoadBase; + pAddr += 3; + break; + } + } + } + } + } + } + } + + pishSectionHeaders[i].dwVirtualAddr = ALIGN_DOWN_BY(pishSectionHeaders[i].dwVirtualAddr,PAGE_SIZE)+delta; + pishSectionHeaders[i].dwHeadSharedRefCountAddr += delta; + pishSectionHeaders[i].dwTailSharedRefCountAddr += delta; + DPRINT1("SIMONE - i=%d dwVirtualAddr=%X SectionName=%s bPreload=%d\n",i,pishSectionHeaders[i].dwVirtualAddr,sectionName,pishSectionHeaders[i].dwFlags.bPreload); + } + pidhXbeHeader->dwKernelImageThunkAddr = (DWORD)kernelImageThunk + (UINT_PTR)ModuleLoadBase; + + PIMAGE_XBE_TLS_HEADER TLSHeader = (PIMAGE_XBE_TLS_HEADER)(pidhXbeHeader->dwTLSAddr + (UINT_PTR)ModuleLoadBase); + TLSHeader->dwTLSIndexAddr += (UINT_PTR)ModuleLoadBase; + + pidhXbeHeader->dwBaseAddr = (DWORD)ModuleLoadBase; + pidhXbeHeader->dwCertificateAddr += delta; + pidhXbeHeader->dwSectionHeadersAddr += delta; + pidhXbeHeader->dwPeBaseAddr += delta; + pidhXbeHeader->dwDebugPathnameAddr += delta; + pidhXbeHeader->dwDebugFilenameAddr += delta; + pidhXbeHeader->dwDebugUnicodeFilenameAddr += delta; + + pidhXbeHeader->dwNonKernelImportDirAddr += delta; + pidhXbeHeader->dwLibraryVersionsAddr += delta; + pidhXbeHeader->dwKernelLibraryVersionAddr += delta; + pidhXbeHeader->dwXAPILibraryVersionAddr += delta; + pidhXbeHeader->dwLogoBitmapAddr += delta; + } + else{ + /* Relocate the driver */ + Status = LdrRelocateImageWithBias(ModuleLoadBase, + 0, + "SYSLDR", + STATUS_SUCCESS, + STATUS_CONFLICTING_ADDRESSES, + STATUS_INVALID_IMAGE_FORMAT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status); + goto Quickie; + } + PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader(ModuleLoadBase); + EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase + + NtHeader->OptionalHeader.AddressOfEntryPoint); + CheckSum = NtHeader->OptionalHeader.CheckSum; + MajorOperatingSystemVersion = NtHeader->OptionalHeader.MajorOperatingSystemVersion; + MajorImageVersion = NtHeader->OptionalHeader.MajorImageVersion; + } /* Calculate the size we'll need for the entry and allocate it */ EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) + @@ -3260,8 +3414,8 @@ LoaderScan: LdrEntry->PatchInformation = NULL; /* Check the version */ - if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) && - (NtHeader->OptionalHeader.MajorImageVersion >= 5)) + if ( (MajorOperatingSystemVersion>= 5) && + (MajorImageVersion >= 5)) { /* Mark this image as a native image */ LdrEntry->Flags |= LDRP_ENTRY_NATIVE; @@ -3269,10 +3423,9 @@ LoaderScan: /* Setup the rest of the entry */ LdrEntry->DllBase = ModuleLoadBase; - LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase + - NtHeader->OptionalHeader.AddressOfEntryPoint); + LdrEntry->EntryPoint = EntryPoint; LdrEntry->SizeOfImage = DriverSize; - LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum; + LdrEntry->CheckSum = CheckSum; LdrEntry->SectionPointer = Section; /* Now write the DLL name */ @@ -3371,7 +3524,9 @@ LoaderScan: MiWriteProtectSystemImage(LdrEntry->DllBase); /* Initialize the security cookie (Win7 is not doing this yet!) */ - LdrpInitSecurityCookie(LdrEntry); + + if(pidhXbeHeader->dwMagic != IMAGE_XBE_SIGNATURE) + LdrpInitSecurityCookie(LdrEntry); /* Check if notifications are enabled */ if (PsImageNotifyEnabled) @@ -3390,10 +3545,10 @@ LoaderScan: #ifdef __ROS_ROSSYM__ /* MiCacheImageSymbols doesn't detect rossym */ - if (TRUE) + if (pidhXbeHeader->dwMagic != IMAGE_XBE_SIGNATURE) #else /* Check if there's symbols */ - if (MiCacheImageSymbols(LdrEntry->DllBase)) + if (MiCacheImageSymbols(LdrEntry->DllBase) && XbeHeader->dwMagic != IMAGE_XBE_SIGNATURE) #endif { UNICODE_STRING UnicodeTemp;