Changeset 106379 in vbox for trunk/src/VBox/Debugger
- Timestamp:
- Oct 16, 2024 1:45:18 PM (4 months ago)
- svn:sync-xref-src-repo-rev:
- 165192
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp
r106061 r106379 251 251 * (For fending off illegal interface method calls.) */ 252 252 bool fValid; 253 /** 32-bit (true) or 64-bit (false) */254 bool f32Bit;255 253 /** Set if NT 3.1 was detected. 256 254 * This implies both Misc.VirtualSize and NTMTE32::SizeOfImage are zero. */ 257 255 bool fNt31; 256 /** Detected architecture. */ 257 RTLDRARCH enmArch; 258 258 259 259 /** The NT version. */ … … 271 271 DBGFADDRESS BootMgrAddr; 272 272 /** The address of the winload.exe image if early during boot. 273 * When this is set, f32Bithas also been determined. */273 * When this is set, enmArch has also been determined. */ 274 274 DBGFADDRESS WinLoadAddr; 275 275 … … 342 342 /** Validates a 64-bit Windows NT kernel address */ 343 343 #define WINNT64_VALID_ADDRESS(Addr) ((Addr) > UINT64_C(0xffff800000000000) && (Addr) < UINT64_C(0xfffffffffffff000)) 344 /** Returns whether this is a 32-bit Windows NT kernel. */ 345 #define WINNT_IS_32BIT(a_pThis) ((a_pThis)->enmArch == RTLDRARCH_X86_32) 344 346 /** Validates a kernel address. */ 345 #define WINNT_VALID_ADDRESS(pThis, Addr) ( (pThis)->f32Bit? WINNT32_VALID_ADDRESS(Addr) : WINNT64_VALID_ADDRESS(Addr))347 #define WINNT_VALID_ADDRESS(pThis, Addr) (WINNT_IS_32BIT(pThis) ? WINNT32_VALID_ADDRESS(Addr) : WINNT64_VALID_ADDRESS(Addr)) 346 348 /** Versioned and bitness wrapper. */ 347 #define WINNT_UNION(pThis, pUnion, Member) ( (pThis)->f32Bit? (pUnion)->vX_32. Member : (pUnion)->vX_64. Member )349 #define WINNT_UNION(pThis, pUnion, Member) (WINNT_IS_32BIT(pThis) ? (pUnion)->vX_32. Member : (pUnion)->vX_64. Member ) 348 350 349 351 /** The length (in chars) of the kernel file name (no path). */ … … 443 445 char aszFmtStr[_1K]; /* Restricted size. */ 444 446 DBGFADDRESS AddrVaList; 445 if ( !pThis->f32Bit)447 if (pThis->enmArch != RTLDRARCH_X86_32) 446 448 { 447 449 /* … … 520 522 { 521 523 uint32_t cbInsn = 0; 522 rc = DISInstr(&abInstr[0], pThis-> f32Bit? DISCPUMODE_32BIT : DISCPUMODE_64BIT, &DisState, &cbInsn);524 rc = DISInstr(&abInstr[0], pThis->enmArch == RTLDRARCH_X86_32 ? DISCPUMODE_32BIT : DISCPUMODE_64BIT, &DisState, &cbInsn); 523 525 if ( RT_SUCCESS(rc) 524 526 && DisState.pCurInstr->uOpcode == OP_CALL … … 702 704 PDBGFADDRESS pKpcrbAddr = &pThis->paKpcrbAddr[idCpu]; 703 705 704 if (pThis-> f32Bit)706 if (pThis->enmArch == RTLDRARCH_X86_32) 705 707 { 706 708 /* Read FS base */ … … 970 972 */ 971 973 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 (p f32Bit)975 *p f32Bit = false;974 RTLDRARCH *penmArch, uint32_t *pcbImage, uint32_t *puNtMajorVersion, uint32_t *puNtMinorVersion) 975 { 976 if (penmArch) 977 *penmArch = RTLDRARCH_X86_32; 976 978 if (pcbImage) 977 979 *pcbImage = 0; … … 1007 1009 return false; 1008 1010 bool f32Bit; 1011 RTLDRARCH enmArch; 1009 1012 if (pHdrs32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) 1013 { 1010 1014 f32Bit = true; 1015 enmArch = RTLDRARCH_X86_32; 1016 } 1011 1017 else if (pHdrs32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) 1018 { 1012 1019 f32Bit = false; 1020 enmArch = RTLDRARCH_AMD64; 1021 } 1022 else if (pHdrs32->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64) 1023 { 1024 f32Bit = false; 1025 enmArch = RTLDRARCH_ARM64; 1026 } 1013 1027 else 1014 1028 return false; … … 1086 1100 return false; 1087 1101 1088 if (p f32Bit)1089 *p f32Bit = f32Bit;1102 if (penmArch) 1103 *penmArch = enmArch; 1090 1104 if (pcbImage) 1091 1105 *pcbImage = pHdrs32->OptionalHeader.SizeOfImage; … … 1133 1147 */ 1134 1148 if (enmArch == RTLDRARCH_WHATEVER) 1135 enmArch = pThis-> f32Bit ? RTLDRARCH_X86_32 : RTLDRARCH_AMD64;1149 enmArch = pThis->enmArch; 1136 1150 RTERRINFOSTATIC ErrInfo; 1137 1151 RTDBGMOD hDbgMod = NIL_RTDBGMOD; … … 1228 1242 *puBuildNumber = pData->NtBuildNumber; 1229 1243 if (pf32Bit) 1230 *pf32Bit = pData->f32Bit;1244 *pf32Bit = WINNT_IS_32BIT(pData); 1231 1245 return VINF_SUCCESS; 1232 1246 } … … 1464 1478 } 1465 1479 1480 const char *pszArch; 1481 switch (pThis->enmArch) 1482 { 1483 case RTLDRARCH_X86_32: pszArch = "x86"; break; 1484 case RTLDRARCH_AMD64: pszArch = "AMD64"; break; 1485 case RTLDRARCH_ARM64: pszArch = "ARM64"; break; 1486 default: pszArch = "<??>"; break; 1487 } 1466 1488 RTStrPrintf(pszVersion, cchVersion, "%u.%u-%s%s (BuildNumber %u)", pThis->NtMajorVersion, pThis->NtMinorVersion, 1467 p This->f32Bit ? "x86" : "AMD64", pszNtProductType, pThis->NtBuildNumber);1489 pszArch, pszNtProductType, pThis->NtBuildNumber); 1468 1490 return VINF_SUCCESS; 1469 1491 } … … 1605 1627 * Try figure the NT version. 1606 1628 */ 1607 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, pThis->f32Bit? NTKUSERSHAREDDATA_WINNT32 : NTKUSERSHAREDDATA_WINNT64);1629 pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, WINNT_IS_32BIT(pThis) ? NTKUSERSHAREDDATA_WINNT32 : NTKUSERSHAREDDATA_WINNT64); 1608 1630 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, &u, GUEST_PAGE_SIZE); 1609 1631 if (RT_SUCCESS(rc)) … … 1641 1663 /* Read the validate the MTE. */ 1642 1664 NTMTE Mte; 1643 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, &Mte, pThis->f32Bit? sizeof(Mte.vX_32) : sizeof(Mte.vX_64));1665 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, &Mte, WINNT_IS_32BIT(pThis) ? sizeof(Mte.vX_32) : sizeof(Mte.vX_64)); 1644 1666 if (RT_FAILURE(rc)) 1645 1667 break; … … 1768 1790 RT_ZERO(pThis->KernelMteAddr); 1769 1791 RT_ZERO(pThis->PsLoadedModuleListAddr); 1770 pThis-> f32Bit = false;1771 pThis->fNt31 = false;1792 pThis->enmArch = RTLDRARCH_WHATEVER; 1793 pThis->fNt31 = false; 1772 1794 1773 1795 /* … … 1808 1830 Addr.FlatPtr & ~(RTGCUINTPTR)GUEST_PAGE_OFFSET_MASK), 1809 1831 &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))1832 RTLDRARCH enmArch = RTLDRARCH_WHATEVER; 1833 if (RT_SUCCESS(rc) && dbgDiggerWinNtIsWinLoad(pUVM, pVMM, &AddrMz, &u.au8[0], sizeof(u), &enmArch, NULL, NULL, NULL)) 1812 1834 { 1813 1835 pThis->WinLoadAddr = AddrMz; 1814 pThis-> f32Bit = f32Bit;1836 pThis->enmArch = enmArch; 1815 1837 fRet = true; 1816 1838 break; … … 1824 1846 */ 1825 1847 CPUMMODE const enmMode = pVMM->pfnDBGFR3CpuGetMode(pUVM, 0 /*idCpu*/); 1826 if (enmMode != CPUMMODE_PROTECTED && enmMode != CPUMMODE_LONG )1848 if (enmMode != CPUMMODE_PROTECTED && enmMode != CPUMMODE_LONG && enmMode != CPUMMODE_ARMV8_AARCH64) 1827 1849 return fRet; 1828 1850 bool const f64Bit = enmMode == CPUMMODE_LONG 1829 || (DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr) && !pThis->f32Bit); 1851 || enmMode == CPUMMODE_ARMV8_AARCH64 1852 || (DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr) && !WINNT_IS_32BIT(pThis)); 1830 1853 uint64_t const uStart = f64Bit ? UINT64_C(0xffff800000000000) : UINT32_C(0x80001000); 1831 1854 uint64_t const uEnd = f64Bit ? UINT64_C(0xffffffffffff0000) : UINT32_C(0xffff0000); 1832 1855 1833 /*1834 * To approximately locate the kernel we examine the IDTR handlers.1835 *1836 * The exception/trap/fault handlers are all in NT kernel image, we pick1837 * KiPageFault here.1838 */1839 uint64_t uIdtrBase = 0;1840 uint16_t uIdtrLimit = 0;1841 int rc = pVMM->pfnDBGFR3RegCpuQueryXdtr(pUVM, 0, DBGFREG_IDTR, &uIdtrBase, &uIdtrLimit);1842 AssertRCReturn(rc, fRet);1843 1844 const uint16_t cbMinIdtr = (X86_XCPT_PF + 1) * (f64Bit ? sizeof(X86DESC64GATE) : sizeof(X86DESCGATE));1845 if (uIdtrLimit < cbMinIdtr)1846 return fRet;1847 1848 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, uIdtrBase), &u, cbMinIdtr);1849 if (RT_FAILURE(rc))1850 return fRet;1851 1852 1856 uint64_t uKrnlStart = uStart; 1853 1857 uint64_t uKrnlEnd = uEnd; 1854 if (f64Bit) 1855 { 1856 uint64_t uHandler = u.a64Gates[X86_XCPT_PF].u16OffsetLow 1857 | ((uint32_t)u.a64Gates[X86_XCPT_PF].u16OffsetHigh << 16) 1858 | ((uint64_t)u.a64Gates[X86_XCPT_PF].u32OffsetTop << 32); 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)) 1858 1859 int rc; 1860 if (enmMode == CPUMMODE_ARMV8_AARCH64) 1861 { 1862 /* 1863 * To approximately locate the kernel we use the exception table base address 1864 * which contains actual instructions so it is located in the NT kernel image. 1865 */ 1866 uint64_t uVBarBase = 0; 1867 rc = pVMM->pfnDBGFR3RegCpuQueryU64(pUVM, 0, DBGFREG_ARMV8_VBAR_EL1, &uVBarBase); 1868 AssertRCReturn(rc, fRet); 1869 1870 if (f64Bit) 1871 { 1872 if (uVBarBase >= uStart && uVBarBase <= uEnd) 1873 { 1874 uKrnlStart = (uVBarBase & ~(uint64_t)_4M) - _512M; 1875 uKrnlEnd = (uVBarBase + (uint64_t)_4M) & ~(uint64_t)_4M; 1876 } 1877 else if (!DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr)) 1878 return fRet; 1879 } 1880 else 1881 { 1882 AssertFailed(); 1865 1883 return fRet; 1884 } 1866 1885 } 1867 1886 else 1868 1887 { 1869 uint32_t uHandler = RT_MAKE_U32(u.a32Gates[X86_XCPT_PF].u16OffsetLow, u.a32Gates[X86_XCPT_PF].u16OffsetHigh); 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)) 1888 /* 1889 * To approximately locate the kernel we examine the IDTR handlers. 1890 * 1891 * The exception/trap/fault handlers are all in NT kernel image, we pick 1892 * KiPageFault here. 1893 */ 1894 uint64_t uIdtrBase = 0; 1895 uint16_t uIdtrLimit = 0; 1896 rc = pVMM->pfnDBGFR3RegCpuQueryXdtr(pUVM, 0, DBGFREG_IDTR, &uIdtrBase, &uIdtrLimit); 1897 AssertRCReturn(rc, fRet); 1898 1899 const uint16_t cbMinIdtr = (X86_XCPT_PF + 1) * (f64Bit ? sizeof(X86DESC64GATE) : sizeof(X86DESCGATE)); 1900 if (uIdtrLimit < cbMinIdtr) 1876 1901 return fRet; 1902 1903 rc = pVMM->pfnDBGFR3MemRead(pUVM, 0 /*idCpu*/, pVMM->pfnDBGFR3AddrFromFlat(pUVM, &Addr, uIdtrBase), &u, cbMinIdtr); 1904 if (RT_FAILURE(rc)) 1905 return fRet; 1906 1907 if (f64Bit) 1908 { 1909 uint64_t uHandler = u.a64Gates[X86_XCPT_PF].u16OffsetLow 1910 | ((uint32_t)u.a64Gates[X86_XCPT_PF].u16OffsetHigh << 16) 1911 | ((uint64_t)u.a64Gates[X86_XCPT_PF].u32OffsetTop << 32); 1912 if (uHandler >= uStart && uHandler <= uEnd) 1913 { 1914 uKrnlStart = (uHandler & ~(uint64_t)_4M) - _512M; 1915 uKrnlEnd = (uHandler + (uint64_t)_4M) & ~(uint64_t)_4M; 1916 } 1917 else if (!DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr)) 1918 return fRet; 1919 } 1920 else 1921 { 1922 uint32_t uHandler = RT_MAKE_U32(u.a32Gates[X86_XCPT_PF].u16OffsetLow, u.a32Gates[X86_XCPT_PF].u16OffsetHigh); 1923 if (uHandler >= uStart && uHandler <= uEnd) 1924 { 1925 uKrnlStart = (uHandler & ~(uint64_t)_4M) - _64M; 1926 uKrnlEnd = (uHandler + (uint64_t)_4M) & ~(uint64_t)_4M; 1927 } 1928 else if (!DBGFADDRESS_IS_VALID(&pThis->WinLoadAddr)) 1929 return fRet; 1930 } 1877 1931 } 1878 1932 … … 1976 2030 pThis->KernelMteAddr = MteAddr; 1977 2031 pThis->PsLoadedModuleListAddr = Addr; 1978 pThis-> f32Bit = true;2032 pThis->enmArch = RTLDRARCH_X86_32; 1979 2033 pThis->fNt31 = fNt31; 1980 2034 return true; … … 2003 2057 IMAGE_NT_HEADERS64 const *pHdrs = (IMAGE_NT_HEADERS64 const *)&u.au8[u.MzHdr.e_lfanew]; 2004 2058 if ( pHdrs->Signature == IMAGE_NT_SIGNATURE 2005 && pHdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 2006 && pHdrs->FileHeader.SizeOfOptionalHeader == sizeof(pHdrs->OptionalHeader) 2059 && ( pHdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 2060 || pHdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64) 2061 //&& pHdrs->FileHeader.SizeOfOptionalHeader == sizeof(pHdrs->OptionalHeader) 2007 2062 && pHdrs->FileHeader.NumberOfSections >= 10 /* the kernel has lots */ 2008 && (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL))2009 == IMAGE_FILE_EXECUTABLE_IMAGE2063 //&& (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) 2064 // == (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL) 2010 2065 && pHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC 2011 && pHdrs->OptionalHeader.NumberOfRvaAndSizes == IMAGE_NUMBEROF_DIRECTORY_ENTRIES2066 //&& pHdrs->OptionalHeader.NumberOfRvaAndSizes == IMAGE_NUMBEROF_DIRECTORY_ENTRIES 2012 2067 ) 2013 2068 { … … 2060 2115 && WINNT64_VALID_ADDRESS(uMte3.v64.InLoadOrderLinks.Blink) ) 2061 2116 { 2062 Log(("DigWinNt: MteAddr=%RGv KernelAddr=%RGv SizeOfImage=%x &PsLoadedModuleList=%RGv ( 32-bit)\n",2117 Log(("DigWinNt: MteAddr=%RGv KernelAddr=%RGv SizeOfImage=%x &PsLoadedModuleList=%RGv (64-bit)\n", 2063 2118 MteAddr.FlatPtr, KernelAddr.FlatPtr, uMte2.v64.SizeOfImage, Addr.FlatPtr)); 2064 2119 pThis->KernelAddr = KernelAddr; 2065 2120 pThis->KernelMteAddr = MteAddr; 2066 2121 pThis->PsLoadedModuleListAddr = Addr; 2067 pThis->f32Bit = false; 2122 pThis->enmArch = enmMode == CPUMMODE_LONG 2123 ? RTLDRARCH_AMD64 2124 : RTLDRARCH_ARM64; 2068 2125 pThis->fNt31 = false; 2069 2126 return true; … … 2112 2169 PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData; 2113 2170 pThis->fValid = false; 2114 pThis-> f32Bit = false;2171 pThis->enmArch = RTLDRARCH_WHATEVER; 2115 2172 pThis->enmVer = DBGDIGGERWINNTVER_UNKNOWN; 2116 2173
Note:
See TracChangeset
for help on using the changeset viewer.