下面POC CODE
显示了如何使用从 pdb 中提取 TypeInfodia sdk
//小心处理脆弱的代码
#include "typefrompdb.h"
int main(int argc, char* argv[]) {
USAGE;
swprintf(pdb, MAX_PATH,L"%S",argv[1]);
swprintf(type, MAX_PATH,L"%S",argv[2]);
result = CoInitialize(NULL);
result = CoCreateInstance( CLSID_DiaSource,NULL,
CLSCTX_INPROC_SERVER,__uuidof( IDiaDataSource ),(void **) &pSource);
result = pSource->loadDataFromPdb(pdb);
SHOUT("%s 2find %S %d\n",(result==S_OK)?"succeded":"failed",pdb,__LINE__);
result = pSource->openSession(&pSession);
result = pSession->get_globalScope(&pSymbol);
result = pSymbol->findChildren(SymTagUDT,type,nsNone,&pEnumsymbols);
result = pEnumsymbols->get_Count(&count);
result = pEnumsymbols->Next(1,&pSymudt,&noofsymret);
SHOUT("%s 2find %S %d\n",(result==S_OK)?"succeded":"failed",type,__LINE__);
result = pSymudt->get_name(udtname);
result = pSymudt->findChildren(SymTagNull,NULL,nsNone,&pEnumsymbols);
result = pEnumsymbols->get_Count(&count);
SHOUT("no of members in struct %S is 0X%X %d\n",type,count,__LINE__);
wprintf(L"\nstruct %s {\nType Leng Tags Name \n",*udtname);
for (LONG i =0 ; i< count; i++) {
result = pEnumsymbols->Next(1,&pSymchild,&noofsymret);
result = pSymchild->get_name(childname);
result = pSymchild->get_type(&pSymtags);
result = pSymtags->get_symTag(&dwtag);
result = pSymtags->get_length(&len);
result = pSymtags->get_baseType(&basetype);
wprintf(L"0x%.2X 0x%.2I64X 0x%.2X %s\n",basetype,len,dwtag,*childname);
} return 0; }
头文件类型的内容来自pdb.h
/* handling errors/releasing memory BSTRS pointers closing handles using
sensible coding standards using dynamic allocations replacing ansi with unicode
etc etc etc should be implemented POC CODE not meant for blind copy pasting
typical test case is typefrompdb.exe ntdll.pdb _DRIVER_OBJECT */
#include <stdio.h>
#include <Windows.h>
#include <Dia2.h> // set INCLUDE=diasdkdir\inc
#include <atlbase.h> // vs 2010 express edition used with wdk 7600
#include <atlcom.h> // set INCLUDE=C:\WinDDK\7600.16385.1\inc\atl71
#include <dbghelp.h> // set INCLUDE=windbg\sdk\inc
#define SHOUT(...) if(result!=S_OK){printf(__VA_ARGS__);exit(0);\
}else{printf(__VA_ARGS__);}
#define USAGE if (argc != 3) { printf( \
"usage %s %s %s\n",argv[0],"file.pdb","typename"); return 0;}
HRESULT result = E_FAIL;
IDiaDataSource *pSource = NULL;
IDiaSession *pSession = NULL;
IDiaSymbol *pSymbol,*pSymchild = NULL;
IDiaEnumSymbols *pEnumsymbols = NULL;
wchar_t pdb[500], type[500] = {0};
BSTR childname[0x100],udtname[0x100] = {0};
LONG count = 0;
ULONG noofsymret = 0;
DWORD dwtag,basetype = 0;
ULONGLONG len = 0;
CComPtr< IDiaSymbol > pSymudt;
CComPtr< IDiaSymbol > pSymtags;
编译并链接到
@call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
set INCLUDE=XXXX;XXXX;XXXX;%INCLUDE%
set LIB=YYYY;YYYY;YYYY;%LIB%
cl /c /Zi /nologo /W4 /wd6387 /analyze %1%
link /DEBUG /nologo /RELEASE /IGNORE:4254 diaguids.lib *.obj
pause
测试用例的结果
typefrompdb.exe
usage typefrompdb.exe file.pdb typename
typefrompdb.exe ntd dr
failed 2find ntd 11
typefrompdb.exe ntdll.pdb _driver_object
succeded 2find ntdll.pdb 11
failed 2find _driver_object 17
typefrompdb.exe ntdll.pdb _DRIVER_OBJECT
succeded 2find ntdll.pdb 11
succeded 2find _DRIVER_OBJECT 17
no of members in struct _DRIVER_OBJECT is 0XF 21
struct _DRIVER_OBJECT {
Type Leng Tags Name
0x06 0x02 0x10 Type
0x06 0x02 0x10 Size
0x00 0x04 0x0E DeviceObject
0x0E 0x04 0x10 Flags
0x00 0x04 0x0E DriverStart
0x0E 0x04 0x10 DriverSize
0x00 0x04 0x0E DriverSection
0x00 0x04 0x0E DriverExtension
0x00 0x08 0x0B DriverName
0x00 0x04 0x0E HardwareDatabase
0x00 0x04 0x0E FastIoDispatch
0x00 0x04 0x0E DriverInit
0x00 0x04 0x0E DriverStartIo
0x00 0x04 0x0E DriverUnload
0x00 0x70 0x0F MajorFunction
典型测试用例的结果解释
grep -iE "btint|btulong|btnotype" cvconst.h
btNoType = 0,
btInt = 6,
btULong = 14,
grep -i -A 35 "enum symtagenum" cvconst.h
| awk "{ if ( NR==0x0B || NR==0x0E || NR==0x0F || NR==0x10 ) print $0 }"
SymTagAnnotation,
SymTagUDT,
SymTagEnum,
SymTagFunctionType,
编辑
我从来不确定这是一个答案,这更多的是使用 dia sdk 的测试或实验,
SymLoadModule uses an arbitrary address hardcoded as 0x1000000
您可以看到DBH src
在平台 sdk 示例中,相同 src 的已编译二进制文件在 windbg 安装中可用
C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\winbase\debug\dbh
//global
DWORD64 gDefaultBaseForVirtualMods;
BOOL init()
{
int i;
*gModName = 0;
gBase = 0;;
gDefaultBaseForVirtualMods = 0x1000000;
else if (!_tcsicmp(ext, _T(".pdb")))
{
addr = gDefaultBaseForVirtualMods;
dontopen = true;
} else {
addr = gDefaultBase;
}
C:\>dbh XXXXXXX\ntdll.pdb t _DRIVER_OBJECT
name : _DRIVER_OBJECT
addr : 0
size : a8
flags : 0
type : 1
modbase : 1000000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagUDT (b)
index : 1
C:\>
无论如何i would reiterate that you are
不在 supposed to use dbghelp functions
windbg扩展中阅读以下链接上的注释(编写wdbg扩展/ dbgeng扩展/ engextcpp函数,该函数声明不支持在windbg扩展中使用dbghelp函数
Note You must not attempt to call any DbgHelp or ImageHlp routines from any debugger extension. Calling these routines is not supported and may cause a variety of problems.
编写 wdbgexts windbg 扩展
编写 dbgeng windbg 扩展
编写 engextcpp windbg 扩展