IDA Dynamic Debugging
- 1 视频也可以含恶意代码吗
- 2 Frida 入门
- 3 虚拟机保护
- 4 C#逆向入门
- 5 安卓刷机一点通
- 6 Z3-Solver教程
- 7 出题人的“恶意”
- 8 编译器为我做了什么
- 9 CSAPP Lab2 Note
- 10 Hash系列算法
- 11 程序脱壳
- 12 安卓逆向介绍
- 13 IDA类型修复
- 14 IDA疑难杂症
- 15 花指令
- 16 反动态调试技术与应对手段
- 17 AES加密算法
- 18 如何解决魔改后的加密算法
- 19 常见加密算法识别与变种分析
- 20 TEA 加密算法
- 21 RC4 加密算法
- 22 Base64 编码
- 23 IDA Dynamic Debugging 本文
- 24 IDA Usage With Reverse Basic
1. 动态调试的概念
动态调试是指在程序运行中,通过附加在程序进程上的调试器 (debugger),获知程序的执行流程、内存数据和寄存器信息等的一种手段。
我们还有其他的监控程序运行的手段,比如动态插装和内存修改器(CE大法好)
对于逆向工程,动态调试可以帮助使用者验证静态分析时的一些猜测,有时可以直接解决静态分析下表面上复杂的算法,例如对于某个本质上是可逆的算法,可以直接将密文作为输入,在动态调试中查看原程序处理后的明文。这比从头写解密脚本要快速得多,而且不容易出错。
建议可以多尝试动态调试,看看能不能通过原程序直接得到 flag,有些题目是算法完全可逆,有些则是 flag 与输入无关。
我们还可以通过动态调试完成对花指令和壳的分析。另外,有些数据只有经过动态调试才能知道它在内存中实际是什么样子(比如可恶的大/小端序)
IDA 可以应对大部分动态调试任务。如果出现 IDA 无法调试的情况,可以换用 Ollydbg (32-bits) 和 x64dbg,因为后两者有比较完善的反调试插件(OpenSource魅力时刻)。
2.IDA支持的调试特性
2.1 断点
-
软件断点
IDA将程序目标地址上的原字节覆盖为调试字节。当断点命中时,IDA再恢复原字节
-
硬件断点
IDA利用CPU提供的断点机制,将目标地址存入特殊的几个寄存器。CPU执行到目标地址时,会向操作系统发送异常指令,IDA就会捕获这个断点。硬件断点不会修改内存数据,隐蔽性强,但有数量限制
-
条件断点
用户预设一段代码,程序执行到断点处,执行这段代码。如果代码返回
True,命中断点;如果代码返回False,不命中断点。 -
脚本断点
用户预设一个脚本,每命中断点一次就执行一次脚本。脚本执行完后可以返回
False比如我们希望循环获取程序中某个寄存器的值,并且要求自动处理断点,我们就可以设置脚本断点,并让其返回
False
2.2 控制程序运行
-
步入
-
步过
-
步出函数
-
执行到光标位置
2.3 调试代码
-
汇编级
-
伪代码级
-
源码级
2.4 内存操作
-
寄存器读写
-
内存读写
2.5 特殊调试
-
进程调试
-
附加调试
3.IDA动态调试演示
BUUCTF - Reverse1
我们先查看程序的伪代码:
printf("input the flag:"); scanf("%20s", Str1); v5 = j_strlen(Str2); if ( !strncmp(Str1, Str2, v5) ) printf("this is the right flag!\n"); else printf("wrong flag\n");本段程序的目的是比较Str1和Str2。Str1由我们输入,而Str2作为目标flag,是不依附于任何输入的。我们可以对
if ( !strncmp(Str1, Str2, v5) )这一行设置断点,当断点命中时,查看Str2的值


FCTF 2025 - Tree
本题如果只靠静态分析加密算法的话是很吓人的,毕竟这里的加密算法又是二叉树又是 DFS 的,一看就搞不定。
真的搞不定吗?可以动态调试看看。
将密文作为输入,下断点在加密函数执行后,查看用户输入变量,惊奇地发现我们已经得到了 flag——不需要任何的密码和算法经验。
为什么?如果去问 DeepSeek,可以找到一些答案(但不要寄希望于小鲸鱼可以直接写出解密脚本,它也说不清楚):所有子节点指针都是 NULL,实际上没有构建出任何树结构,这不过是出题者写的纸老虎。此时该算法退化成简单的对称加密。
尽管如此,我们提供的信息仍然无法让 DeepSeek 给出正确的解密脚本(至少我是如此)。DeepSeek 不厌其烦地跟我提示这里还有其他未发现的加密流程,可我无法定位。动态调试的建议直到我明确表述加密和二叉树无关后才提及。
4.IDA附加调试演示
还是上面的例子,设置断点,但我们不从IDA运行程序。我们在外部先运行程序。
然后进入Debugger > Attach to process… ,选择我们要调试的进程:

开始调试后,IDA会先将程序停在某个系统dll库中,我们一般需要继续运行程序。
5.调试代码演示
F7 是步入(Step into),程序会进入当前函数。如果需要撤回,可以按 Ctrl+ F7 (Run until return)。
F8 是步过(Step over),程序不会进入当前函数。(scanf等具有阻塞机制的函数除外)
F4 是执行到光标处(Run to cursor),程序可以执行到当前位置之后的任意位置。
6.内存修改演示
调试时,我们一个比较常用的窗口是内存窗口(Hex view)。
在Hex View窗口按下 G键,或进入 Jump > Jump to address…,出现跳转窗口,输入你需要跳转到的地址即可。

IDA提供了修改内存的功能。
我们跳到Str1处。

按 F2或者右键 > Edit… 进入修改模式
通过修改对应位上的十六进制值,我们就可以修改Str1的内容:

修改完成之后再按一次 F2或者右键 > Apply Changes,保存修改结果。
有时我们需要一次性复制大量内存数据,这时就可以用其他开发者提供的插件了,比如此处使用的 LazyIDA 插件:

插件提供了十六进制输入、Base64编码输入和ASCII码输入三种输入方式:


我们的内存就被改好了。
需要注意的是,插件并不会自动添加字符串结尾的‘0’。如果你想要输入的是字符串,请手动添加末尾的‘0’。
如果需要修改寄存器的值,可以在General registers窗口点击目标寄存器的值进行修改。
7.模块窗口演示
进入Debugger > Debugger windows > Module list,弹出的窗口展示了当前程序加载的所有模块。在Windows系统上一般为.dll文件,在Linux系统上一般为.so文件。

调试.dll或.so库时需要关注这个窗口。
8.跨平台调试
8.1 Windows动态调试
如果要调试PE文件,我们直接使用IDA的Windows本地调试(Local Windows debugger)即可(当然IDA也支持远程调试Windows程序)
一般步骤:
- 选择调试器:Debugger > Select Debugger > Local Windows debugger
- 开始调试:Debugger > Start Process
注意调试前先设好断点。
8.2 Linux动态调试
Linux的ELF文件无法在Windows系统上运行,更不用说动态调试了。所以IDA提供了远程调试,在Windows上将调试指令发送到Linux上,在Linux中调试程序。
远程调试需要在被调试机上安装一个远程调试服务端。实际的调试指令由该服务端执行,IDA作为调试前端展示调试结果。
IDA和服务端之间通过tcp通信发送调试指令。
调试机和被调试机之间要保持网络畅通,一般两机是在同一个内网部署。
打开已经部署的Linux系统,将IDA安装目录(Windows)下dbgsvr的linux_server和linux_server32上传到Linux系统,运行server
对于Windows用户,可以通过以下方式部署Linux系统:
- VMWare、VirtualBox 等虚拟机软件
- WSL2(⚠️必须是 WSL2,WSL1 不能远程调试)
- 本机双系统
- 云服务
再买一台主机装Linux
我们建议,如果是以逆向为目标的部署 Linux,首选 WSL2(与 Windows 集成较好,并且仅命令行界面的性能要求不高),次选 VMWare、VirtualBox 等虚拟机软件
你应该看到这样的输出:

之后我们打开IDA。
我们还要将Windows上需要调试的文件上传到Linux中。我们可以手动上传,但在配置好远程调试后,IDA也可以帮我们上传文件到Linux。
选择 Debugger > Process options…,在弹出的窗口中按照Linux_server监听(Listen)的IP地址和端口设置Hostname和Port。
0.0.0.0表示监听所有可用地址。由于我们是本机调试,所以Hostname应填写127.0.0.1,表示本地调试。
接下来选择Remote Linux debugger,开始调试。由于Linux系统中没有目标文件,因此IDA会问我们需不需要上传到Linux中,这里我们选择Yes,然后就进入我们熟悉的调试界面了:

9.动态调试技巧
- Ctrl + N设置代码执行的位置(用来跳过不想运行的代码)
- 使用插件(如LazyIDA)批量修改内存
- 附加调试(附加到一个正在运行的进程进行调试,一般附加成功后程序会断在一个固定的库函数处)
-
一般用来调试动态库
-
绕过一些反调试
-
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!