DBGPlugInWinNt.cpp revision daa94352f51be2329ac8660f70396e03a7cb983b
15617cf4cb5fa181f4d6f55f987a883cf298cce6vboxsync * DBGPlugInWindows - Debugger and Guest OS Digger Plugin For Windows NT.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Copyright (C) 2009-2013 Oracle Corporation
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b4915d0cee39500bb2f42e15c25e176619929150vboxsync/*******************************************************************************
b4915d0cee39500bb2f42e15c25e176619929150vboxsync* Header Files *
b4915d0cee39500bb2f42e15c25e176619929150vboxsync*******************************************************************************/
b4915d0cee39500bb2f42e15c25e176619929150vboxsync#define LOG_GROUP LOG_GROUP_DBGF ///@todo add new log group.
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync#include "../Runtime/include/internal/ldrMZ.h" /* ugly */
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync#include "../Runtime/include/internal/ldrPE.h" /* ugly */
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync/*******************************************************************************
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync* Structures and Typedefs *
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync*******************************************************************************/
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync/** @name Internal WinNT structures
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync * PsLoadedModuleList entry for 32-bit NT aka LDR_DATA_TABLE_ENTRY.
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync * Tested with XP.
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsynctypedef struct NTMTE32
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync /* ... there is more ... */
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync * PsLoadedModuleList entry for 32-bit NT aka LDR_DATA_TABLE_ENTRY.
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync * Tested with XP.
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsync * @todo This is incomplete and just to get rid of warnings.
c3cd0366348bcd10e42bd7be9ea05d194394f389vboxsynctypedef struct NTMTE64
a664fa5a4c93cf89efebe6c071cc89e9d3d3cd61vboxsync /* ... there is more ... */
15617cf4cb5fa181f4d6f55f987a883cf298cce6vboxsync/** MTE union. */
15617cf4cb5fa181f4d6f55f987a883cf298cce6vboxsynctypedef union NTMTE
15617cf4cb5fa181f4d6f55f987a883cf298cce6vboxsync * The essential bits of the KUSER_SHARED_DATA structure.
typedef enum NTPRODUCTTYPE
typedef struct CV_INFO_PDB20
typedef struct CV_INFO_PDB70
#pragma pack()
typedef enum DBGDIGGERWINNTVER
typedef struct DBGDIGGERWINNT
bool fValid;
bool f32Bit;
#define WINNT32_VALID_ADDRESS(Addr) ((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000))
#define WINNT64_VALID_ADDRESS(Addr) ((Addr) > UINT64_C(0xffffffff80000000) && (Addr) < UINT64_C(0xfffffffffffff000))
#define WINNT_VALID_ADDRESS(pThis, Addr) ((pThis)->f32Bit ? WINNT32_VALID_ADDRESS(Addr) : WINNT64_VALID_ADDRESS(Addr))
#define WINNT_UNION(pThis, pUnion, Member) ((pThis)->f32Bit ? (pUnion)->vX_32. Member : (pUnion)->vX_64. Member )
typedef union NTHDRSU
} NTHDRS;
offHdrs = 0;
if (pHdrs->vX_32.FileHeader.Machine != (pThis->f32Bit ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_AMD64))
if (pHdrs->vX_32.FileHeader.SizeOfOptionalHeader != (pThis->f32Bit ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64)))
Log(("DigWinNt: %s: Invalid FH.SizeOfOptionalHeader: %#x\n", pszName, pHdrs->vX_32.FileHeader.SizeOfOptionalHeader));
if (WINNT_UNION(pThis, pHdrs, OptionalHeader.Magic) != (pThis->f32Bit ? IMAGE_NT_OPTIONAL_HDR32_MAGIC : IMAGE_NT_OPTIONAL_HDR64_MAGIC))
Log(("DigWinNt: %s: Invalid OH.Magic: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, OptionalHeader.Magic)));
Log(("DigWinNt: %s: Invalid OH.SizeOfImage: %#x, expected %#x\n", pszName, cbImageFromHdr, cbImage));
if (WINNT_UNION(pThis, pHdrs, OptionalHeader.NumberOfRvaAndSizes) != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
Log(("DigWinNt: %s: Invalid OH.NumberOfRvaAndSizes: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, OptionalHeader.NumberOfRvaAndSizes)));
IMAGE_DATA_DIRECTORY const *pDir = &WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]);
bool fPeImageMod = true;
int rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM));
fPeImageMod = false;
if (fPeImageMod)
if (uRvaDebugDir != 0)
for (uint32_t i = 0; i < c; i++)
static DECLCALLBACK(void *) dbgDiggerWinNtQueryInterface(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf)
return NULL;
static DECLCALLBACK(int) dbgDiggerWinNtQueryVersion(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion)
const char *pszNtProductType;
RTStrPrintf(pszVersion, cchVersion, "%u.%u%s", pThis->NtMajorVersion, pThis->NtMinorVersion, pszNtProductType);
return VINF_SUCCESS;
while (iMod-- > 0)
int rc;
DBGFR3AddrFromFlat(pUVM, &Addr, pThis->f32Bit ? NTKUSERSHAREDDATA_WINNT32 : NTKUSERSHAREDDATA_WINNT64);
return rc;
pThis->NtProductType = u.UserSharedData.ProductTypeIsValid && u.UserSharedData.NtProductType <= kNtProductType_Server
rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, &Mte, pThis->f32Bit ? sizeof(Mte.vX_32) : sizeof(Mte.vX_64));
Log(("DigWinNt: Bad Mte at %RGv - BaseDllName=%llx\n", Addr.FlatPtr, WINNT_UNION(pThis, &Mte, BaseDllName.Buffer)));
Log(("DigWinNt: Bad Mte at %RGv - FullDllName=%llx\n", Addr.FlatPtr, WINNT_UNION(pThis, &Mte, FullDllName.Buffer)));
|| WINNT_UNION(pThis, &Mte, EntryPoint) - WINNT_UNION(pThis, &Mte, DllBase) > WINNT_UNION(pThis, &Mte, SizeOfImage) )
Addr.FlatPtr, WINNT_UNION(pThis, &Mte, EntryPoint), WINNT_UNION(pThis, &Mte, SizeOfImage), WINNT_UNION(pThis, &Mte, DllBase)));
if (cbName < sizeof(u))
if (cbName < sizeof(u))
char *pszName;
pUVM,
&u.au8[0],
return VINF_SUCCESS;
&& (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) == IMAGE_FILE_EXECUTABLE_IMAGE
return VINF_SUCCESS;