首页 > 其他分享 >[1] 以逆向的角度来看流程控制语句——if

[1] 以逆向的角度来看流程控制语句——if

时间:2023-02-03 02:23:00浏览次数:45  
标签:语句 逆向 JMP 流程 else 指令 跳转 代码

[1] 以逆向的角度来看流程控制语句——if

1. if语句(单分支)

​ if语句转换的条件跳转指令与if语句的判断结果是相反的, 因为C语言是根据代码行的位置决定编译后二进制代码地址高低的,即低行数对应低地址,高行数对应高地址

​ 汇编标识:

00401003  cmp     dword ptr [ebp+8], 0
00401007  jnz     short loc_401016             ;如果argc!=0,则跳转到if结束块代码
{
00401009  push    offset aArgc0
0040100E  call    printf
00401013  add     esp, 4                       ;if语句块代码
}
00401016 loc_401016:
00401016  xor     eax, eax                     ;if结束块代码

​ 逆向总结:

执行影响标志位指令
JXX向下跳转到if结束代码块
{
if语句块代码
...
语句块结束无JMP
}
if结束代码块

​ 以上指令序列即可推断为由if语句组成的单分支结构

2. if…else…语句

Debug 汇编标识:

00401003  cmp     dword ptr [ebp+8], 0
00401007  jnz     short loc_401018            ;如果argc!=0,则跳转到else语句块代码
{
00401009  push    offset aArgc0
0040100E  call    sub_401070
00401013  add     esp, 4                      ;if语句块代码 
}
00401016  jmp     short loc_401025            ;跳转到if_else结束代码块
{
00401018 loc_401018:
00401018  push    offset aArgc0_0
0040101D  call    sub_401070
00401022  add     esp, 4                      ;else语句块代码
}
00401025 loc_401025:                          ;if_else结束代码块

逆向总结:

执行影响标志位指令
JXX向下跳转到else语句块代码
{
if语句块代码
...
JMP向下跳转到if_else结束代码块
}
{
else语句块代码
...
语句块结束无JMP
}
if_else结束代码块

​ 先考察两个跳转指令,当第一个条件跳转指令跳转到地址ELSE_BEGIN处之前有JMP指令,则视为由if…else…组合而成的双分支结构。根据这两个跳转指令可以得到if和else语句块的代码边界。通过cmp与jxx可还原if的比较信息,jmp指令之后即为else块的开始。依此分析,即可逆向分析出if…else…组合的原型

Release 汇编标识:

执行影响标志位指令
JXX向下跳转到else语句块代码
{
if语句块代码
...
语句块结束无JMP
}
if_else结束代码块
{
else语句代码块
...
JMP向上跳转到if_else结束代码块
}

​ 对于GCC编译器的Release,进入if语句块不会产生跳转,进入else语句块则会产生两次跳转。gcc在编译时会判断if和else的语句块的命中率,将命中率高的语句块代码调整到if语句块

3. 用if构成的多分支流程

Debug 汇编标识:

00401003  cmp     dword ptr [ebp+8], 0
00401007  jle     short loc_401018            ;如果argc<=0,则跳转到else_if语句块代码
{
00401009  push    offset aArgc0
0040100E  call    sub_401080
00401013  add     esp, 4                      ;if语句块代码 
}
00401016  jmp     short loc_40103A            ;跳转到if_else_if结束代码块
{
00401018  cmp     dword ptr [ebp+8], 0
0040101C  jnz     short loc_40102D            ;如果argc!=0,则跳转到else语句块代码
0040101E  push    offset aArgc0_0
00401023  call    sub_401080
00401028  add     esp, 4                      ;else_if语句块代码
}
0040102B  jmp     short loc_40103A            ;跳转到 if_else_if结束代码块
{
0040102D  push    offset aArgc0_1
00401032  call    sub_401080
00401037  add     esp, 4                      ;else语句块代码
}
0040103A  xor     eax, eax                    ;if_else_if结束代码块

逆向总结:

执行影响标志位指令
JXX向下跳转到else_if语句块代码
{
if语句块代码
...
JMP向下跳转到if_else_if结束块代码
}
{
else_if语句块代码
执行影响标志位指令
JXX向下跳转到else语句块代码
...
JMP向下跳转到if_else_if结束块代码
}
{
else语句块代码
...
语句块结束无JMP
}
if_else_if结束块代码

​ 当每个条件跳转指令的跳转地址之前都紧跟JMP指令,并且它们跳转的地址值一样时,可视为一个多分支结构。JMP指令指明了多分支结构的末尾,配合比较判断指令与条件跳转指令,可还原出各分支语句块的组成

Release 汇编标识:

执行影响标志位指令
JXX向下跳转到else_if语句块代码
{
if语句块代码
...
语句块结束无JMP
}
if_else_if结束代码块
...
{
else_if语句代码块
执行影响标志位指令
JXX向下跳转到else语句块代码
...
JMP向上跳转到if_else_if结束代码块
}
{
else语句块代码
...
JMP向上跳转到if_else_if结束块代码
}

逆向总结:

​ 对于GCC编译器的Release,进入if语句块不会产生跳转,进入else语句块则会产生两次跳转。gcc在编译时会判断if和else的语句块的命中率,将命中率高的语句块代码调整到if语句块

​ 由于编译器可以在编译期间对代码进行优化,当代码中的分支结构形成永远不可抵达的分支语句块时,它永远不会被执行,可以被优化掉而不参与编译处理

标签:语句,逆向,JMP,流程,else,指令,跳转,代码
From: https://www.cnblogs.com/XiuzhuKirakira/p/17087891.html

相关文章