如何使用 SymLoadModuleEx 加载 PDB 文件?
我正在尝试调用 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 文件中查找与给定地址对应的符号?
I'm trying to call SymLoadModuleEx
to load the symbols from a PDB file and then use SymFromAddr
to look up symbols from that PDB. However, I can't figure out what to pass for the parameters BaseOfDll
and DllSize
-- the documentation explicitly says that when loading a PDB file, these parameters can't be 0, and indeed attempting to pass 0 results in it failing with ERROR_INVALID_PARAMETER
.
Here's what my code looks like:
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");
}
How do you figure out what BaseOfDll
and DllSize
to pass in when loading a PDB file? The PDB file in question is the symbol file for a different program executable (not a DLL), and just for the sake of argument, assume that you don't have access to the original EXE from which the PDB was generated.
Alternatively, is there a better method of looking up the symbols corresponding to a given address from a PDB file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
dbghelp.dll 和此处的
Sym*
方法利用 调试接口访问 (DIA) SDK。1DIA 本身是基于 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
。dbghelp.dll and the
Sym*
methods here make use of the Debug Interface Access (DIA) SDK.1DIA itself is COM-based and much more flexible than what DbgHelp offers.
Specifically, to load a known PDB and lookup a symbol based on an address, you can do the following:
IDiaDataSource::loadDataFromPdb
to load a specific PDB (DLL size and base address are not needed).IDiaDataSource::openSession
to get theIDiaSession
for your data source.findSymbolByVA
orfindSymbolByRVA
, respectively, to get theIDiaSymbol
associated with that address.IDiaSymbol::get_name
to get the function name containing the address you specified.None of this requires the original image; only the PDB is required. Assuming you're using Visual Studio, the headers and libraries for DIA are available under (for example):
C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK
.Dia2Dump 示例非常适合我将相对虚拟地址(eip 程序加载地址)解析为 pdb 以获取未解析的函数指针。这是我尝试的方法:
例如:
函数: [00447B60][0001:00446B60] ServerConfig::getSSLConfig(public: struct ssl_config __cdecl ServerConfig::getSSLConfig(void) __ptr64)
这里的 RVA 是 00447B60 [ eip - 进程加载地址 ]
该段是 0001
偏移量是00446B60
The Dia2Dump sample works well for me in resolving relative virtual address (eip-program load address) to pdb for unresolved function pointers. This is the way I try it:
For example:
Function: [00447B60][0001:00446B60] ServerConfig::getSSLConfig(public: struct ssl_config __cdecl ServerConfig::getSSLConfig(void) __ptr64)
Here the RVA is 00447B60 [ eip - Process Load Address ]
the Segment is 0001
the offset is 00446B60
我没有发表评论的权限,因此将在单独的答案中进行此操作。
DbgHelp 很紧凑,建议 Microsoft 随您的应用程序分发私有副本。 请参阅“这些内容的重新分发策略” DLL 经过专门设计,使人们能够尽可能轻松地将这些文件包含在自己的包中并发布”
我没有找到如何使用 DIA 接口下载 PDB 文件的方法。 Sym API 允许这样做。它委托对 SymSrv.dll 的调用。
所以原来的问题仍然是实际的。
I don't have permitions to comment, so will do this in separate answer.
DbgHelp is compact and recommended to distribute private copies with your application by 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"
I didn't find the way how to download PDB files using DIA interfaces. Sym API allows this. it delegates calls to SymSrv.dll.
So original question is still actual.