[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