- Timestamp:
- Jul 27, 2024 12:55:53 AM (6 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp
r104611 r105532 268 268 uint32_t NtBuildNumber; 269 269 270 /** The address of the bootmgr image if early during boot. */ 271 DBGFADDRESS BootMgrAddr; 272 /** The address of the winload.exe image if early during boot. 273 * When this is set, f32Bit has also been determined. */ 274 DBGFADDRESS WinLoadAddr; 275 270 276 /** The address of the ntoskrnl.exe image. */ 271 277 DBGFADDRESS KernelAddr; … … 365 371 366 372 #ifdef VBOX_DEBUGGER_WITH_WIN_DBG_PRINT_HOOKING 373 367 374 /** 368 375 * Queries the string from guest memory with the pointer in the given register, sanitizing it. … … 662 669 LogRel(("DigWinNt/DbgPrint: Failed to resolve kernel address space handle\n")); 663 670 } 664 #endif 671 672 #endif /* VBOX_DEBUGGER_WITH_WIN_DBG_PRINT_HOOKING */ 665 673 666 674 /** … … 850 858 851 859 /** 860 * Checks if the given headers are for the BootMgr image loaded very early 861 * during the BIOS boot process. 862 */ 863 static bool dbgDiggerWinNtIsBootMgr(PUVM pUVM, PCVMMR3VTABLE pVMM, PCDBGFADDRESS pAddr, 864 uint8_t const *pbHdrs, size_t cbHdrs, uint32_t *pcbImage) 865 { 866 if (pcbImage) 867 *pcbImage = 0; 868 869 /* 870 * Check and skip the DOS header. 871 */ 872 AssertReturn(sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS32) < cbHdrs, false); 873 IMAGE_DOS_HEADER const * const pMzHdr = (IMAGE_DOS_HEADER const *)pbHdrs; 874 if ( pMzHdr->e_magic != IMAGE_DOS_SIGNATURE 875 || pMzHdr->e_lfanew < 0x40 876 || pMzHdr->e_lfanew > 0x400) 877 return false; 878 879 /* 880 * Check the NT headers. 881 */ 882 AssertReturn(pMzHdr->e_lfanew + sizeof(IMAGE_NT_HEADERS32) <= cbHdrs, false); 883 IMAGE_NT_HEADERS32 const * const pHdrs = (PCIMAGE_NT_HEADERS32)&pbHdrs[pMzHdr->e_lfanew]; 884 if (pHdrs->Signature != IMAGE_NT_SIGNATURE) 885 return false; 886 /* Not so many sections here, typically 3: */ 887 if ( pHdrs->FileHeader.NumberOfSections <= 1 888 || pHdrs->FileHeader.NumberOfSections >= 6) 889 return false; 890 if ( pHdrs->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 891 || pHdrs->FileHeader.SizeOfOptionalHeader != sizeof(pHdrs->OptionalHeader)) 892 return false; 893 if (pHdrs->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) 894 return false; 895 if (pHdrs->OptionalHeader.NumberOfRvaAndSizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES) 896 return false; 897 /* Special subsystem with version 1.0: */ 898 /** @todo which subsystem type does pre win11 use? (this is win11/amd64) */ 899 if (pHdrs->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) 900 return false; 901 if ( pHdrs->OptionalHeader.MajorSubsystemVersion != 1 902 || pHdrs->OptionalHeader.MinorSubsystemVersion != 0) 903 return false; 904 /* Image OS version and windows version value are all zero: */ 905 if ( pHdrs->OptionalHeader.MajorOperatingSystemVersion != 0 906 || pHdrs->OptionalHeader.MinorOperatingSystemVersion != 0 907 || pHdrs->OptionalHeader.Win32VersionValue != 0) 908 return false; 909 /* DLL image with 32-bit machine code: */ 910 if ( (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL | IMAGE_FILE_32BIT_MACHINE)) 911 != (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL | IMAGE_FILE_32BIT_MACHINE)) 912 return false; 913 /* No imports: */ 914 if ( pHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size != 0 915 || pHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size != 0) 916 return false; 917 /* Has a bunch of exports ('BootLib.dll'), for win11/amd64 it's 2630 bytes: */ 918 IMAGE_DATA_DIRECTORY const ExpRvaSize = pHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; /* cache for later */ 919 if (ExpRvaSize.Size < 1024) 920 return false; 921 if ((uint64_t)ExpRvaSize.VirtualAddress + ExpRvaSize.Size > pHdrs->OptionalHeader.SizeOfImage) 922 return false; 923 /* Check the image size is reasonable (win11/amd64 is 872448): */ 924 /** @todo adjust for older windows versions... */ 925 if ( pHdrs->OptionalHeader.SizeOfImage < _64K 926 || pHdrs->OptionalHeader.SizeOfImage > _4M) 927 return false; 928 /* The image base is 0x00400000 (relocations typically stripped): */ 929 if (pHdrs->OptionalHeader.ImageBase != UINT32_C(0x00400000)) 930 return false; 931 932 /* 933 * Final check is that export directory name is 'BootLib.dll'. 934 */ 935 static char const s_szBootLibDll[] = "BootLib.dll"; 936 DBGFADDRESS Addr2; 937 IMAGE_EXPORT_DIRECTORY ExpDir; 938 int rc = pVMM->pfnDBGFR3MemRead(pUVM, 0, 939 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr2, pAddr->FlatPtr + ExpRvaSize.VirtualAddress), 940 &ExpDir, sizeof(ExpDir)); 941 if (RT_FAILURE(rc)) 942 return false; 943 /* There ought to be a few named exports here (win11 has 94): */ 944 if (ExpDir.NumberOfNames < 48 || ExpDir.NumberOfNames > _4K) 945 return false; 946 947 if ( ExpDir.Name < pMzHdr->e_lfanew + pHdrs->OptionalHeader.SizeOfHeaders 948 || (uint64_t)ExpDir.Name + sizeof(s_szBootLibDll) > pHdrs->OptionalHeader.SizeOfImage) 949 return false; 950 951 char szActualName[sizeof(s_szBootLibDll)]; 952 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0, pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr2, pAddr->FlatPtr + ExpDir.Name), 953 &szActualName, sizeof(szActualName)); 954 if (RT_FAILURE(rc)) 955 return false; 956 if (szActualName[sizeof(s_szBootLibDll) - 1] != '\0') 957 return false; 958 if (RTStrICmpAscii(szActualName, s_szBootLibDll) != 0) 959 return false; 960 961 if (pcbImage) 962 *pcbImage = pHdrs->OptionalHeader.SizeOfImage; 963 return true; 964 } 965 966 967 /** 968 * Checks if the given headers are for the WinLoad.exe/efi image loaded very 969 * early during the BIOS or EFI boot process. 970 */ 971 static bool dbgDiggerWinNtIsWinLoad(PUVM pUVM, PCVMMR3VTABLE pVMM, PCDBGFADDRESS pAddr, uint8_t const *pbHdrs, size_t cbHdrs, 972 bool *pf32Bit, uint32_t *pcbImage, uint32_t *puNtMajorVersion, uint32_t *puNtMinorVersion) 973 { 974 if (pf32Bit) 975 *pf32Bit = false; 976 if (pcbImage) 977 *pcbImage = 0; 978 if (puNtMajorVersion) 979 *puNtMajorVersion = 0; 980 if (puNtMinorVersion) 981 *puNtMinorVersion = 0; 982 983 /* 984 * Check and skip the DOS header. 985 */ 986 AssertReturn(sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS64) < cbHdrs, false); 987 IMAGE_DOS_HEADER const * const pMzHdr = (IMAGE_DOS_HEADER const *)pbHdrs; 988 if ( pMzHdr->e_magic != IMAGE_DOS_SIGNATURE 989 || pMzHdr->e_lfanew < 0x40 990 || pMzHdr->e_lfanew > 0x400) 991 return false; 992 993 /* 994 * Check the NT headers. 995 * 996 * ASSUMES that the 64-bit and 32-bit optional headers match up to 997 * SizeOfStackReserve, if you exclude ImageBase and BaseOfData. 998 */ 999 AssertReturn(pMzHdr->e_lfanew + sizeof(IMAGE_NT_HEADERS64) <= cbHdrs, false); 1000 IMAGE_NT_HEADERS32 const * const pHdrs32 = (PCIMAGE_NT_HEADERS32)&pbHdrs[pMzHdr->e_lfanew]; 1001 IMAGE_NT_HEADERS64 const * const pHdrs64 = (PCIMAGE_NT_HEADERS64)&pbHdrs[pMzHdr->e_lfanew]; 1002 if (pHdrs32->Signature != IMAGE_NT_SIGNATURE) 1003 return false; 1004 /* There are a few extra sections here, but not too many: */ 1005 if ( pHdrs32->FileHeader.NumberOfSections <= 4 1006 || pHdrs32->FileHeader.NumberOfSections >= 15) 1007 return false; 1008 bool f32Bit; 1009 if (pHdrs32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) 1010 f32Bit = true; 1011 else if (pHdrs32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) 1012 f32Bit = false; 1013 else 1014 return false; 1015 if (pHdrs32->FileHeader.SizeOfOptionalHeader != (f32Bit ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64))) 1016 return false; 1017 if (pHdrs32->OptionalHeader.Magic != (f32Bit ? IMAGE_NT_OPTIONAL_HDR32_MAGIC : IMAGE_NT_OPTIONAL_HDR64_MAGIC)) 1018 return false; 1019 /* Special subsystem with version 6.0 or later: */ 1020 /** @todo which subsystem type does pre win11 use? (this is win11/amd64) */ 1021 if (pHdrs32->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) 1022 return false; 1023 if (pHdrs32->OptionalHeader.MajorSubsystemVersion < 6) 1024 return false; 1025 /* Image OS version and windows version value are all zero: */ 1026 if ( pHdrs32->OptionalHeader.MajorOperatingSystemVersion != 0 1027 || pHdrs32->OptionalHeader.MinorOperatingSystemVersion != 0 1028 || pHdrs32->OptionalHeader.Win32VersionValue != 0) 1029 return false; 1030 /* DLL image: */ 1031 if ( (pHdrs32->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) 1032 != (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) 1033 return false; 1034 /* Check the image size is reasonable (win11/amd64 is 1769472 for BIOS and ~2MB for EFI): */ 1035 /** @todo adjust for older windows versions... */ 1036 if ( pHdrs32->OptionalHeader.SizeOfImage < _1M 1037 || pHdrs32->OptionalHeader.SizeOfImage > _8M) 1038 return false; 1039 1040 /* The rest of the fields differs in placement between 32-bit and 64-bit. */ 1041 1042 if ( (f32Bit ? pHdrs32->OptionalHeader.NumberOfRvaAndSizes : pHdrs64->OptionalHeader.NumberOfRvaAndSizes) 1043 != IMAGE_NUMBEROF_DIRECTORY_ENTRIES) 1044 return false; 1045 1046 /* No imports: */ 1047 IMAGE_DATA_DIRECTORY const * const paDataDirs = f32Bit 1048 ? pHdrs32->OptionalHeader.DataDirectory : pHdrs64->OptionalHeader.DataDirectory; 1049 if ( paDataDirs[IMAGE_DIRECTORY_ENTRY_IMPORT].Size != 0 1050 || paDataDirs[IMAGE_DIRECTORY_ENTRY_IAT].Size != 0) 1051 return false; 1052 /* Has a bunch of exports ('winload.sys'), for win11/amd64 it's 11734 bytes: */ 1053 IMAGE_DATA_DIRECTORY const ExpRvaSize = paDataDirs[IMAGE_DIRECTORY_ENTRY_EXPORT]; /* cache for later */ 1054 if (ExpRvaSize.Size < 1024) 1055 return false; 1056 if ((uint64_t)ExpRvaSize.VirtualAddress + ExpRvaSize.Size > pHdrs32->OptionalHeader.SizeOfImage) 1057 return false; 1058 1059 /* 1060 * Final check is that export directory name is 'winload.sys'. 1061 */ 1062 static char const s_szWinLoadSys[] = "winload.sys"; 1063 DBGFADDRESS Addr2; 1064 IMAGE_EXPORT_DIRECTORY ExpDir; 1065 int rc = pVMM->pfnDBGFR3MemRead(pUVM, 0, 1066 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr2, pAddr->FlatPtr + ExpRvaSize.VirtualAddress), 1067 &ExpDir, sizeof(ExpDir)); 1068 if (RT_FAILURE(rc)) 1069 return false; 1070 /* There ought to be a few named exports here (win11 has 373): */ 1071 if (ExpDir.NumberOfNames < 128 || ExpDir.NumberOfNames > _4K) 1072 return false; 1073 1074 if ( ExpDir.Name < pMzHdr->e_lfanew + pHdrs32->OptionalHeader.SizeOfHeaders 1075 || (uint64_t)ExpDir.Name + sizeof(s_szWinLoadSys) > pHdrs32->OptionalHeader.SizeOfImage) 1076 return false; 1077 1078 char szActualName[sizeof(s_szWinLoadSys)]; 1079 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0, pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr2, pAddr->FlatPtr + ExpDir.Name), 1080 &szActualName, sizeof(szActualName)); 1081 if (RT_FAILURE(rc)) 1082 return false; 1083 if (szActualName[sizeof(s_szWinLoadSys) - 1] != '\0') 1084 return false; 1085 if (RTStrICmpAscii(szActualName, s_szWinLoadSys) != 0) 1086 return false; 1087 1088 if (pf32Bit) 1089 *pf32Bit = f32Bit; 1090 if (pcbImage) 1091 *pcbImage = pHdrs32->OptionalHeader.SizeOfImage; 1092 /* Note! We could get more accurate version info from the resource section if we wanted to... */ 1093 if (puNtMajorVersion) 1094 *puNtMajorVersion = pHdrs32->OptionalHeader.MajorSubsystemVersion; 1095 if (puNtMinorVersion) 1096 *puNtMinorVersion = pHdrs32->OptionalHeader.MinorSubsystemVersion; 1097 1098 return true; 1099 } 1100 1101 1102 /** 852 1103 * Process a PE image found in guest memory. 853 1104 * … … 859 1110 * @param pImageAddr The image address. 860 1111 * @param cbImage The size of the image. 1112 * @param enmArch Module architecture override. Default is determined 1113 * by DBGDIGGERWINNT::f32Bit. 861 1114 */ 862 1115 static void dbgDiggerWinNtProcessImage(PDBGDIGGERWINNT pThis, PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszName, 863 const char *pszFilename, PCDBGFADDRESS pImageAddr, uint32_t cbImage) 1116 const char *pszFilename, PCDBGFADDRESS pImageAddr, uint32_t cbImage, 1117 RTLDRARCH enmArch = RTLDRARCH_WHATEVER) 864 1118 { 865 1119 LogFlow(("DigWinNt: %RGp %#x %s\n", pImageAddr->FlatPtr, cbImage, pszName)); … … 878 1132 * Use the common in-memory module reader to create a debug module. 879 1133 */ 1134 if (enmArch == RTLDRARCH_WHATEVER) 1135 enmArch = pThis->f32Bit ? RTLDRARCH_X86_32 : RTLDRARCH_AMD64; 880 1136 RTERRINFOSTATIC ErrInfo; 881 1137 RTDBGMOD hDbgMod = NIL_RTDBGMOD; 882 1138 int rc = pVMM->pfnDBGFR3ModInMem(pUVM, pImageAddr, pThis->fNt31 ? DBGFMODINMEM_F_PE_NT31 : 0, pszName, pszFilename, 883 pThis->f32Bit ? RTLDRARCH_X86_32 : RTLDRARCH_AMD64, cbImage, 884 &hDbgMod, RTErrInfoInitStatic(&ErrInfo)); 1139 enmArch, cbImage, &hDbgMod, RTErrInfoInitStatic(&ErrInfo)); 885 1140 if (RT_SUCCESS(rc)) 886 1141 { … … 1311 1566 1312 1567 /* 1313 * Figure the NT version. 1568 * Load the bootmgr module if it was detected and is still present. 1569 * The boot manager is always 32-bit on x86. 1570 */ 1571 if (DBGFADDRESS_IS_VALID(&pThis->BootMgrAddr)) 1572 { 1573 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, &pThis->BootMgrAddr, &u, sizeof(u)); 1574 if (RT_SUCCESS(rc)) 1575 { 1576 uint32_t cbImage = 0; 1577 if (dbgDiggerWinNtIsBootMgr(pUVM, pVMM, &pThis->BootMgrAddr, &u.au8[0], sizeof(u), &cbImage)) 1578 dbgDiggerWinNtProcessImage(pThis, pUVM, pVMM, "BootMgr", "BootMgr.exe", 1579 &pThis->BootMgrAddr, cbImage, RTLDRARCH_X86_32); 1580 } 1581 } 1582 1583 /* 1584 * Load the winload module if it was detected and still present. 1585 */ 1586 if (DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr)) 1587 { 1588 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, &pThis->WinLoadAddr, &u, sizeof(u)); 1589 if (RT_SUCCESS(rc)) 1590 { 1591 uint32_t cbImage = 0; 1592 uint32_t uNtMajorVersion = 0; 1593 uint32_t uNtMinorVersion = 0; 1594 if (dbgDiggerWinNtIsWinLoad(pUVM, pVMM, &pThis->WinLoadAddr, &u.au8[0], sizeof(u), 1595 NULL /*pf32Bit*/, &cbImage, &uNtMajorVersion, &uNtMinorVersion)) 1596 { 1597 dbgDiggerWinNtProcessImage(pThis, pUVM, pVMM, "WinLoad", "WinLoad.exe", &pThis->WinLoadAddr, cbImage); 1598 pThis->NtMajorVersion = uNtMajorVersion; 1599 pThis->NtMinorVersion = uNtMinorVersion; 1600 } 1601 } 1602 } 1603 1604 /* 1605 * Try figure the NT version. 1314 1606 */ 1315 1607 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, pThis->f32Bit ? NTKUSERSHAREDDATA_WINNT32 : NTKUSERSHAREDDATA_WINNT64); … … 1334 1626 { 1335 1627 Log(("DigWinNt: Error reading KUSER_SHARED_DATA: %Rrc\n", rc)); 1336 return rc; 1628 if ( !DBGFADDRESS_IS_VALID(&pThis->KernelAddr) 1629 || !DBGFADDRESS_IS_VALID(&pThis->KernelMteAddr) 1630 || !DBGFADDRESS_IS_VALID(&pThis->PsLoadedModuleListAddr)) 1631 return DBGFADDRESS_IS_VALID(&pThis->BootMgrAddr) || DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr) ? VINF_SUCCESS : rc; 1337 1632 } 1338 1633 … … 1446 1741 { 1447 1742 PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData; 1743 bool fRet = false; 1448 1744 DBGFADDRESS Addr; 1449 1745 union … … 1465 1761 1466 1762 /* 1763 * Reset the state (paranoia) 1764 */ 1765 RT_ZERO(pThis->BootMgrAddr); 1766 RT_ZERO(pThis->WinLoadAddr); 1767 RT_ZERO(pThis->KernelAddr); 1768 RT_ZERO(pThis->KernelMteAddr); 1769 RT_ZERO(pThis->PsLoadedModuleListAddr); 1770 pThis->f32Bit = false; 1771 pThis->fNt31 = false; 1772 1773 /* 1774 * Look for the BootMgr/BootLib.dll module at 0x400000. 1775 * This is only relevant when booting via BIOS. 1776 */ 1777 if (1/** @todo BIOS + x86/amd64 only */) 1778 { 1779 int rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, 1780 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, UINT32_C(0x400000)), 1781 &u.au8[0], sizeof(u)); 1782 if (RT_SUCCESS(rc) && dbgDiggerWinNtIsBootMgr(pUVM, pVMM, &Addr, &u.au8[0], sizeof(u), NULL)) 1783 { 1784 pThis->BootMgrAddr = Addr; 1785 fRet = true; 1786 } 1787 } 1788 1789 /* 1790 * Look for the winload.exe/winload.sys module that's, from the looks of it, 1791 * responsible for loading the kernel and boot drivers. 1792 */ 1793 if (DBGFADDRESS_IS_VALID(&pThis->BootMgrAddr)) 1794 { 1795 static const char s_szNeedle[] = "PAGER32C"; /* Section name. No terminator. */ 1796 uint32_t const uEndAddr = _16M + _1M; 1797 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, pThis->BootMgrAddr.FlatPtr + _64K); 1798 do 1799 { 1800 int rc = pVMM->pfnDBGFR3MemScan(pUVM, 0 /*idCpu*/, &Addr, uEndAddr - Addr.FlatPtr, 1801 8 /*uAlign*/, s_szNeedle, sizeof(s_szNeedle) - 1, &Addr); 1802 if (RT_FAILURE(rc)) 1803 break; 1804 1805 DBGFADDRESS AddrMz; 1806 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, 1807 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &AddrMz, 1808 Addr.FlatPtr & ~(RTGCUINTPTR)GUEST_PAGE_OFFSET_MASK), 1809 &u.au8[0], sizeof(u)); 1810 bool f32Bit = false; 1811 if (RT_SUCCESS(rc) && dbgDiggerWinNtIsWinLoad(pUVM, pVMM, &AddrMz, &u.au8[0], sizeof(u), &f32Bit, NULL, NULL, NULL)) 1812 { 1813 pThis->WinLoadAddr = AddrMz; 1814 pThis->f32Bit = f32Bit; 1815 fRet = true; 1816 break; 1817 } 1818 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, AddrMz.FlatPtr + GUEST_PAGE_SIZE); 1819 } while (Addr.FlatPtr + _64K < uEndAddr); 1820 } 1821 1822 /* 1467 1823 * NT only runs in protected or long mode. 1468 1824 */ 1469 1825 CPUMMODE const enmMode = pVMM->pfnDBGFR3CpuGetMode(pUVM, 0 /*idCpu*/); 1470 1826 if (enmMode != CPUMMODE_PROTECTED && enmMode != CPUMMODE_LONG) 1471 return false; 1472 bool const f64Bit = enmMode == CPUMMODE_LONG; 1473 uint64_t const uStart = f64Bit ? UINT64_C(0xffff080000000000) : UINT32_C(0x80001000); 1827 return fRet; 1828 bool const f64Bit = enmMode == CPUMMODE_LONG 1829 || (DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr) && !pThis->f32Bit); 1830 uint64_t const uStart = f64Bit ? UINT64_C(0xffff800000000000) : UINT32_C(0x80001000); 1474 1831 uint64_t const uEnd = f64Bit ? UINT64_C(0xffffffffffff0000) : UINT32_C(0xffff0000); 1475 1832 … … 1483 1840 uint16_t uIdtrLimit = 0; 1484 1841 int rc = pVMM->pfnDBGFR3RegCpuQueryXdtr(pUVM, 0, DBGFREG_IDTR, &uIdtrBase, &uIdtrLimit); 1485 AssertRCReturn(rc, f alse);1842 AssertRCReturn(rc, fRet); 1486 1843 1487 1844 const uint16_t cbMinIdtr = (X86_XCPT_PF + 1) * (f64Bit ? sizeof(X86DESC64GATE) : sizeof(X86DESCGATE)); 1488 1845 if (uIdtrLimit < cbMinIdtr) 1489 return f alse;1846 return fRet; 1490 1847 1491 1848 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, uIdtrBase), &u, cbMinIdtr); 1492 1849 if (RT_FAILURE(rc)) 1493 return f alse;1494 1495 uint64_t uKrnlStart ;1496 uint64_t uKrnlEnd ;1850 return fRet; 1851 1852 uint64_t uKrnlStart = uStart; 1853 uint64_t uKrnlEnd = uEnd; 1497 1854 if (f64Bit) 1498 1855 { … … 1500 1857 | ((uint32_t)u.a64Gates[X86_XCPT_PF].u16OffsetHigh << 16) 1501 1858 | ((uint64_t)u.a64Gates[X86_XCPT_PF].u32OffsetTop << 32); 1502 if (uHandler < uStart || uHandler > uEnd) 1503 return false; 1504 uKrnlStart = (uHandler & ~(uint64_t)_4M) - _512M; 1505 uKrnlEnd = (uHandler + (uint64_t)_4M) & ~(uint64_t)_4M; 1859 if (uHandler >= uStart && uHandler <= uEnd) 1860 { 1861 uKrnlStart = (uHandler & ~(uint64_t)_4M) - _512M; 1862 uKrnlEnd = (uHandler + (uint64_t)_4M) & ~(uint64_t)_4M; 1863 } 1864 else if (!DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr)) 1865 return fRet; 1506 1866 } 1507 1867 else 1508 1868 { 1509 1869 uint32_t uHandler = RT_MAKE_U32(u.a32Gates[X86_XCPT_PF].u16OffsetLow, u.a32Gates[X86_XCPT_PF].u16OffsetHigh); 1510 if (uHandler < uStart || uHandler > uEnd) 1511 return false; 1512 uKrnlStart = (uHandler & ~(uint64_t)_4M) - _64M; 1513 uKrnlEnd = (uHandler + (uint64_t)_4M) & ~(uint64_t)_4M; 1870 if (uHandler >= uStart && uHandler <= uEnd) 1871 { 1872 uKrnlStart = (uHandler & ~(uint64_t)_4M) - _64M; 1873 uKrnlEnd = (uHandler + (uint64_t)_4M) & ~(uint64_t)_4M; 1874 } 1875 else if (!DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr)) 1876 return fRet; 1514 1877 } 1515 1878 … … 1532 1895 8, "PAGELK\0", sizeof("PAGELK\0"), &KernelAddr); 1533 1896 if ( rc == VERR_DBGF_MEM_NOT_FOUND 1534 && enmMode != CPUMMODE_LONG)1897 && !f64Bit) 1535 1898 { 1536 1899 /* NT3.1 didn't have a PAGELK section, so look for _TEXT instead. The … … 1552 1915 && u.MzHdr.e_lfanew <= 0x400) /* W8 is at 0x288*/ 1553 1916 { 1554 if ( enmMode != CPUMMODE_LONG)1917 if (!f64Bit) 1555 1918 { 1556 1919 IMAGE_NT_HEADERS32 const *pHdrs = (IMAGE_NT_HEADERS32 const *)&u.au8[u.MzHdr.e_lfanew]; … … 1727 2090 } 1728 2091 } 1729 return false; 2092 2093 return fRet; 1730 2094 } 1731 2095
Note:
See TracChangeset
for help on using the changeset viewer.