IDA 使用
本文写作时使用的 IDA Pro 版本:Version 8.3.230608 Windows x64
作者现已升级到 Version 9.2.20250908
9.2 最显著的一个特点就是正式迁移至 QT6 并提供 QT5-shims 兼容层。优先选择正式支持 9.2 的插件,若不确定兼容性,请先逐个在实际项目中测试后再使用。部分插件会抛出警告,提示现在使用 PySide6 模拟 PyQt5 行为,这是正常的。
IDA 从 Version 9 开始启用新的默认快捷键方案,如果用不惯,在 Options > Shortcuts… 里取消勾选 “Use new shortcuts”
IDA(Interactive Disassembler,交互式反汇编器)由 Hex-Rays 开发,是无数逆向工程师心中的女神是反汇编和反编译行业的首选解决方案。IDA 反编译器将机器代码(反汇编过程的结果)转换为人类可读的类似 C 语言的伪代码文本。
IDA 可以作为通用反汇编器使用,其支持的文件类型请参考 Disassembly Gallery。当然,由于是 “通用”,说明 IDA 可能无法良好完成特定语言/平台的反汇编/反编译,这时请寻找专门工具,比如 Python 的 pyc 文件有 uncompyle6 (3.8 -) 库和 pycdc (3.9 +),exe 文件有 pyinstxtractor 脚本;.NET 平台有 dnSpy 和 dotPeek;Java 有 JADX 和 JEB。
1. 安装
要么正版:ida-free
有无 Fugger 让我看看正版 😘,一年要一千多刀乐呢!
要么到 吾爱破解 上搜一搜。本笔记使用的 IDA Pro 就是来自 52 上的分享
2. Python 插件
IDA 支持以 Python 语言编写的插件。你可以在官方的 Plugins & Apps 和 Github 中找到丰富的插件;如果你有能力,也可以自己开辟一片天地。
较新版的 IDA 建议使用 Python 3.12。如果你想要更换 IDA 使用的 Python 版本,可以运行安装目录下的 idaptswitch.exe。注意 IDA 不能识别相对路径,此时请在终端运行 idaptswitch.exe -s <目标 Python 的绝对路径>。
如果你使用 Pyenv 安装系统 Python,建议在 IDA 安装目录下安装 Embeddable Python(嵌入式版本 Python)或者换用 UV 等其他管理器并设置 IDA 专用的 Python 虚拟环境。
Embeddable Python 只需要解压到 IDA 安装目录即可。注意,无论是使用 Embed 版本还是虚拟环境,均需使用所得的独立 Python 目录下的 python.exe 安装 Python 包,因为此时我们的 IDA 是不识别系统 Python 的。
注意 QT 问题。IDA 自带修改版的 QT,请不要在虚拟环境中再次安装 QT 官方的 PySide6、PyQt5 等,否则会覆盖 IDA 自带的 QT,导致窗口渲染失败。
插件的安装很简单:将插件放在安装目录下的 plugins 文件夹里就行。
这里推荐几个插件:
- KeyPatch:用于修改汇编指令。使用前需要在 python 中通过 pip 安装依赖
keystone-engine - LazyIDA:用于提取数据、批量修改数据
- Hexforge: 内置数类工具,如数据解密和内存修改。
- Hrtng:好用的反混淆插件
3. 选择哪个 IDA
进入 IDA 的安装目录,我们有两个 IDA:ida.exe 和 ida64.exe,要选哪一个?
很简单,要反汇编 32 位可执行文件,就用 ida.exe (32-bit);要反汇编 64 位可执行文件,就用 ida64.exe (64-bit)。
在 IDA 9 中,HexRays 终于将这两个可执行文件合二为一了。换句话说,对于 IDA 9,无论是 32 位还是 64 位可执行文件,都使用 ida.exe。
如果不知道可执行文件的位数,我们可以:
- 用 Linux 系统下的
file命令 - 用 peid、exeinfo 和 DIE 等查壳软件(首选 DIE)
请确保目标程序和 IDA 等逆向工具的位数相同(32 位对 32 位,64 位对 64 位),否则可能出现出乎意料的结果。
4. 熟悉 IDA 的子窗口

- 函数 (Functions) 窗口。列举所有已经被 IDA 识别的函数
- IDA View 窗口。汇编代码窗口,空格键切换图形模式和文本模式,Tab 键或 F5 键切换到伪代码窗口 (Pseudocode)
- 伪代码窗口 (Pseudocode)。在伪代码位置按下 Tab 键可以切换到对应的汇编窗口 (IDA View)。
- 字符串窗口。列举程序代码所有引用到的字符串常量
- Shift + F12 打开字符串窗口
- Ctrl + F 可以弹出底部搜索小窗口
- 其他窗口,如 HEX View、Exports、Imports、Structures
View > Open subviews 可以找到 IDA 绝大部分子窗口的入口。
5. 命名前缀
IDA 需要调试符号文件(对于 Microsoft C / C++ 和 C# 程序,为 PDB 文件)来获取代码元素(变量、函数等)的名字。如果没有,那么 IDA 会尝试自动生成这些元素的名字,一般是 prefix_ + random number。命名前缀有这些:
sub_:指令和子函数起点locret_:返回指令块loc_:普通指令块off_:数据,包含偏移量seg_:数据,包含段地址值asc_:数据,ASCII 字符串byte_:数据,字节(或字节数组)word_:数据,16 位数据(或字数组)dword_:数据,32 位数据(或双字数组)qword_:数据,64 位数据(或 4 字数组)flt_:浮点数据,32 位(或浮点数组)dbl_:浮点数,64 位(或双精度数组)tbyte_:浮点数,80 位(或扩展精度浮点数)stru_:结构体(或结构体数组)algn_:对齐指示unk_:未处理字节
6. 中文显示
IDA 默认的编码是 UTF-8,在其他编码环境下(如 Windows)会导致乱码
逆向入门
在正向开发中,程序经过设计 -> 编程 -> 调试 -> 构建,最终得到可执行文件。每一步都有信息丢失:
- 这段代码的设计目的
- 这段代码达成目的的步骤
- 注释、变量和函数名、结构化数据等额外信息(特别是软件提供者可能不会提供调试文件)
逆向工程的核心点在于:我们如何逆向出程序的设计思路?这也是为什么我们需要在逆向之前了解一些开发知识,因为你需要将自己置于开发人员的角度。
从程序讲起
模块 (Modules)
查看可执行文件的字符串时,你可能看到过像 /lib64/ld-linux-x86-64.so.2 的字样。这是程序模块,内置了重要的函数库。由于这些库具有良好的文档,因此不是我们的主要目标。
函数 (Functions)
函数具有一组封装起来的功能。大部分函数都有明确的作用,比如:
- 设置数据
- 计算/取回/验证数据
- 将任务分派给其他函数
- 在此程序外执行操作
在逆向工程中,函数可以分别逆向,最终建立起整体的思路。
一个完整的函数通常以一个序言 (prologue) 和一个尾声 (epilogue) 作为头尾。序言会设置栈帧,尾声则会卸载栈帧。
示例
我们希望找到程序中的 main 函数,因为 main 函数是程序的入口点。从 main 函数出发就能找到我们需要关心的大量代码。
如何找到 main 函数?一种方式是看 IDA 的 Functions 窗口,找找看有没有 main 函数。
没有或者列出的函数量太大的话就需要分析程序行为了。
试着运行一下程序,看看它的输入输出。很多程序会输出一些提示用字符串,我们可以通过字符串来定位main函数。
转到字符串窗口,用 Ctrl + F 唤起搜索小窗口并输入你要找的字符串,然后双击,IDA 会跳到字符串在反汇编中的位置。
你可能会看到像这样的指令:
1 | .rdata:004250EC aD db '距离出现答案还有%d秒,请耐心等待!',0Ah,0 |
这时可以右击这行指令,选择 “Jump to xref to operand” 或者 “List cross reference to…”,IDA 会列出所有引用了这个字符串的函数,然后你就可以选择要跳到main函数了。
交叉引用是个很重要的东西,它可以帮忙寻找变量的多个引用处,从而发现开发者隐藏的 “彩蛋”。
找到main函数,转到伪代码窗口,我们可以得到一个相对好阅读的代码。这个代码中有一些 IDA 没能填上的 “坑”,需要我们合理猜测,将函数和常变量猜出来。
整个流程总结起来就是:
graph LR A[查、脱壳程序] --> B[运行程序] B --> C[收集字符串] C --> D[寻找字符串的引用函数] D --> E[生成函数伪代码] E --> F[修复匿名函数] F --> G[分析程序逻辑,并写解题脚本] G --> H[获得 Flag 😄]
这是比较入门的思路,每个步骤都有可能遇到问题,比如:
- 没有可用的自动脱壳机,需要动调、写脚本
- (CTF 赛题出现)程序隐藏了一些运行文件,导致程序运行不起来,需要从二进制文件中提取
- 字符串在静态分析中被隐藏,需要动调(也可能是由于 IDA 的字符编码缺失)
- 无法生成伪代码
- 函数功能看不懂,不理解逻辑
- 脚本写不出 / 解不出
这就需要实践经验了。