我正在尝试调用SymLoadModuleEx
从PDB文件加载符号,然后使用SymFromAddr
从该PDB中查找符号。但是,我无法弄清楚要为参数BaseOfDll
和DllSize
传递什么 - 文档明确说明在加载PDB文件时,这些参数不能为0,并且确实试图传递0会导致ERROR_INVALID_PARAMETER
失败。
以下是我的代码:
SymSetOptions(SYMOPT_LOAD_LINES);
HANDLE hprocess = GetCurrentProcess();
if (!SymInitialize(hprocess, NULL, FALSE))
die("SymInitialize");
if(SymLoadModuleEx(hprocess, NULL, "full path to some PDB file.pdb", NULL,
0, // What to pass here?
0, // What to pass here?
NULL, 0) == 0)
{
die("SymLoadModuleEx");
}
如何确定加载PDB文件时传入的BaseOfDll
和DllSize
?有问题的PDB文件是不同程序可执行文件(不是DLL)的符号文件,只是为了参数,假设您无权访问生成PDB的原始EXE。
或者,是否有更好的方法从PDB文件中查找与给定地址对应的符号?
答案 0 :(得分:10)
此处的dbghelp.dll和Sym*
方法使用Debug Interface Access(DIA)SDK。1
DIA本身是基于COM的,比DbgHelp提供的更灵活。
具体来说,要加载已知的PDB并根据地址查找符号,您可以执行以下操作:
IDiaDataSource::loadDataFromPdb
加载特定的PDB(不需要DLL大小和基址)。IDiaDataSource::openSession
获取数据源的IDiaSession
。findSymbolByVA
或findSymbolByRVA
来获取与IDiaSymbol
关联的内容那个地址。IDiaSymbol::get_name
获取包含您指定地址的函数名称。这些都不需要原始图像;只需要PDB。假设您使用的是Visual Studio,DIA的标题和库可以在(例如)下使用:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK
。
答案 1 :(得分:3)
查看SymLoadPdb.cpp示例here。
答案 2 :(得分:0)
Dia2Dump示例适用于我解决相对虚拟地址(eip程序加载地址)到pdb的未解析函数指针。这是我尝试的方式:
DWORD64 dwAddress = _wcstoui64(argv[i], NULL, 16);
DWORD64 dwRVA = dwAddress - dwLoadAddress;
long displacement = 0;
IDiaSymbol* pFunc = 0;
error = (DWORD)g_pDiaSession->findSymbolByRVAEx(dwRVA, SymTagFunction, &pFunc, &displacement );
if (!error && pFunc)
{
BSTR bstrName;
if (pFunc->get_name(&bstrName) != S_OK) {
wprintf(L"(???)\n\n");
}
else {
wprintf(L"%s \n\n", bstrName);
if (displacement)
wprintf(L"+ 0x%x \n\n", displacement);
else
wprintf(L" \n\n");
SysFreeString(bstrName);
}
}
例如: 功能:[00447B60] [0001:00446B60] ServerConfig :: getSSLConfig(public:struct ssl_config __cdecl ServerConfig :: getSSLConfig(void)__ ptr64)
此处RVA为00447B60 [eip - 处理加载地址] 细分是0001 偏移量为00446B60
答案 3 :(得分:0)
我没有评论的权限,所以将在单独的答案中这样做。
DbgHelp是紧凑型的,建议Microsoft通过您的应用程序分发私有副本。 See "The redistribution policies for these included DLLs were specifically designed to make it as easy as possible for people to include these files in their own packages and release"
我没有找到使用DIA接口下载PDB文件的方法。 Sym API允许这样做。它委托调用SymSrv.dll。
所以原始问题仍然存在。