- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试编写一个适用于实时远程目标和故障转储的 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
关于c - 从已卸载模块的 pdb 中提取结构信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25066514/
我目前正在尝试基于哈希表构建字典。逻辑是:有一个名为 HashTable 的结构,其中包含以下内容: HashFunc HashFunc; PrintFunc PrintEntry; CompareF
如果我有一个指向结构/对象的指针,并且该结构/对象包含另外两个指向其他对象的指针,并且我想删除“包含这两个指针的对象而不破坏它所持有的指针”——我该怎么做这样做吗? 指向对象 A 的指针(包含指向对象
像这样的代码 package main import "fmt" type Hello struct { ID int Raw string } type World []*Hell
我有一个采用以下格式的 CSV: Module, Topic, Sub-topic 它需要能够导入到具有以下格式的 MySQL 数据库中: CREATE TABLE `modules` ( `id
通常我使用类似的东西 copy((uint8_t*)&POD, (uint8_t*)(&POD + 1 ), back_inserter(rawData)); copy((uint8_t*)&PODV
错误 : 联合只能在具有兼容列类型的表上执行。 结构(层:字符串,skyward_number:字符串,skyward_points:字符串)<> 结构(skyward_number:字符串,层:字符
我有一个指向结构的指针数组,我正在尝试使用它们进行 while 循环。我对如何准确初始化它并不完全有信心,但我一直这样做: Entry *newEntry = malloc(sizeof(Entry)
我正在学习 C,我的问题可能很愚蠢,但我很困惑。在这样的函数中: int afunction(somevariables) { if (someconditions)
我现在正在做一项编程作业,我并没有真正完全掌握链接,因为我们还没有涉及它。但是我觉得我需要它来做我想做的事情,因为数组还不够 我创建了一个结构,如下 struct node { float coef;
给定以下代码片段: #include #include #define MAX_SIZE 15 typedef struct{ int touchdowns; int intercepti
struct contact list[3]; int checknullarray() { for(int x=0;x<10;x++) { if(strlen(con
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Empty “for” loop in Facebook ajax what does AJAX call
我刚刚在反射器中浏览了一个文件,并在结构构造函数中看到了这个: this = new Binder.SyntaxNodeOrToken(); 我以前从未见过该术语。有人能解释一下这个赋值在 C# 中的
我经常使用字符串常量,例如: DICT_KEY1 = 'DICT_KEY1' DICT_KEY2 = 'DICT_KEY2' ... 很多时候我不介意实际的文字是什么,只要它们是独一无二的并且对人类读
我是 C 的新手,我不明白为什么下面的代码不起作用: typedef struct{ uint8_t a; uint8_t* b; } test_struct; test_struct
您能否制作一个行为类似于内置类之一的结构,您可以在其中直接分配值而无需调用属性? 前任: RoundedDouble count; count = 5; 而不是使用 RoundedDouble cou
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
在创建嵌套列表时,我认为 R 具有对列表元素有用的命名结构。我有一个列表列表,并希望应用包含在任何列表中的每个向量的函数。 lapply这样做但随后剥离了列表的命名结构。我该怎么办 lapply嵌套列
我正在做一个用于学习目的的个人组织者,我从来没有使用过 XML,所以我不确定我的解决方案是否是最好的。这是我附带的 XML 文件的基本结构:
我是新来的 nosql概念,所以当我开始学习时 PouchDB ,我找到了这个转换表。我的困惑是,如何PouchDB如果可以说我有多个表,是否意味着我需要创建多个数据库?因为根据我在 pouchdb
我是一名优秀的程序员,十分优秀!