gpt4 book ai didi

c - 从已卸载模块的 pdb 中提取结构信息

转载 作者:可可西里 更新时间:2023-11-01 14:35:59 25 4
gpt4 key购买 nike

我正在尝试编写一个适用于实时远程目标和故障转储的 WinDbg 调试器扩展。此扩展通过结构偏移向下移动并将其不同区域转换到已知对象来分析不透明的内存块。

结构在版本之间更改字段/字段顺序,所以我不能在我的调试器扩展本身中对其进行硬编码(或包含 header )。相反,我想从我有私有(private)符号的 pdb 中提取结构信息。

在 pdb/image 位于已加载模块列表中的实时目标上使用它时,效果很好,我可以使用像 GetFieldOffset 这样的函数获取类结构中的字段。

GetFieldOffset("MyClass!MyNestedClass", "m_Struct", &offsetInClass);

GetFieldData(offsetInClass + classAddr, "MyClass!_MY_STRUCT", "FieldInStruct",
sizeof(ULONG), &myFieldValue);

我的问题:当我在加载的模块列表中没有模块时(在错误的上下文中,或者分析故障转储),我无法使用上述功能。

在我正在分析的内存区域的开头,我存储了 pdb GUID 和年龄。使用它,我可以使用 SymFindFileInPath 在我的符号路径/符号缓存中找到我的 pdb 的路径。 .

char symbolPath[MAX_SYMBOL_PATH] = "";
PSTR pdbPath = NULL;

hr = ExtSymbols->lpVtbl->GetSymbolPath(ExtSymbols,
symbolPath,
sizeof(symbolPath),
NULL);

SymSetOptions(SYMOPT_IGNORE_CVREC | SYMOPT_FAIL_CRITICAL_ERRORS |
SYMOPT_CASE_INSENSITIVE);

result = SymFindFileInPath(hSymbols,
symbolPath,
Name,
&GUID,
Age,
0,
SSRVOPT_GUIDPTR,
pdbPath,
NULL,
NULL);

所以我有我的特定 pdb 实例的路径,但我不确定从这里去哪里。翻看Sym* functions由 DbgHelp.dll 公开,我没有看到使用此 pdb 文件获取类型信息的任何明显方法。 SymGetTypeInfo等函数需要一个模块库,而我的模块没有也无法加载。我所需要的只是结构中字段的字节偏移量。有什么想法吗?

谢谢!

最佳答案

下面的POC代码展示了如何使用dia sdk从pdb中提取TypeInfo

//脆弱代码小心处理

#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; }

头文件typefrompdb.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 使用硬编码为 0x1000000 的任意地址 你可以看到,在平台 sdk 示例的 DBH src 中,相同 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:\>

无论如何 我要重申你是 应该在 windbg 扩展中使用 dbghelp 函数 请阅读以下链接上的注释(编写 wdbg 扩展/dbgeng extensions/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. 

writing wdbgexts windbg extensions

writing dbgeng windbg extensions

writing engextcpp windbg extensions

关于c - 从已卸载模块的 pdb 中提取结构信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25066514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com