Windows开发,关于通过写代码加载PDB的那些事
最近,接到一个活,要写一个程序,用来批量分析一堆dll和对应的PDB,
其实工作很简单,就是根据一堆偏移,通过PDB文件,找到对应dll里面对应位置的明文符号,
简单的需求,实现起来,通常都很麻烦,
微软的demo中,有一个demo叫做dia,这个demo可以提供类似的功能,
我很高兴地编译了这个项目,但是失败了,加载符号失败,
通过单步调试,越过了若干个小问题(比如msdia120没注册这种),发现出现问题的位置位于 loadDataForExe 这个函数上,
这个函数原型是
virtual HRESULT STDMETHODCALLTYPE loadDataForExe( LPCOLESTR executable, LPCOLESTR searchPath, IUnknown *pCallback) = 0
可以看出,参数1是要解析的可执行文件,参数2是目标dll活着exe,参数3是一个接口,可以为NULL,或者按照微软demo中不用修改。
但是执行之后发现,它给我报错,说路径错误,无法找到目标pdb。
具体错误细节不说了,浪费时间。
说说怎么解决这个问题吧。
解决方式比较简单,
首先确定思路,这个函数不能用,说明它不能自己下载符号了,那么怎么办,
解决办法就是我们下载符号,然后让它直接加载就好了,另一个函数是可以用的 loadDataFromPdb。
确定了思路,那么就要铺平道路,我怎么怎么自己下载符号,
最简单的办法,其实就是使用Windows自己的下载功能,为了尽量少开发,所以可以使用WinDBG内部的功能来自动下载符号。
这样,符号文件有了,加载方式有了,就差如何把符号文件和可执行文件对应起来了,如何对应。
通过分析,我们发现,实际上符号文件落地之后是有个特殊的目录名字的,这个名字很像一个MD5,或者很像一个GUID,
通过分析程序,最终发现,这个目录名字实际上是可执行文件内部记录的一个GUID,再在最后补上一个字符 1。
具体一点,就是这样。
PCHAR pBuffer = (PCHAR)h;
PCHAR pTemp = pBuffer + 0x3C;
pTemp = pBuffer + *(DWORD *)pTemp;
if (!(pTemp[] == 'P' && pTemp[] == 'E' && pTemp[] == '\0' && pTemp[] == '\0'))
{
return NULL;
}
PVOID *pv;
pv = (PVOID*)(pTemp + 0xA8); // 找到调试节
pTemp = pBuffer + (DWORD)*pv; // 计算调试节指定的内存地址
pv = (PVOID *)(pTemp + * ); // 找到偏移
pTemp = pBuffer + (DWORD)*pv; // 找到 UUID 基址
if (!(pTemp[] == 'R' && pTemp[] == 'S' && pTemp[] == 'D' && pTemp[] == 'S'))
{
return NULL;
}
GUID tGuid = { };
memcpy_s(&tGuid, sizeof(tGuid), pTemp + , sizeof(tGuid));
先根据可执行文件,找到PE头,从PE头里面找到调试节,
调试节里面找到GUID的偏移地址,
GUID偏移地址的前四个字符固定是RSDS,判断了之后,如果没有问题,
那么之后就是一个GUID的长度,
最后把这个GUID格式化出来变成字符串,最后再在后面补一个字符 '1' 即拼装成了当前文件对应的PDB目录名字,
然后通过这个目录名字可以拼接出一个完整的目录,很像Windows dbghelp.dll 拼接出来的目录,
然后去里面就能找到自己对应的pdb。
整个过程叙述结束。
最后总结一下。
解决pdb无法加载的方法:自己下载,独立加载。
方法:
1:使用WinDBG命令行下载可执行文件对应的PDB文件。
2:根据可执行文件计算PDB路径,寻找目标PDB。
3:找到目标PDB之后,loadDataFromPdb 直接加载PDB就好了。
Windows开发,关于通过写代码加载PDB的那些事的更多相关文章
- 支付宝小程序室内地图导航开发-支付宝小程序JS加载esmap地图
如果是微信小程序开发,请参考微信小程序室内地图导航开发-微信小程序JS加载esmap地图文章 一.在支付宝小程序里显示室内三维地图 需要满足的两个条件 调用ESMap室内地图需要用到小程序web-vi ...
- WPF中,怎样将XAML代码加载为相应的对象?
原文:WPF中,怎样将XAML代码加载为相应的对象? 在前面"在WPF中,如何得到任何Object对象的XAML代码?"一文中,我介绍了使用System.Windows.Marku ...
- 解决代码加载慢,以至于乱码—————VUE
vue.js解决开始代码加载,以至于乱码 vue.js通过几行代码可以解决这个问题 css: [v-cloak] { display: none; } html: <div id="a ...
- 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件
[源码下载] 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件 作者 ...
- 打开地图文件和shape文件代码加载Mxd文档
代码加载Mxd文档 用代码添加Mxd文档,用到AxMapControl.LoadMxFile(sFilePath),我们只要将Mxd文档的路径传给这个方法即可 /// <summary> ...
- 【转载】一行代码加载网络图片到ImageView——Android Picasso
原文链接:一句代码加载网络图片到ImageView——Android Picasso 注意:此处使用下面代码需要先配置一下gradle,下载所需包. 具体操作如下图: compile 'com.sq ...
- AngularJS进阶(三十)AngularJS项目开发技巧之图片预加载
AngularJS项目开发技巧之图片预加载 绪 项目(移动端采用Ionic 框架)开发完毕,测试阶段发现移动APP首页的广告图片(图片由服务器端返回相应url地址)很难加载,主要原因还是网速.如下图左 ...
- 模块 DLL C:\WINDOWS\system32\inetsrv\aspnetcore.dll 未能加载。返回的数据为错误信息。
更新了win10的版本后,就启动原来的iis发布的程序 程序池就自动关闭.后来 启动网站 iis程序池自动关闭. 在为应用程序池“.NET v4.5”提供服务的工作进程“21908”中,协议“http ...
- Unity开发实战探讨-资源的加载释放最佳策略简要心得
Unity开发实战探讨-资源的加载释放最佳策略简要心得 看过我另外一篇关于Unity资源释放随笔<Unity开发实战探讨-资源的加载释放最佳策略>如果觉得略微复杂,那么下面是一些比较简要的 ...
随机推荐
- 常见前端HTML5面试题
1.H5新标签新特性 新标签:header,nav,footer,aside,article,section,Canvas,audio,video 新特性:localStorag, sessionSt ...
- elasticsearch 基础 —— ReIndex
Reindex会将一个索引的数据复制到另一个已存在的索引,但是并不会复制原索引的mapping(映射).shard(分片).replicas(副本)等配置信息. 一.reindex的常用操作 1.re ...
- linux处理器子系统调优
- mongodb 索引基础
一 .索引基础: MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令: > db.test.ensureIndex({&quo ...
- PL SQL安装
首先,在官网下载PL SQL 的对应版本,本机是64位的就下载64位的,网址:https://www.allroundautomations.com/downloads.html#PLS 点击应用程序 ...
- python2和python3同时存在电脑时,安装包时的的命令行
若是在Python2中使用pip操作时,用pip2或是pip2.7相关命令. 例:给Python2安装selenium,在cmd中输入 pip2 install selenium 或是 pip2.7 ...
- .NET面试题集锦②
一.前言部分 文中的问题及答案多收集整理自网络,不保证100%准确,还望斟酌采纳. 1.实现产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复. ]; ArrayList my ...
- 随手记--QT
设置toolButton按钮隐藏(可视化): ui->toolButton->setVisible(true); 改变按钮背景色: ui->toolButton->setSty ...
- TortoiseGit操作之提交代码到远程库
1.在本地代码库的文件夹中,"右键" 2.GIT提交要求必须填写Commit message,请认真填写描述信息. 建议填写的变更项编号,如上图. 代码提交到本地的配置库中,然后p ...
- ASIO
{ 编译ASIO库时,出现编译警告, "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n& ...