0210、Windows 逆向入门:条件、分支与循环逆向
这一部分把高级语言里的 if、switch、循环还原成汇编中的比较、测试、条件跳转和无条件跳转。控制流能看懂,逆向时就能画出程序逻辑图。
1、内容范围
| 小节 | 内容 | 复盘点 |
|---|---|---|
| 11.2 - 11.9 | 基础指令补充 | ADD/SUB/MUL/DIV/AND/OR/NOT/XOR/CMP |
| 12.0 | TEST | 位测试和空值判断 |
| 12.1 | JCC | 条件跳转和标志位 |
| 12.2 - 12.6 | IF/三目/多条件 | 条件分支结构 |
| 12.7 - 13.1 | SWITCH | 跳转表、中转索引和折半查找 |
| 13.2 - 13.3 | LOOP/REP | 循环计数和重复前缀 |
| 13.4 - 13.8 | FOR/WHILE/DOWHILE | 循环结构、continue/break |
| 13.9 | 缓冲区溢出案例 | 只做原理和边界复盘 |
2、CMP 与 TEST
cmp a, b 本质是计算 a - b 并设置标志位,不保存结果。test a, b 本质是按位与并设置标志位,也不保存结果。
| 指令 | 常见用途 |
|---|---|
cmp eax, 0 |
判断大小或相等 |
test eax, eax |
判断是否为 0 |
test eax, 1 |
判断某个位是否为 1 |
3、JCC 条件跳转
条件跳转根据标志位决定是否跳转。
| 指令 | 常见含义 |
|---|---|
je/jz |
相等 / 结果为 0 |
jne/jnz |
不相等 / 结果非 0 |
ja/jb |
无符号大于/小于 |
jg/jl |
有符号大于/小于 |
jge/jle |
有符号大于等于/小于等于 |
复盘时一定要分清有符号和无符号跳转。
4、IF 结构
简单 if 常表现为:
1 | cmp eax, 0 |
还原时先标出 true/false 分支,再写伪代码。
5、三目运算符
三目可能编译成条件跳转,也可能编译成条件移动。不要看到没有明显分支就以为没有条件逻辑。
6、多条件 IF
&&、|| 通常有短路逻辑。
| 表达式 | 特点 | ||
|---|---|---|---|
a && b |
a 为假时不再判断 b |
||
| `a | b` | a 为真时不再判断 b |
汇编中会表现为多个比较和跳转。
7、SWITCH 结构
switch 可能编译成:
| 形式 | 场景 |
|---|---|
| 连续 if | 分支少 |
| 跳转表 | case 密集 |
| 索引表 | case 值不连续但可映射 |
| 折半查找 | case 多且分散 |
看到间接跳转时,要警惕它可能是跳转表。
8、循环结构
| 高级结构 | 汇编特征 |
|---|---|
for |
初始化、比较、循环体、更新 |
while |
先判断,再执行 |
do while |
先执行,再判断 |
break |
跳到循环后 |
continue |
跳到下一轮判断或更新 |
还原循环时先找循环头、循环体、回跳边和退出边。
9、缓冲区案例复盘
缓冲区问题只按防护和原理复盘:
| 关注点 | 说明 |
|---|---|
| 边界 | 写入是否超过数组长度 |
| 邻近数据 | 越界后覆盖了什么 |
| 崩溃位置 | 异常地址和调用栈 |
| 修复 | 限制长度、检查返回值、使用安全接口 |
不整理可直接用于攻击的载荷构造。
10、学习检查清单
| 检查项 | 状态 |
|---|---|
能区分 cmp 和 test |
待复盘 |
| 能根据 JCC 还原简单 if | 待复盘 |
| 能看懂短路逻辑的跳转结构 | 待复盘 |
| 能识别 switch 跳转表 | 待复盘 |
| 能画出 for/while/do while 的控制流图 | 待复盘 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!











