DBGPlugInWinNt.cpp revision b529ce62f7f41042866f179ea4c103e913f499e0
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * DBGPlugInWindows - Debugger and Guest OS Digger Plugin For Windows NT.
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * Copyright (C) 2009-2010 Oracle Corporation
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * available from http://www.virtualbox.org. This file is free software;
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * you can redistribute it and/or modify it under the terms of the GNU
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * General Public License (GPL) as published by the Free Software
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync/*******************************************************************************
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync* Header Files *
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync*******************************************************************************/
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync#define LOG_GROUP LOG_GROUP_DBGF ///@todo add new log group.
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync#include "../Runtime/include/internal/ldrMZ.h" /* ugly */
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync#include "../Runtime/include/internal/ldrPE.h" /* ugly */
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync/*******************************************************************************
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync* Structures and Typedefs *
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync*******************************************************************************/
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync/** @name Internal WinNT structures
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * PsLoadedModuleList entry for 32-bit NT aka LDR_DATA_TABLE_ENTRY.
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsync * Tested with XP.
03532efdc331b598d3dedc8cc7477641c3b0dd12vboxsynctypedef struct NTMTE32
} FullDllName,
} NTMTE32;
typedef struct NTMTE64
} FullDllName,
} NTMTE64;
typedef union NTMTE
} NTMTE;
typedef struct NTKUSERSHAREDDATA
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, WINNT_UNION(pThis, pHdrs, OptionalHeader.SizeOfImage), cbImage));
if (WINNT_UNION(pThis, pHdrs, OptionalHeader.NumberOfRvaAndSizes) != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
Log(("DigWinNt: %s: Invalid OH.SizeOfImage: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, OptionalHeader.NumberOfRvaAndSizes)));
IMAGE_DATA_DIRECTORY const *pDir = &WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]);
if (uRvaDebugDir != 0)
for (uint32_t i = 0; i < c; i++)
static DECLCALLBACK(void *) dbgDiggerWinNtQueryInterface(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf)
return NULL;
static DECLCALLBACK(int) dbgDiggerWinNtQueryVersion(PVM pVM, 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(pVM, &Addr, pThis->f32Bit ? NTKUSERSHAREDDATA_WINNT32 : NTKUSERSHAREDDATA_WINNT64);
return rc;
pThis->NtProductType = u.UserSharedData.ProductTypeIsValid && u.UserSharedData.NtProductType <= kNtProductType_Server
rc = DBGFR3MemRead(pVM, 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;
pVM,
&u.au8[0],
return VINF_SUCCESS;
&& (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) == IMAGE_FILE_EXECUTABLE_IMAGE
return VINF_SUCCESS;