CTF 逆向入门:
从读懂汇编开始
逆向工程是 CTF 里让新人最头疼的方向。没有源码,只有一个可执行文件。但逆向有固定的思路和工具链。这篇文章从零讲起——逆向是什么、分析流程是什么、工具怎么用,以及去哪里找题练手。
CTF 里的逆向题,通常给你一个编译好的二进制文件。没有源代码,没有注释。你的任务是搞清楚它做了什么,然后找到 flag。
听起来很难。但逆向有方法论。大多数 CTF 逆向题都遵循相似的结构,掌握基本工具和思路之后,入门并不像想象中那么痛苦。
如果你对 CTF Web 方向感兴趣,上一篇文章讲了命令注入的完整思路:分隔符原理、常见过滤绕过、拿 flag 的步骤,以及推荐练习平台。
拿到一个逆向题,不要直接用反汇编器开干。先花几分钟做静态侦察,然后再决定切入点。
file 命令确认:ELF(Linux)还是 PE(Windows)?32 位还是 64 位?有没有被 strip(符号表删除)?这决定你用什么工具。strings 扫一遍文件里的可打印字符串。有时候 flag 直接明文存着,或者有关键提示字符串,比如 “Correct!”、”Wrong password”,帮你找到验证逻辑的位置。ltrace 跟踪库函数调用,strace 跟踪系统调用。很多简单的逆向题,用 ltrace 就能直接看到 strcmp 在比较什么,flag 就出来了。逆向有两条路可以走,实际做题时通常两者结合。
NSA 开源的反编译框架。能把汇编还原成可读的伪 C 代码。界面比 IDA 复杂,但完全免费,功能强大。CTF 入门首选。
GDB 是 Linux 下的标准调试器,pwndbg 是增强插件,让寄存器、栈、内存的显示更直观。逆向和 pwn 都会用到。
Linux 内置的基础工具。strings 提取可打印字符串,file 判断文件类型,xxd 查看十六进制。每道题开始前必跑一遍。
ltrace 追踪库函数(如 strcmp、malloc),strace 追踪系统调用(如 open、read)。很多简单题用这两个就能解。
把二进制文件的汇编代码打印出来。不如 Ghidra 直观,但速度快,命令行场景很实用。
逆向分析完,通常需要写脚本生成答案或自动化交互。pwntools 是 CTF 专用 Python 库,处理二进制数据非常方便。
用一个典型的入门题流程来说明。题目给了一个 ELF 文件 crackme,要求找到正确的密码。
crackme: ELF 64-bit LSB executable, x86-64, dynamically linked, not stripped
# 64 位 ELF,动态链接,没有 strip(符号表还在,对我们有利)
$ strings crackme
Enter password:
Correct! Flag is:
Wrong password.
# 找到关键字符串,说明程序会比较密码,比较正确后输出 flag
Enter password: test
strcmp(“test”, “s3cr3t_k3y”) # 直接看到在和什么比较!
Wrong password.
$ echo “s3cr3t_k3y” | ./crackme
Correct! Flag is: CTF{r3v3rs1ng_1s_fun}
入门题很多可以用 ltrace 直接解。但出题人知道这个,所以稍难一点的题会把比较逻辑写成自定义函数,或者做简单的字符变换,让 ltrace 看不到直接答案。这时候就要进 Ghidra 里看反编译结果。
int check_password(char *input) {
char key[] = {0x41, 0x42, 0x43, 0x31, 0x32, 0x33}; // “ABC123”
for (int i = 0; i < 6; i++) {
if (input[i] != key[i]) {
return 0; // 错误
}
}
return 1; // 正确
}
读懂这段代码,就知道密码是 ABC123。这就是静态分析的价值:不需要运行程序,直接从反编译结果推出答案。
逆向不需要你能写汇编。但要能读懂几个最常见的指令。
mov rax, 0x1 ; 把 1 存进 rax 寄存器
push rbp ; 把 rbp 压栈(函数开头常见)
pop rbp ; 弹出栈顶到 rbp(函数结尾常见)
; 比较与跳转
cmp rax, rbx ; 比较两个值,结果存入标志位
je label ; 相等则跳转(jump if equal)
jne label ; 不相等则跳转
jmp label ; 无条件跳转
; 函数调用
call func ; 调用函数
ret ; 从函数返回
; 常用寄存器(64位)
; rdi rsi rdx rcx r8 r9 → 函数参数(依次)
; rax → 函数返回值
; rsp → 栈顶指针
重点关注 cmp 和 je/jne。程序里的”判断密码对不对”,在汇编层面通常就是这两条指令的组合。找到 cmp,就找到了验证逻辑的核心位置。
crackme 类:给密码,判断对不对。流程就是上面讲的那套。先 ltrace,不行就进 Ghidra 找验证函数。
字符变换类:程序对输入做了某种变换(XOR、移位、base64 变体),然后和硬编码的目标比较。逆向出变换逻辑,写 Python 脚本反向计算。
虚拟机类(VM):程序自己实现了一套”指令集”,真正的逻辑跑在这个虚拟机上。这类题比较难,需要先逆向 VM 的解释器,再逆向 VM 字节码。CTF 入门阶段遇到可以先跳过。
加壳题:程序被加了壳(UPX 最常见),先要脱壳才能分析。file 命令会显示 “packed with UPX”,用 upx -d 脱壳后再分析。
推荐三个有逆向方向题目的平台,都免费,题目质量有保证。
NSSCTF:国内主流 CTF 平台,逆向题库完整,有难度分级,适合按难度递进练习。BUUCTF:历年赛题收录丰富,逆向方向有大量经典题,很多有附带 writeup 可以参考。Pwn.College:Arizona State University 出品,逆向和 pwn 的系统课程,从汇编基础到进阶,有配套视频,适合想打好基础的学习者。
本文所有内容用于 CTF 竞赛学习和安全教育。逆向工程技能只能在 CTF 平台、自建靶机、自己拥有的程序上练习。对他人软件进行未授权逆向可能违反软件许可协议和相关法律。


