前言
调试符号方便逆向分析人员在逆向分析程序时快速找到关键位置,也有助于逆向分析人员理解程序的函数功能以及代码逻辑。WinDbg是款强大的程序动态分析工具,也是从事逆向分析的人员不可或缺的工具。
WinDbg符号设置
使用WinDbg的第一步自然是设置调试符号的路径和微软的调试符号服务器。
- 设置符号路径和调试符号服务器
.sympath SRV*cache*https://msdl.microsoft.com/download/symbols
-
其中的cache是本地的符号缓存路径,需要自己根据实际磁盘空间来进行设置。例如我的缓存路径是 D : m y s y m b o l \textcolor{orange}{D:\\mysymbol} D:mysymbol,那么以上命令就写成
.sympath SRV*D:\mysymbol*https://msdl.microsoft.com/download/symbols
-
设置一个环境变量
_NT_SYMBOL_PATH
,以保证每次打开WinDbg时自动使用之前设定好的符号路径。
-
设置代理
因为调试符号服务器被墙了,需要科学上网才能下载符号文件,并且希望 WinDbg在下载符号的时候自动走代理,这需要进行如下设置:
-
设置系统环境变量
- 设置一个名为
_NT_SYMBOL_PROXY
的环境变量
- 设置一个名为
-
设置自己梯子的SOCKET代理端口要和环境变量中的一致,这里是8080。
-
-
在WinDbg中执行
!sym noisy .reload
- 第一条命令是显示符号加载(下载)过程的详细信息,方便找出加载失败的原因
- 第一条命令则是重新加载符号,可选参数:
- /d,重新加载调试器模块列表中的所有模块。
- /i,忽略 .pdb文件版本不匹配的情况。(如果没有包含该参数,调试器不会加载不匹配的符号文件。) 使用 /i时,即使没有明确指定,也会使用 /f。
- /f,强制调试器立即加载符号。该参数会覆盖延迟符号加载。
- /n,仅重加载内核符号。该参数不会重加载任何用户模式符号。(只能在内核模式调试时使用该选项。)
- /user,仅重加载用户模式符号。(只能在内核模式调试时使用该选项。)
- /u,卸载指定模块和它的所有符号。调试器卸载任何名字匹配 Module 的模块,不管它的全路径是什么。映像名也会被搜索。更多信息,查看下面的注释节。
正常情况下,做完以上 3个步骤的操作后,WinDbg就会从微软调试符号服务器中下载调试符号到缓存路径下,并根据实际调试情况自动加载符号。
意外情况
如 果 用 的 是 S O C K E T 5 的 代 理 则 不 能 正 常 下 载 符 号 文 件 \textcolor{green}{如果用的是SOCKET5的代理则不能正常下载符号文件} 如果用的是SOCKET5的代理则不能正常下载符号文件
解决办法:
首先从WinDbg的命令行窗口中复制下所有符号加载过程的详细信息到一个文本文件中,这里命名为log.txt。
使用以下脚本下载调试符号
#!/usr/bin/env python
from urllib.parse import urljoin
import os
import logging
LOG_LEVEL = logging.DEBUG
def download_file_by_curl(url, outdir, filename):
newpath = os.path.dirname(outdir)
if newpath != '':
old_path=os.getcwd()
logging.info(newpath)
if not os.path.exists(newpath):
os.makedirs(newpath)
os.chdir(os.getcwd()+"\\"+newpath)
os.system('curl -OL %s'%url)
os.chdir(old_path)
else:
os.system('curl -OL %s'%url)
def main():
filename = "log.txt"
outdir = 'downloads/'
main_url = 'https://msdl.microsoft.com/'
with open(filename, 'r') as fp:
content = fp.readlines()
for rline in content:
line = rline.strip()
if line.startswith('SYMSRV: HTTPGET:'):
m = line.split(': ')
url =urljoin(main_url, m[2])
pdb_name = m[2][len('/download/symbols/'):]
logging.info("{} {}".format(url, pdb_name))
download_file_by_curl(url, pdb_name, filename)
if __name__ == '__main__':
logging.basicConfig(format='%(asctime)s\tFile \"%(filename)s\",line %(lineno)s\t%(levelname)s: %(message)s', level=LOG_LEVEL)
main()
将脚本放到你的符号缓存目录下执行。
脚 本 需 要 使 用 到 c u r l 工 具 , 运 行 该 脚 本 前 需 要 安 装 c u r l \textcolor{green}{脚本需要使用到curl工具,运行该脚本前需要安装curl} 脚本需要使用到curl工具,运行该脚本前需要安装curl
curl下载
curl官网:https://curl.haxx.se/windows/
根据你的系统选择合适的版本下载,我的是64位的系统,对应最新版本的curl是
-
下载解压文件,我的解压路径是 G : / t o o l / n c u r l − 7.81.0 − w i n 64 − m i n g w / b i n \textcolor{orange}{G:/tool/ncurl-7.81.0-win64-mingw/bin} G:/tool/ncurl−7.81.0−win64−mingw/bin
-
设置用户环境变量Path,添加一项 G : / t o o l / c u r l − 7.81.0 − w i n 64 − m i n g w / b i n \textcolor{orange}{G:/tool/curl-7.81.0-win64-mingw/bin} G:/tool/curl−7.81.0−win64−mingw/bin
-
cmd执行
curl --version --------------------------------------------------------------------------------------- curl 7.79.1 (Windows) libcurl/7.79.1 Schannel Release-Date: 2021-09-22 Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp Features: AsynchDNS HSTS IPv6 Kerberos Largefile NTLM SPNEGO SSL SSPI UnixSockets
出现这样的信息则表示安装成功。
参考
[1] https://blog.csdn.net/counsellor/article/details/104721338
[2] https://www.cnblogs.com/hgy413/archive/2012/05/12/3693715.html
[3] https://blog.csdn.net/guzhao593/article/details/83473427