a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/* $Id$ */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** @file
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * DBGPlugInWindows - Debugger and Guest OS Digger Plugin For Windows NT.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2009-2013 Oracle Corporation
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync *
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * available from http://www.virtualbox.org. This file is free software;
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * you can redistribute it and/or modify it under the terms of the GNU
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * General Public License (GPL) as published by the Free Software
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Header Files *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define LOG_GROUP LOG_GROUP_DBGF ///@todo add new log group.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include "DBGPlugIns.h"
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/dbgf.h>
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include <VBox/err.h>
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include <VBox/param.h>
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync#include <iprt/ldr.h>
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include <iprt/mem.h>
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include <iprt/stream.h>
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync#include <iprt/string.h>
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include "../Runtime/include/internal/ldrMZ.h" /* ugly */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#include "../Runtime/include/internal/ldrPE.h" /* ugly */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Structures and Typedefs *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** @name Internal WinNT structures
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @{ */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * PsLoadedModuleList entry for 32-bit NT aka LDR_DATA_TABLE_ENTRY.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Tested with XP.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef struct NTMTE32
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync struct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t Flink;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t Blink;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync } InLoadOrderLinks,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync InMemoryOrderModuleList,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync InInitializationOrderModuleList;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t DllBase;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t EntryPoint;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t SizeOfImage;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync struct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t Length;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t MaximumLength;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t Buffer;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync } FullDllName,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync BaseDllName;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t Flags;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t LoadCount;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t TlsIndex;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* ... there is more ... */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} NTMTE32;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef NTMTE32 *PNTMTE32;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * PsLoadedModuleList entry for 32-bit NT aka LDR_DATA_TABLE_ENTRY.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Tested with XP.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @todo This is incomplete and just to get rid of warnings.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef struct NTMTE64
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync struct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint64_t Flink;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint64_t Blink;
db073d0e5fab95903c54296592a82cb35d565520vboxsync } InLoadOrderLinks, /**< 0x00 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync InMemoryOrderModuleList, /**< 0x10 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync InInitializationOrderModuleList; /**< 0x20 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint64_t DllBase; /**< 0x30 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint64_t EntryPoint; /**< 0x38 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint32_t SizeOfImage; /**< 0x40 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint32_t Alignment; /**< 0x44 */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync struct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint16_t Length; /**< 0x48,0x58 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint16_t MaximumLength; /**< 0x4a,0x5a */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint32_t Alignment; /**< 0x4c,0x5c */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint64_t Buffer; /**< 0x50,0x60 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync } FullDllName, /**< 0x48 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync BaseDllName; /**< 0x58 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint32_t Flags; /**< 0x68 */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint16_t LoadCount; /**< 0x6c */
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint16_t TlsIndex; /**< 0x6e */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* ... there is more ... */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} NTMTE64;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef NTMTE64 *PNTMTE64;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** MTE union. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef union NTMTE
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NTMTE32 vX_32;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NTMTE64 vX_64;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} NTMTE;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef NTMTE *PNTMTE;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The essential bits of the KUSER_SHARED_DATA structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef struct NTKUSERSHAREDDATA
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t TickCountLowDeprecated;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t TickCountMultiplier;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync struct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t LowPart;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int32_t High1Time;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int32_t High2Time;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync } InterruptTime,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync SystemTime,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync TimeZoneBias;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t ImageNumberLow;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t ImageNumberHigh;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTUTF16 NtSystemRoot[260];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t MaxStackTraceDepth;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t CryptoExponent;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t TimeZoneId;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t LargePageMinimum;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t Reserved2[7];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t NtProductType;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint8_t ProductTypeIsValid;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint8_t abPadding[3];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t NtMajorVersion;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t NtMinorVersion;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* uint8_t ProcessorFeatures[64];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync ...
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} NTKUSERSHAREDDATA;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef NTKUSERSHAREDDATA *PNTKUSERSHAREDDATA;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** KI_USER_SHARED_DATA for i386 */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define NTKUSERSHAREDDATA_WINNT32 UINT32_C(0xffdf0000)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** KI_USER_SHARED_DATA for AMD64 */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define NTKUSERSHAREDDATA_WINNT64 UINT64_C(0xfffff78000000000)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** NTKUSERSHAREDDATA::NtProductType */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef enum NTPRODUCTTYPE
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync kNtProductType_Invalid = 0,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync kNtProductType_WinNt = 1,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync kNtProductType_LanManNt,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync kNtProductType_Server
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} NTPRODUCTTYPE;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync/** NT image header union. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsynctypedef union NTHDRSU
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync IMAGE_NT_HEADERS32 vX_32;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync IMAGE_NT_HEADERS64 vX_64;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync} NTHDRS;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync/** Pointer to NT image header union. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsynctypedef NTHDRS *PNTHDRS;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync/** Pointer to const NT image header union. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsynctypedef NTHDRS const *PCNTHDRS;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** @} */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef enum DBGDIGGERWINNTVER
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_UNKNOWN,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_3_1,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_3_5,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_4_0,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_5_0,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_5_1,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER_6_0
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} DBGDIGGERWINNTVER;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * WinNT guest OS digger instance data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef struct DBGDIGGERWINNT
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** Whether the information is valid or not.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * (For fending off illegal interface method calls.) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync bool fValid;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** 32-bit (true) or 64-bit (false) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync bool f32Bit;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The NT version. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGDIGGERWINNTVER enmVer;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** NTKUSERSHAREDDATA::NtProductType */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NTPRODUCTTYPE NtProductType;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** NTKUSERSHAREDDATA::NtMajorVersion */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t NtMajorVersion;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** NTKUSERSHAREDDATA::NtMinorVersion */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t NtMinorVersion;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The address of the ntoskrnl.exe image. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS KernelAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The address of the ntoskrnl.exe module table entry. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS KernelMteAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** The address of PsLoadedModuleList. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS PsLoadedModuleListAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync} DBGDIGGERWINNT;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** Pointer to the linux guest OS digger instance data. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsynctypedef DBGDIGGERWINNT *PDBGDIGGERWINNT;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync/**
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync * The WinNT digger's loader reader instance data.
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsynctypedef struct DBGDIGGERWINNTRDR
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync{
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** The VM handle (referenced). */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync PUVM pUVM;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** The image base. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync DBGFADDRESS ImageAddr;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** The image size. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /** The file offset of the SizeOfImage field in the optional header if it
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * needs patching, otherwise set to UINT32_MAX. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t offSizeOfImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /** The correct image size. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t cbCorrectImageSize;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** Number of entries in the aMappings table. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t cMappings;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** Mapping hint. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t iHint;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** Mapping file offset to memory offsets, ordered by file offset. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync struct
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync {
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** The file offset. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t offFile;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** The size of this mapping. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t cbMem;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /** The offset to the memory from the start of the image. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t offMem;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync } aMappings[1];
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync} DBGDIGGERWINNTRDR;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync/** Pointer a WinNT loader reader instance data. */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsynctypedef DBGDIGGERWINNTRDR *PDBGDIGGERWINNTRDR;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Defined Constants And Macros *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** Validates a 32-bit Windows NT kernel address */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define WINNT32_VALID_ADDRESS(Addr) ((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** Validates a 64-bit Windows NT kernel address */
db073d0e5fab95903c54296592a82cb35d565520vboxsync #define WINNT64_VALID_ADDRESS(Addr) ((Addr) > UINT64_C(0xffff800000000000) && (Addr) < UINT64_C(0xfffffffffffff000))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** Validates a kernel address. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define WINNT_VALID_ADDRESS(pThis, Addr) ((pThis)->f32Bit ? WINNT32_VALID_ADDRESS(Addr) : WINNT64_VALID_ADDRESS(Addr))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** Versioned and bitness wrapper. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define WINNT_UNION(pThis, pUnion, Member) ((pThis)->f32Bit ? (pUnion)->vX_32. Member : (pUnion)->vX_64. Member )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** The length (in chars) of the kernel file name (no path). */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define WINNT_KERNEL_BASE_NAME_LEN 12
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** WindowsNT on little endian ASCII systems. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync#define DIG_WINNT_MOD_TAG UINT64_C(0x54696e646f774e54)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Internal Functions *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(int) dbgDiggerWinNtInit(PUVM pUVM, void *pvData);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Global Variables *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/** Kernel names. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic const RTUTF16 g_wszKernelNames[][WINNT_KERNEL_BASE_NAME_LEN + 1] =
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync { 'n', 't', 'o', 's', 'k', 'r', 'n', 'l', '.', 'e', 'x', 'e' }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync};
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync/** @callback_method_impl{PFNRTLDRRDRMEMREAD} */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsyncstatic DECLCALLBACK(int) dbgDiggerWinNtRdr_Read(void *pvBuf, size_t cb, size_t off, void *pvUser)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync{
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync PDBGDIGGERWINNTRDR pThis = (PDBGDIGGERWINNTRDR)pvUser;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t offFile = (uint32_t)off;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync AssertReturn(offFile == off, VERR_INVALID_PARAMETER);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t i = pThis->iHint;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (pThis->aMappings[i].offFile > offFile)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync {
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync i = pThis->cMappings;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync while (i-- > 0)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (offFile >= pThis->aMappings[i].offFile)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync break;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync pThis->iHint = i;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync }
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync while (cb > 0)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync {
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t offNextMap = i + 1 < pThis->cMappings ? pThis->aMappings[i + 1].offFile : pThis->cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t offMap = offFile - pThis->aMappings[i].offFile;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /* Read file bits backed by memory. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (offMap < pThis->aMappings[i].cbMem)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync {
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t cbToRead = pThis->aMappings[i].cbMem - offMap;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (cbToRead > cb)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync cbToRead = (uint32_t)cb;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync DBGFADDRESS Addr = pThis->ImageAddr;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync DBGFR3AddrAdd(&Addr, pThis->aMappings[i].offMem + offMap);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync int rc = DBGFR3MemRead(pThis->pUVM, 0 /*idCpu*/, &Addr, pvBuf, cbToRead);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (RT_FAILURE(rc))
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync return rc;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /* Apply SizeOfImage patch? */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if ( pThis->offSizeOfImage != UINT32_MAX
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync && offFile < pThis->offSizeOfImage + 4
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync && offFile + cbToRead > pThis->offSizeOfImage)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t SizeOfImage = pThis->cbCorrectImageSize;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync uint32_t cbPatch = sizeof(SizeOfImage);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync int32_t offPatch = pThis->offSizeOfImage - offFile;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint8_t *pbPatch = (uint8_t *)pvBuf + offPatch;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (offFile + cbToRead < pThis->offSizeOfImage + cbPatch)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync cbPatch = offFile + cbToRead - pThis->offSizeOfImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync while (cbPatch-- > 0)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (offPatch >= 0)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync *pbPatch = (uint8_t)SizeOfImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync offPatch++;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pbPatch++;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync SizeOfImage >>= 8;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /* Done? */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (cbToRead == cb)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync break;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync offFile += cbToRead;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync cb -= cbToRead;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pvBuf = (char *)pvBuf + cbToRead;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync }
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /* Mind the gap. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (offNextMap > offFile)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t cbZero = offNextMap - offFile;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (cbZero > cb)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync {
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync RT_BZERO(pvBuf, cb);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync break;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync }
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync RT_BZERO(pvBuf, cbZero);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync offFile += cbZero;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync cb -= cbZero;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pvBuf = (char *)pvBuf + cbZero;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync }
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync pThis->iHint = ++i;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync }
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync return VINF_SUCCESS;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync}
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync/** @callback_method_impl{PFNRTLDRRDRMEMDTOR} */
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsyncstatic DECLCALLBACK(void) dbgDiggerWinNtRdr_Dtor(void *pvUser)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync{
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync PDBGDIGGERWINNTRDR pThis = (PDBGDIGGERWINNTRDR)pvUser;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync VMR3ReleaseUVM(pThis->pUVM);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync pThis->pUVM = NULL;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync RTMemFree(pvUser);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync}
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync/**
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Checks if the section headers look okay.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync *
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * @returns true / false.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * @param paShs Pointer to the section headers.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * @param cShs Number of headers.
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * @param cbImage The image size reported by NT.
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * @param uRvaRsrc The RVA of the resource directory. UINT32_MAX if
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * no resource directory.
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * @param cbSectAlign The section alignment specified in the header.
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * @param pcbImageCorrect The corrected image size. This is derived from
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * cbImage and virtual range of the section tables.
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync *
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * The problem is that NT may choose to drop the
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * last pages in images it loads early, starting at
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * the resource directory. These images will have
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * a page aligned cbImage.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsyncstatic bool dbgDiggerWinNtCheckSectHdrsAndImgSize(PCIMAGE_SECTION_HEADER paShs, uint32_t cShs, uint32_t cbImage,
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync uint32_t uRvaRsrc, uint32_t cbSectAlign, uint32_t *pcbImageCorrect)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync{
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync *pcbImageCorrect = cbImage;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync for (uint32_t i = 0; i < cShs; i++)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (!paShs[i].Name[0])
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync Log(("DigWinNt: Section header #%u has no name\n", i));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return false;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync continue;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /* Check that sizes are within the same range and that both sizes and
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync addresses are within reasonable limits. */
fa421f77df9e7af3a16bc3df8eca61cc752b2b77vboxsync if ( RT_ALIGN(paShs[i].Misc.VirtualSize, _64K) < RT_ALIGN(paShs[i].SizeOfRawData, _64K)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync || paShs[i].Misc.VirtualSize >= _1G
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync || paShs[i].SizeOfRawData >= _1G)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync Log(("DigWinNt: Section header #%u has a VirtualSize=%#x and SizeOfRawData=%#x, that's too much data!\n",
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync i, paShs[i].Misc.VirtualSize, paShs[i].SizeOfRawData));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return false;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync uint32_t uRvaEnd = paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync if (uRvaEnd >= _1G || uRvaEnd < paShs[i].VirtualAddress)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync Log(("DigWinNt: Section header #%u has a VirtualSize=%#x and VirtualAddr=%#x, %#x in total, that's too much!\n",
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync i, paShs[i].Misc.VirtualSize, paShs[i].VirtualAddress, uRvaEnd));
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync return false;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync }
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /* Check for images chopped off around '.rsrc'. */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync if ( cbImage < uRvaEnd
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync && uRvaEnd >= uRvaRsrc)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync cbImage = RT_ALIGN(uRvaEnd, cbSectAlign);
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /* Check that the section is within the image. */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync if (uRvaEnd > cbImage)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync {
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync Log(("DigWinNt: Section header #%u has a virtual address range beyond the image: %#x TO %#x cbImage=%#x\n",
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync i, paShs[i].VirtualAddress, uRvaEnd, cbImage));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return false;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync Assert(*pcbImageCorrect == cbImage || !(*pcbImageCorrect & 0xfff));
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync *pcbImageCorrect = cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return true;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync}
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync/**
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Create a loader module for the in-guest-memory PE module.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsyncstatic int dbgDiggerWinNtCreateLdrMod(PDBGDIGGERWINNT pThis, PUVM pUVM, const char *pszName, PCDBGFADDRESS pImageAddr,
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t cbImage, uint8_t *pbBuf, size_t cbBuf,
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t offHdrs, PCNTHDRS pHdrs, PRTLDRMOD phLdrMod)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync{
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /*
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Allocate and create a reader instance.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t const cShs = WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync PDBGDIGGERWINNTRDR pRdr = (PDBGDIGGERWINNTRDR)RTMemAlloc(RT_OFFSETOF(DBGDIGGERWINNTRDR, aMappings[cShs + 2]));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (!pRdr)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return VERR_NO_MEMORY;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync VMR3RetainUVM(pUVM);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->pUVM = pUVM;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->ImageAddr = *pImageAddr;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cbImage = cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cbCorrectImageSize = cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->offSizeOfImage = UINT32_MAX;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->iHint = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /*
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Use the section table to construct a more accurate view of the file/
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * image if it's in the buffer (it should be).
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync uint32_t uRvaRsrc = UINT32_MAX;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync if (WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).Size > 0)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync uRvaRsrc = WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).VirtualAddress;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t offShs = offHdrs
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync + ( pThis->f32Bit
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync ? pHdrs->vX_32.FileHeader.SizeOfOptionalHeader + RT_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync : pHdrs->vX_64.FileHeader.SizeOfOptionalHeader + RT_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t cbShs = cShs * sizeof(IMAGE_SECTION_HEADER);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync PCIMAGE_SECTION_HEADER paShs = (PCIMAGE_SECTION_HEADER)(pbBuf + offShs);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if ( offShs + cbShs <= RT_MIN(cbImage, cbBuf)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync && dbgDiggerWinNtCheckSectHdrsAndImgSize(paShs, cShs, cbImage, uRvaRsrc,
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync WINNT_UNION(pThis, pHdrs, OptionalHeader.SectionAlignment),
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync &pRdr->cbCorrectImageSize))
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cMappings = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync for (uint32_t i = 0; i < cShs; i++)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if ( paShs[i].SizeOfRawData > 0
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync && paShs[i].PointerToRawData > 0)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t j = 1;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (!pRdr->cMappings)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cMappings++;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync else
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync while (j < pRdr->cMappings && pRdr->aMappings[j].offFile < paShs[i].PointerToRawData)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync j++;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (j < pRdr->cMappings)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync memmove(&pRdr->aMappings[j + 1], &pRdr->aMappings[j], (pRdr->cMappings - j) * sizeof(pRdr->aMappings));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[j].offFile = paShs[i].PointerToRawData;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[j].offMem = paShs[i].VirtualAddress;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[j].cbMem = i + 1 < cShs
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync ? paShs[i + 1].VirtualAddress - paShs[i].VirtualAddress
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync : paShs[i].Misc.VirtualSize;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (j == pRdr->cMappings)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cbImage = paShs[i].PointerToRawData + paShs[i].SizeOfRawData;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cMappings++;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /* Insert the mapping of the headers that isn't covered by the section table. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[0].offFile = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[0].offMem = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[0].cbMem = pRdr->cMappings ? pRdr->aMappings[1].offFile : pRdr->cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync int j = pRdr->cMappings - 1;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync while (j-- > 0)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync uint32_t cbFile = pRdr->aMappings[j + 1].offFile - pRdr->aMappings[j].offFile;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (pRdr->aMappings[j].cbMem > cbFile)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[j].cbMem = cbFile;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync else
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /*
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Fallback, fake identity mapped file data.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->cMappings = 1;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[0].offFile = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[0].offMem = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pRdr->aMappings[0].cbMem = pRdr->cbImage;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /* Enable the SizeOfImage patching if necessary. */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync if (pRdr->cbCorrectImageSize != cbImage)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync {
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync Log(("DigWinNT: The image is really %#x bytes long, not %#x as mapped by NT!\n", pRdr->cbCorrectImageSize, cbImage));
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync pRdr->offSizeOfImage = pThis->f32Bit
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync ? offHdrs + RT_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader.SizeOfImage)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync : offHdrs + RT_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader.SizeOfImage);
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync }
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /*
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Call the loader to open the PE image for debugging.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Note! It always calls pfnDtor.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync RTLDRMOD hLdrMod;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync int rc = RTLdrOpenInMemory(pszName, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, pRdr->cbImage,
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync dbgDiggerWinNtRdr_Read, dbgDiggerWinNtRdr_Dtor, pRdr,
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync &hLdrMod);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (RT_SUCCESS(rc))
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync *phLdrMod = hLdrMod;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync else
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync *phLdrMod = NIL_RTLDRMOD;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return rc;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync}
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Process a PE image found in guest memory.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync *
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param pThis The instance data.
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param pUVM The user mode VM handle.
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param pszName The image name.
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param pImageAddr The image address.
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param cbImage The size of the image.
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param pbBuf Scratch buffer containing the first
98427c0ab08697e468c26dc33ee9571308577867vboxsync * RT_MIN(cbBuf, cbImage) bytes of the image.
98427c0ab08697e468c26dc33ee9571308577867vboxsync * @param cbBuf The scratch buffer size.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic void dbgDiggerWinNtProcessImage(PDBGDIGGERWINNT pThis, PUVM pUVM, const char *pszName,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PCDBGFADDRESS pImageAddr, uint32_t cbImage,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint8_t *pbBuf, size_t cbBuf)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync LogFlow(("DigWinNt: %RGp %#x %s\n", pImageAddr->FlatPtr, cbImage, pszName));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Do some basic validation first.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is the usual exteremely verbose and messy code...
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(cbBuf >= sizeof(IMAGE_NT_HEADERS64));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( cbImage < sizeof(IMAGE_NT_HEADERS64)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || cbImage >= _1M * 256)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: Bad image size: %#x\n", pszName, cbImage));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Dig out the NT/PE headers. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync IMAGE_DOS_HEADER const *pMzHdr = (IMAGE_DOS_HEADER const *)pbBuf;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync PCNTHDRS pHdrs;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t offHdrs;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (pMzHdr->e_magic != IMAGE_DOS_SIGNATURE)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync offHdrs = 0;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pHdrs = (PCNTHDRS)pbBuf;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else if ( pMzHdr->e_lfanew >= cbImage
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || pMzHdr->e_lfanew < sizeof(*pMzHdr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || pMzHdr->e_lfanew + sizeof(IMAGE_NT_HEADERS64) > cbImage)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: PE header to far into image: %#x cbImage=%#x\n", pMzHdr->e_lfanew, cbImage));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else if ( pMzHdr->e_lfanew < cbBuf
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pMzHdr->e_lfanew + sizeof(IMAGE_NT_HEADERS64) <= cbBuf)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync offHdrs = pMzHdr->e_lfanew;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pHdrs = (NTHDRS const *)(pbBuf + offHdrs);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: PE header to far into image (lazy bird): %#x\n", pMzHdr->e_lfanew));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (pHdrs->vX_32.Signature != IMAGE_NT_SIGNATURE)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: Bad PE signature: %#x\n", pszName, pHdrs->vX_32.Signature));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* The file header is the same on both archs */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (pHdrs->vX_32.FileHeader.Machine != (pThis->f32Bit ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_AMD64))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: Invalid FH.Machine: %#x\n", pszName, pHdrs->vX_32.FileHeader.Machine));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (pHdrs->vX_32.FileHeader.SizeOfOptionalHeader != (pThis->f32Bit ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64)))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: Invalid FH.SizeOfOptionalHeader: %#x\n", pszName, pHdrs->vX_32.FileHeader.SizeOfOptionalHeader));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections) > 64)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync {
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync Log(("DigWinNt: %s: Too many sections: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections)));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync }
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync const uint32_t TimeDateStamp = pHdrs->vX_32.FileHeader.TimeDateStamp;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* The optional header is not... */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (WINNT_UNION(pThis, pHdrs, OptionalHeader.Magic) != (pThis->f32Bit ? IMAGE_NT_OPTIONAL_HDR32_MAGIC : IMAGE_NT_OPTIONAL_HDR64_MAGIC))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: %s: Invalid OH.Magic: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, OptionalHeader.Magic)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync uint32_t cbImageFromHdr = WINNT_UNION(pThis, pHdrs, OptionalHeader.SizeOfImage);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync if (RT_ALIGN(cbImageFromHdr, _4K) != RT_ALIGN(cbImage, _4K))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync Log(("DigWinNt: %s: Invalid OH.SizeOfImage: %#x, expected %#x\n", pszName, cbImageFromHdr, cbImage));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (WINNT_UNION(pThis, pHdrs, OptionalHeader.NumberOfRvaAndSizes) != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
df66753ca310c5d36c3ae2cf36f78bbe333ece4fvboxsync Log(("DigWinNt: %s: Invalid OH.NumberOfRvaAndSizes: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, OptionalHeader.NumberOfRvaAndSizes)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Create the module using the in memory image first, falling back
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * on cached image.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync RTLDRMOD hLdrMod;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync int rc = dbgDiggerWinNtCreateLdrMod(pThis, pUVM, pszName, pImageAddr, cbImage, pbBuf, cbBuf, offHdrs, pHdrs,
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync &hLdrMod);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (RT_FAILURE(rc))
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync hLdrMod = NIL_RTLDRMOD;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTDBGMOD hMod;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, hLdrMod,
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_FAILURE(rc))
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync {
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /*
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Final fallback is a container module.
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync rc = RTDbgModCreate(&hMod, pszName, cbImage, 0);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (RT_FAILURE(rc))
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync rc = RTDbgModSymbolAdd(hMod, "Headers", 0 /*iSeg*/, 0, cbImage, 0 /*fFlags*/, NULL);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync AssertRC(rc);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync /* Tag the module. */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync rc = RTDbgModSetTag(hMod, DIG_WINNT_MOD_TAG);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync AssertRC(rc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Link the module.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsync RTDBGAS hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (hAs != NIL_RTDBGAS)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = RTDbgAsModuleLink(hAs, hMod, pImageAddr->FlatPtr, RTDBGASLINK_FLAGS_REPLACE /*fFlags*/);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = VERR_INTERNAL_ERROR;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTDbgModRelease(hMod);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTDbgAsRelease(hAs);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnQueryInterface
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(void *) dbgDiggerWinNtQueryInterface(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return NULL;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnQueryVersion
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(int) dbgDiggerWinNtQueryVersion(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(pThis->fValid);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync const char *pszNtProductType;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync switch (pThis->NtProductType)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case kNtProductType_WinNt: pszNtProductType = "-WinNT"; break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case kNtProductType_LanManNt: pszNtProductType = "-LanManNT"; break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case kNtProductType_Server: pszNtProductType = "-Server"; break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync default: pszNtProductType = ""; break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync RTStrPrintf(pszVersion, cchVersion, "%u.%u-%s%s", pThis->NtMajorVersion, pThis->NtMinorVersion,
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync pThis->f32Bit ? "x86" : "AMD64", pszNtProductType);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return VINF_SUCCESS;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnTerm
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(void) dbgDiggerWinNtTerm(PUVM pUVM, void *pvData)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(pThis->fValid);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->fValid = false;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnRefresh
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(int) dbgDiggerWinNtRefresh(PUVM pUVM, void *pvData)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NOREF(pThis);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(pThis->fValid);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * For now we'll flush and reload everything.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsync RTDBGAS hDbgAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (hDbgAs != NIL_RTDBGAS)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t iMod = RTDbgAsModuleCount(hDbgAs);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync while (iMod-- > 0)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTDBGMOD hMod = RTDbgAsModuleByIndex(hDbgAs, iMod);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (hMod != NIL_RTDBGMOD)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RTDbgModGetTag(hMod) == DIG_WINNT_MOD_TAG)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rc = RTDbgAsModuleUnlink(hDbgAs, hMod);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync AssertRC(rc);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTDbgModRelease(hMod);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTDbgAsRelease(hDbgAs);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
98427c0ab08697e468c26dc33ee9571308577867vboxsync dbgDiggerWinNtTerm(pUVM, pvData);
98427c0ab08697e468c26dc33ee9571308577867vboxsync return dbgDiggerWinNtInit(pUVM, pvData);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnInit
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(int) dbgDiggerWinNtInit(PUVM pUVM, void *pvData)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Assert(!pThis->fValid);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync union
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint8_t au8[0x2000];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTUTF16 wsz[0x2000/2];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NTKUSERSHAREDDATA UserSharedData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync } u;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS Addr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rc;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Figure the NT version.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsync DBGFR3AddrFromFlat(pUVM, &Addr, pThis->f32Bit ? NTKUSERSHAREDDATA_WINNT32 : NTKUSERSHAREDDATA_WINNT64);
98427c0ab08697e468c26dc33ee9571308577867vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, &u, PAGE_SIZE);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_FAILURE(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return rc;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->NtProductType = u.UserSharedData.ProductTypeIsValid && u.UserSharedData.NtProductType <= kNtProductType_Server
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync ? (NTPRODUCTTYPE)u.UserSharedData.NtProductType
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync : kNtProductType_Invalid;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->NtMajorVersion = u.UserSharedData.NtMajorVersion;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->NtMinorVersion = u.UserSharedData.NtMinorVersion;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Dig out the module chain.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS AddrPrev = pThis->PsLoadedModuleListAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Addr = pThis->KernelMteAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync do
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Read the validate the MTE. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NTMTE Mte;
98427c0ab08697e468c26dc33ee9571308577867vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, &Mte, pThis->f32Bit ? sizeof(Mte.vX_32) : sizeof(Mte.vX_64));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_FAILURE(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (WINNT_UNION(pThis, &Mte, InLoadOrderLinks.Blink) != AddrPrev.FlatPtr)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: Bad Mte At %RGv - backpointer\n", Addr.FlatPtr));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (!WINNT_VALID_ADDRESS(pThis, WINNT_UNION(pThis, &Mte, InLoadOrderLinks.Flink)) )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: Bad Mte at %RGv - forward pointer\n", Addr.FlatPtr));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (!WINNT_VALID_ADDRESS(pThis, WINNT_UNION(pThis, &Mte, BaseDllName.Buffer)))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: Bad Mte at %RGv - BaseDllName=%llx\n", Addr.FlatPtr, WINNT_UNION(pThis, &Mte, BaseDllName.Buffer)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (!WINNT_VALID_ADDRESS(pThis, WINNT_UNION(pThis, &Mte, FullDllName.Buffer)))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: Bad Mte at %RGv - FullDllName=%llx\n", Addr.FlatPtr, WINNT_UNION(pThis, &Mte, FullDllName.Buffer)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( !WINNT_VALID_ADDRESS(pThis, WINNT_UNION(pThis, &Mte, DllBase))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || WINNT_UNION(pThis, &Mte, SizeOfImage) > _1M*256
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync || WINNT_UNION(pThis, &Mte, EntryPoint) - WINNT_UNION(pThis, &Mte, DllBase) > WINNT_UNION(pThis, &Mte, SizeOfImage) )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: Bad Mte at %RGv - EntryPoint=%llx SizeOfImage=%x DllBase=%llx\n",
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Addr.FlatPtr, WINNT_UNION(pThis, &Mte, EntryPoint), WINNT_UNION(pThis, &Mte, SizeOfImage), WINNT_UNION(pThis, &Mte, DllBase)));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Read the full name. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS AddrName;
98427c0ab08697e468c26dc33ee9571308577867vboxsync DBGFR3AddrFromFlat(pUVM, &AddrName, WINNT_UNION(pThis, &Mte, FullDllName.Buffer));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t cbName = WINNT_UNION(pThis, &Mte, FullDllName.Length);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (cbName < sizeof(u))
98427c0ab08697e468c26dc33ee9571308577867vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &AddrName, &u, cbName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = VERR_OUT_OF_RANGE;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_FAILURE(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
98427c0ab08697e468c26dc33ee9571308577867vboxsync DBGFR3AddrFromFlat(pUVM, &AddrName, WINNT_UNION(pThis, &Mte, BaseDllName.Buffer));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync cbName = WINNT_UNION(pThis, &Mte, BaseDllName.Length);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (cbName < sizeof(u))
98427c0ab08697e468c26dc33ee9571308577867vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &AddrName, &u, cbName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = VERR_OUT_OF_RANGE;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_SUCCESS(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync u.wsz[cbName/2] = '\0';
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync char *pszName;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = RTUtf16ToUtf8(u.wsz, &pszName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_SUCCESS(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Read the start of the PE image and pass it along to a worker. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS ImageAddr;
98427c0ab08697e468c26dc33ee9571308577867vboxsync DBGFR3AddrFromFlat(pUVM, &ImageAddr, WINNT_UNION(pThis, &Mte, DllBase));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t cbImageBuf = RT_MIN(sizeof(u), WINNT_UNION(pThis, &Mte, SizeOfImage));
98427c0ab08697e468c26dc33ee9571308577867vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &ImageAddr, &u, cbImageBuf);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if (RT_SUCCESS(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync dbgDiggerWinNtProcessImage(pThis,
98427c0ab08697e468c26dc33ee9571308577867vboxsync pUVM,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pszName,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync &ImageAddr,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync WINNT_UNION(pThis, &Mte, SizeOfImage),
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync &u.au8[0],
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync sizeof(u));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrFree(pszName);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* next */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync AddrPrev = Addr;
98427c0ab08697e468c26dc33ee9571308577867vboxsync DBGFR3AddrFromFlat(pUVM, &Addr, WINNT_UNION(pThis, &Mte, InLoadOrderLinks.Flink));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync } while ( Addr.FlatPtr != pThis->KernelMteAddr.FlatPtr
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && Addr.FlatPtr != pThis->PsLoadedModuleListAddr.FlatPtr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->fValid = true;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return VINF_SUCCESS;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnProbe
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(bool) dbgDiggerWinNtProbe(PUVM pUVM, void *pvData)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS Addr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync union
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint8_t au8[8192];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint16_t au16[8192/2];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync uint32_t au32[8192/4];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync IMAGE_DOS_HEADER MzHdr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTUTF16 wsz[8192/2];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync } u;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync union
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync NTMTE32 v32;
db073d0e5fab95903c54296592a82cb35d565520vboxsync NTMTE64 v64;
db073d0e5fab95903c54296592a82cb35d565520vboxsync } uMte, uMte2, uMte3;
db073d0e5fab95903c54296592a82cb35d565520vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /*
df66753ca310c5d36c3ae2cf36f78bbe333ece4fvboxsync * Look for the PAGELK section name that seems to be a part of all kernels.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Then try find the module table entry for it. Since it's the first entry
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * in the PsLoadedModuleList we can easily validate the list head and report
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * success.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
db073d0e5fab95903c54296592a82cb35d565520vboxsync CPUMMODE enmMode = DBGFR3CpuGetMode(pUVM, 0 /*idCpu*/);
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint64_t const uStart = enmMode == CPUMMODE_LONG ? UINT64_C(0xfffff80000000000) : UINT32_C(0x80001000);
db073d0e5fab95903c54296592a82cb35d565520vboxsync uint64_t const uEnd = enmMode == CPUMMODE_LONG ? UINT64_C(0xffffffffffff0000) : UINT32_C(0xffff0000);
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFADDRESS KernelAddr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync for (DBGFR3AddrFromFlat(pUVM, &KernelAddr, uStart);
db073d0e5fab95903c54296592a82cb35d565520vboxsync KernelAddr.FlatPtr < uEnd;
db073d0e5fab95903c54296592a82cb35d565520vboxsync KernelAddr.FlatPtr += PAGE_SIZE)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync int rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, &KernelAddr, uEnd - KernelAddr.FlatPtr,
db073d0e5fab95903c54296592a82cb35d565520vboxsync 1, "PAGELK\0", sizeof("PAGELK\0"), &KernelAddr);
db073d0e5fab95903c54296592a82cb35d565520vboxsync if (RT_FAILURE(rc))
db073d0e5fab95903c54296592a82cb35d565520vboxsync break;
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFR3AddrSub(&KernelAddr, KernelAddr.FlatPtr & PAGE_OFFSET_MASK);
db073d0e5fab95903c54296592a82cb35d565520vboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync /* MZ + PE header. */
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &KernelAddr, &u, sizeof(u));
db073d0e5fab95903c54296592a82cb35d565520vboxsync if ( RT_SUCCESS(rc)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && u.MzHdr.e_magic == IMAGE_DOS_SIGNATURE
db073d0e5fab95903c54296592a82cb35d565520vboxsync && !(u.MzHdr.e_lfanew & 0x7)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && u.MzHdr.e_lfanew >= 0x080
db073d0e5fab95903c54296592a82cb35d565520vboxsync && u.MzHdr.e_lfanew <= 0x400) /* W8 is at 0x288*/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync if (enmMode != CPUMMODE_LONG)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync IMAGE_NT_HEADERS32 const *pHdrs = (IMAGE_NT_HEADERS32 const *)&u.au8[u.MzHdr.e_lfanew];
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( pHdrs->Signature == IMAGE_NT_SIGNATURE
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pHdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_I386
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pHdrs->FileHeader.SizeOfOptionalHeader == sizeof(pHdrs->OptionalHeader)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pHdrs->FileHeader.NumberOfSections >= 10 /* the kernel has lots */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) == IMAGE_FILE_EXECUTABLE_IMAGE
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && pHdrs->OptionalHeader.NumberOfRvaAndSizes == IMAGE_NUMBEROF_DIRECTORY_ENTRIES
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Find the MTE. */
db073d0e5fab95903c54296592a82cb35d565520vboxsync RT_ZERO(uMte);
db073d0e5fab95903c54296592a82cb35d565520vboxsync uMte.v32.DllBase = KernelAddr.FlatPtr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync uMte.v32.EntryPoint = KernelAddr.FlatPtr + pHdrs->OptionalHeader.AddressOfEntryPoint;
db073d0e5fab95903c54296592a82cb35d565520vboxsync uMte.v32.SizeOfImage = pHdrs->OptionalHeader.SizeOfImage;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS HitAddr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, &KernelAddr, uEnd - KernelAddr.FlatPtr,
db073d0e5fab95903c54296592a82cb35d565520vboxsync 4 /*align*/, &uMte.v32.DllBase, 3 * sizeof(uint32_t), &HitAddr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync while (RT_SUCCESS(rc))
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* check the name. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFADDRESS MteAddr = HitAddr;
98427c0ab08697e468c26dc33ee9571308577867vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrSub(&MteAddr, RT_OFFSETOF(NTMTE32, DllBase)),
db073d0e5fab95903c54296592a82cb35d565520vboxsync &uMte2.v32, sizeof(uMte2.v32));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( RT_SUCCESS(rc)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte2.v32.DllBase == uMte.v32.DllBase
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte2.v32.EntryPoint == uMte.v32.EntryPoint
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte2.v32.SizeOfImage == uMte.v32.SizeOfImage
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT32_VALID_ADDRESS(uMte2.v32.InLoadOrderLinks.Flink)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT32_VALID_ADDRESS(uMte2.v32.BaseDllName.Buffer)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT32_VALID_ADDRESS(uMte2.v32.FullDllName.Buffer)
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync && uMte2.v32.BaseDllName.Length <= 128
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync && uMte2.v32.FullDllName.Length <= 260
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, uMte2.v32.BaseDllName.Buffer),
db073d0e5fab95903c54296592a82cb35d565520vboxsync u.wsz, uMte2.v32.BaseDllName.Length);
db073d0e5fab95903c54296592a82cb35d565520vboxsync u.wsz[uMte2.v32.BaseDllName.Length / 2] = '\0';
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( RT_SUCCESS(rc)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync && ( !RTUtf16ICmp(u.wsz, g_wszKernelNames[0])
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* || !RTUtf16ICmp(u.wsz, g_wszKernelNames[1]) */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/,
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFR3AddrFromFlat(pUVM, &Addr, uMte2.v32.InLoadOrderLinks.Blink),
db073d0e5fab95903c54296592a82cb35d565520vboxsync &uMte3.v32, RT_SIZEOFMEMB(NTMTE32, InLoadOrderLinks));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync if ( RT_SUCCESS(rc)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte3.v32.InLoadOrderLinks.Flink == MteAddr.FlatPtr
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT32_VALID_ADDRESS(uMte3.v32.InLoadOrderLinks.Blink) )
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync {
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Log(("DigWinNt: MteAddr=%RGv KernelAddr=%RGv SizeOfImage=%x &PsLoadedModuleList=%RGv (32-bit)\n",
db073d0e5fab95903c54296592a82cb35d565520vboxsync MteAddr.FlatPtr, KernelAddr.FlatPtr, uMte2.v32.SizeOfImage, Addr.FlatPtr));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->KernelAddr = KernelAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->KernelMteAddr = MteAddr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->PsLoadedModuleListAddr = Addr;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->f32Bit = true;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return true;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync else if (RT_SUCCESS(rc))
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync {
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync Log2(("DigWinNt: Wrong module: MteAddr=%RGv ImageAddr=%RGv SizeOfImage=%#x '%ls'\n",
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync MteAddr.FlatPtr, KernelAddr.FlatPtr, uMte2.v32.SizeOfImage, u.wsz));
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync break; /* Not NT kernel */
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* next */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFR3AddrAdd(&HitAddr, 4);
db073d0e5fab95903c54296592a82cb35d565520vboxsync if (HitAddr.FlatPtr < uEnd)
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, &HitAddr, uEnd - HitAddr.FlatPtr,
db073d0e5fab95903c54296592a82cb35d565520vboxsync 4 /*align*/, &uMte.v32.DllBase, 3 * sizeof(uint32_t), &HitAddr);
db073d0e5fab95903c54296592a82cb35d565520vboxsync else
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = VERR_DBGF_MEM_NOT_FOUND;
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync else
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync IMAGE_NT_HEADERS64 const *pHdrs = (IMAGE_NT_HEADERS64 const *)&u.au8[u.MzHdr.e_lfanew];
db073d0e5fab95903c54296592a82cb35d565520vboxsync if ( pHdrs->Signature == IMAGE_NT_SIGNATURE
db073d0e5fab95903c54296592a82cb35d565520vboxsync && pHdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64
db073d0e5fab95903c54296592a82cb35d565520vboxsync && pHdrs->FileHeader.SizeOfOptionalHeader == sizeof(pHdrs->OptionalHeader)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && pHdrs->FileHeader.NumberOfSections >= 10 /* the kernel has lots */
db073d0e5fab95903c54296592a82cb35d565520vboxsync && (pHdrs->FileHeader.Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)) == IMAGE_FILE_EXECUTABLE_IMAGE
db073d0e5fab95903c54296592a82cb35d565520vboxsync && pHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC
db073d0e5fab95903c54296592a82cb35d565520vboxsync && pHdrs->OptionalHeader.NumberOfRvaAndSizes == IMAGE_NUMBEROF_DIRECTORY_ENTRIES
db073d0e5fab95903c54296592a82cb35d565520vboxsync )
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync /* Find the MTE. */
db073d0e5fab95903c54296592a82cb35d565520vboxsync RT_ZERO(uMte.v64);
db073d0e5fab95903c54296592a82cb35d565520vboxsync uMte.v64.DllBase = KernelAddr.FlatPtr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync uMte.v64.EntryPoint = KernelAddr.FlatPtr + pHdrs->OptionalHeader.AddressOfEntryPoint;
db073d0e5fab95903c54296592a82cb35d565520vboxsync uMte.v64.SizeOfImage = pHdrs->OptionalHeader.SizeOfImage;
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFADDRESS ScanAddr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFADDRESS HitAddr;
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &ScanAddr, uStart),
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync uEnd - uStart, 8 /*align*/, &uMte.v64.DllBase, 5 * sizeof(uint32_t), &HitAddr);
db073d0e5fab95903c54296592a82cb35d565520vboxsync while (RT_SUCCESS(rc))
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync /* check the name. */
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFADDRESS MteAddr = HitAddr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrSub(&MteAddr, RT_OFFSETOF(NTMTE64, DllBase)),
db073d0e5fab95903c54296592a82cb35d565520vboxsync &uMte2.v64, sizeof(uMte2.v64));
db073d0e5fab95903c54296592a82cb35d565520vboxsync if ( RT_SUCCESS(rc)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte2.v64.DllBase == uMte.v64.DllBase
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte2.v64.EntryPoint == uMte.v64.EntryPoint
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte2.v64.SizeOfImage == uMte.v64.SizeOfImage
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT64_VALID_ADDRESS(uMte2.v64.InLoadOrderLinks.Flink)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT64_VALID_ADDRESS(uMte2.v64.BaseDllName.Buffer)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT64_VALID_ADDRESS(uMte2.v64.FullDllName.Buffer)
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync && uMte2.v64.BaseDllName.Length <= 128
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync && uMte2.v64.FullDllName.Length <= 260
db073d0e5fab95903c54296592a82cb35d565520vboxsync )
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, uMte2.v64.BaseDllName.Buffer),
db073d0e5fab95903c54296592a82cb35d565520vboxsync u.wsz, uMte2.v64.BaseDllName.Length);
db073d0e5fab95903c54296592a82cb35d565520vboxsync u.wsz[uMte2.v64.BaseDllName.Length / 2] = '\0';
db073d0e5fab95903c54296592a82cb35d565520vboxsync if ( RT_SUCCESS(rc)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && ( !RTUtf16ICmp(u.wsz, g_wszKernelNames[0])
db073d0e5fab95903c54296592a82cb35d565520vboxsync /* || !RTUtf16ICmp(u.wsz, g_wszKernelNames[1]) */
db073d0e5fab95903c54296592a82cb35d565520vboxsync )
db073d0e5fab95903c54296592a82cb35d565520vboxsync )
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/,
db073d0e5fab95903c54296592a82cb35d565520vboxsync DBGFR3AddrFromFlat(pUVM, &Addr, uMte2.v64.InLoadOrderLinks.Blink),
db073d0e5fab95903c54296592a82cb35d565520vboxsync &uMte3.v64, RT_SIZEOFMEMB(NTMTE64, InLoadOrderLinks));
db073d0e5fab95903c54296592a82cb35d565520vboxsync if ( RT_SUCCESS(rc)
db073d0e5fab95903c54296592a82cb35d565520vboxsync && uMte3.v64.InLoadOrderLinks.Flink == MteAddr.FlatPtr
db073d0e5fab95903c54296592a82cb35d565520vboxsync && WINNT64_VALID_ADDRESS(uMte3.v64.InLoadOrderLinks.Blink) )
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync Log(("DigWinNt: MteAddr=%RGv KernelAddr=%RGv SizeOfImage=%x &PsLoadedModuleList=%RGv (32-bit)\n",
db073d0e5fab95903c54296592a82cb35d565520vboxsync MteAddr.FlatPtr, KernelAddr.FlatPtr, uMte2.v64.SizeOfImage, Addr.FlatPtr));
db073d0e5fab95903c54296592a82cb35d565520vboxsync pThis->KernelAddr = KernelAddr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync pThis->KernelMteAddr = MteAddr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync pThis->PsLoadedModuleListAddr = Addr;
db073d0e5fab95903c54296592a82cb35d565520vboxsync pThis->f32Bit = false;
db073d0e5fab95903c54296592a82cb35d565520vboxsync return true;
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync else if (RT_SUCCESS(rc))
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
db073d0e5fab95903c54296592a82cb35d565520vboxsync Log2(("DigWinNt: Wrong module: MteAddr=%RGv ImageAddr=%RGv SizeOfImage=%#x '%ls'\n",
db073d0e5fab95903c54296592a82cb35d565520vboxsync MteAddr.FlatPtr, KernelAddr.FlatPtr, uMte2.v64.SizeOfImage, u.wsz));
db073d0e5fab95903c54296592a82cb35d565520vboxsync break; /* Not NT kernel */
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync /* next */
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync DBGFR3AddrAdd(&HitAddr, 8);
db073d0e5fab95903c54296592a82cb35d565520vboxsync if (HitAddr.FlatPtr < uEnd)
db073d0e5fab95903c54296592a82cb35d565520vboxsync rc = DBGFR3MemScan(pUVM, 0 /*idCpu*/, &HitAddr, uEnd - HitAddr.FlatPtr,
a36108d50d9b9ebef4891548318f5e820bc6cb6cvboxsync 8 /*align*/, &uMte.v64.DllBase, 3 * sizeof(uint32_t), &HitAddr);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync else
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = VERR_DBGF_MEM_NOT_FOUND;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync }
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return false;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnDestruct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(void) dbgDiggerWinNtDestruct(PUVM pUVM, void *pvData)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/**
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGFOSREG::pfnConstruct
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync */
98427c0ab08697e468c26dc33ee9571308577867vboxsyncstatic DECLCALLBACK(int) dbgDiggerWinNtConstruct(PUVM pUVM, void *pvData)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync PDBGDIGGERWINNT pThis = (PDBGDIGGERWINNT)pvData;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->fValid = false;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->f32Bit = false;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync pThis->enmVer = DBGDIGGERWINNTVER_UNKNOWN;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return VINF_SUCCESS;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync}
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncconst DBGFOSREG g_DBGDiggerWinNt =
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync{
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .u32Magic = */ DBGFOSREG_MAGIC,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .fFlags = */ 0,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .cbData = */ sizeof(DBGDIGGERWINNT),
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .szName = */ "WinNT",
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnConstruct = */ dbgDiggerWinNtConstruct,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnDestruct = */ dbgDiggerWinNtDestruct,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnProbe = */ dbgDiggerWinNtProbe,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnInit = */ dbgDiggerWinNtInit,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnRefresh = */ dbgDiggerWinNtRefresh,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnTerm = */ dbgDiggerWinNtTerm,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnQueryVersion = */ dbgDiggerWinNtQueryVersion,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .pfnQueryInterface = */ dbgDiggerWinNtQueryInterface,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* .u32EndMagic = */ DBGFOSREG_MAGIC
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync};
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync