2.if else 语句特征

文章目录

    • [先看原始 C 代码(心里有个目标)](#先看原始 C 代码(心里有个目标))
    • 反汇编关键代码(这是我们真正要读的)
    • 一、我第一眼在反汇编里盯的是哪?
      • [👉 永远先盯:`cmp / test + jXX`](#👉 永远先盯:cmp / test + jXX)
    • [二、条件不跳时:顺序执行的那一段,就是 then 分支](#二、条件不跳时:顺序执行的那一段,就是 then 分支)
      • [1️⃣ `result = 100`](#1️⃣ result = 100)
      • [2️⃣ 一个**很关键的无条件跳转**](#2️⃣ 一个很关键的无条件跳转)
    • [三、被条件跳转"跳到"的地方,通常就是 else 分支](#三、被条件跳转“跳到”的地方,通常就是 else 分支)
    • [四、then / else 最终都会到的地方:汇合点](#四、then / else 最终都会到的地方:汇合点)
    • [五、站在反汇编视角,总结 if / else 的"长相"](#五、站在反汇编视角,总结 if / else 的“长相”)
      • [✅ 1. `cmp / test` + `jXX`](#✅ 1. cmp / test + jXX)
      • [✅ 2. 条件不跳时,顺序执行的代码块](#✅ 2. 条件不跳时,顺序执行的代码块)
      • [✅ 3. 条件跳转的目标地址](#✅ 3. 条件跳转的目标地址)
      • [✅ 4. then / else 之后的公共位置](#✅ 4. then / else 之后的公共位置)
    • 六、把你这段代码套进去,一切都严丝合缝
    • 最后一句"逆向经验总结"

下面这段,是我在反汇编里遇到的一段非常"教科书级"的 if / else,正好可以拿来讲怎么从汇编反推 C 代码的控制结构


先看原始 C 代码(心里有个目标)

先给自己一个"答案模板",这样看汇编时心里有方向:

c 复制代码
int checkNumber(int num) {
    int result;

    if (num > 0) {
        result = 100;
    }
    else {
        result = -100;
    }

    return result;
}

逻辑非常简单:

  • 判断 num > 0

  • 真:result = 100

  • 假:result = -100

  • 最后返回 result

接下来关键是:这套逻辑在反汇编里是怎么"长出来"的?


反汇编关键代码(这是我们真正要读的)

我在 IDA / x64dbg 里看到的核心部分大概是这样(前后栈帧代码我先不关心):

asm 复制代码
00CD1506  cmp  dword ptr [ebp+8],0      ; 比较 num 和 0
00CD150A  jle  00CD1515                 ; 若 num <= 0 跳到 else 分支

00CD150C  mov  dword ptr [ebp-4],64h    ; then 分支:result = 100
00CD1513  jmp  00CD151C                 ; 跳过 else,直接到汇合点

00CD1515  mov  dword ptr [ebp-4],0FFFFFF9Ch ; else 分支:result = -100

00CD151C  mov  eax,dword ptr [ebp-4]    ; 汇合点:return result

这段代码非常典型 ,基本把 if / else 的形态全都暴露出来了。


一、我第一眼在反汇编里盯的是哪?

👉 永远先盯:cmp / test + jXX

asm 复制代码
cmp  dword ptr [ebp+8],0
jle  00CD1515

这是我在反汇编里最敏感的一种组合

  • [ebp+8]

    一看就知道是函数参数(32 位下第一个参数几乎都是这位置)。

  • cmp [ebp+8], 0

    在干嘛?很直白:拿参数跟 0 比。

  • 紧跟一个 jle
    条件跳转出现了 ,说明:

    👉 这里一定有 if / while / for / 三目运算 之类的控制结构。

这一步我不会急着想 C 代码,而是先翻译成"人话":

如果 [ebp+8] <= 0,就跳到 00CD1515

然后再反推一句:

那不跳的情况就是 num > 0

这时候,脑子里基本已经浮现出:

c 复制代码
if (num > 0) {
    ...
}
else {
    ...
}

注意一个很重要的经验点👇

汇编里的条件跳转,往往是 C 里条件的"反向写法"

C 写的是 if (num > 0)

汇编写的是 jle else

这是完全正常的,不是异常。


二、条件不跳时:顺序执行的那一段,就是 then 分支

继续往下看:

asm 复制代码
00CD150C  mov  dword ptr [ebp-4],64h
00CD1513  jmp  00CD151C

这里发生了两件非常"C 语言味"的事情。

1️⃣ result = 100

asm 复制代码
mov dword ptr [ebp-4],64h
  • [ebp-4]:栈上的一个局部变量

  • 64h:十六进制 0x64,也就是十进制 100

这行基本可以直接翻译成:

c 复制代码
result = 100;

2️⃣ 一个很关键的无条件跳转

asm 复制代码
jmp 00CD151C

这条 jmp 非常重要,我在看反汇编时一看到它,立刻就会想到 if / else

为什么?

因为它在做一件事:

then 分支执行完了,必须跳过 else,直接去公共结尾

如果没有这个 jmp,执行流就会"顺着掉进 else",那就不是 if/else 了。


三、被条件跳转"跳到"的地方,通常就是 else 分支

现在回头看最开始那条跳转:

asm 复制代码
jle 00CD1515

跳到哪?👇

asm 复制代码
00CD1515  mov  dword ptr [ebp-4],0FFFFFF9Ch

这里逻辑就非常清楚了:

  • num <= 0

  • CPU 直接跳到 00CD1515

  • 执行:

asm 复制代码
mov [ebp-4], 0FFFFFF9Ch

0xFFFFFF9C 是什么?

  • 32 位补码

  • 十进制就是 -100

所以这一整行,等价于:

c 复制代码
result = -100;

而且你会发现一个细节:

👉 else 分支这里没有再来一个 jmp

这是因为:

  • else 执行完

  • 顺序执行

  • 自然就会"掉到"后面的公共代码


四、then / else 最终都会到的地方:汇合点

再往下:

asm 复制代码
00CD151C  mov  eax,dword ptr [ebp-4]

这一行我一看就知道是:

c 复制代码
return result;

为什么?

  • eax:32 位下的返回值寄存器

  • [ebp-4]:刚才两个分支都在写的那个局部变量

不管你是从 then 跳过来的,还是从 else 顺序走过来的,最终都会走到这儿。

这就是 if / else 在控制流上的"汇合点"。


五、站在反汇编视角,总结 if / else 的"长相"

当我在逆向里判断一段代码是不是 if / else,基本就看下面这套组合拳:


✅ 1. cmp / test + jXX

  • 一定是某种条件判断

  • jXX 的目标地址,往往是 else 的入口


✅ 2. 条件不跳时,顺序执行的代码块

  • 这段代码就是 then 分支

  • 末尾通常会看到一个 jmp,用来跳过 else


✅ 3. 条件跳转的目标地址

  • 这块就是 else 分支

  • 执行完后通常不再跳,顺序流入公共代码


✅ 4. then / else 之后的公共位置

  • 所有路径都会汇聚到这里

  • 常见内容:return、后续逻辑、函数收尾


六、把你这段代码套进去,一切都严丝合缝

  • cmp + jle

    👉 判断 num > 0反向条件

  • 不跳 → result = 100jmp 跳到结尾

  • 跳 → result = -100

  • 最终在 00CD151C 汇合,返回结果

这是一个非常标准、非常干净if / else 汇编形态。


最后一句"逆向经验总结"

在反汇编里,只要你看到:
cmp/test + 条件跳转
紧跟一段代码 + 一个 jmp
条件跳转目标处是另一段代码,
最后两边汇合到同一个地址------
那基本可以 99% 确认:这是一个 if / else。

这不是"猜",而是控制流结构在汇编层面不得不长成的样子

如果你愿意,下一步我可以直接拿这段代码,画一张控制流图(CFG),你会发现它和 C 代码的 if / else 结构一模一样。

相关推荐
2401_858286115 个月前
CD64.【C++ Dev】多态(3): 反汇编剖析单继承下的虚函数表
开发语言·c++·算法·继承·面向对象·虚函数·反汇编
bcbobo21cn6 个月前
OllyDbg技巧学习
ollydbg·反汇编·二进制代码·函数体
2401_858286111 年前
动态内存管理练习题的反汇编代码分析(底层)
汇编·visualstudio·指针·vs·结构体·寄存器·反汇编
NovFif2 年前
【加密与解密(第四版)】第十五章笔记
开发语言·笔记·安全·编程语言·反汇编
NovFif2 年前
【加密与解密(第四版)】第六章笔记
开发语言·安全·系统安全·密码学·编程语言·反汇编
NovFif2 年前
【加密与解密(第四版)】第十七章笔记
windows·笔记·安全·系统安全·反汇编
剁椒排骨2 年前
BUUCTF靶场 [reverse]easyre、reverse1、reverse2
网络安全·数据分析·ida·逆向·ctf·reverse·反汇编