[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语句块

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

[1] 以逆向的角度来看流程控制语句——if的更多相关文章

  1. JAVA 1.6 流程控制语句

    1. 条件运算符(三元表达式),其形式为:type d = a ? b : c; 具体化形式为:int d = 2 < 1 ? 3 : 4;2. 轻量级的文本编辑器:UltraEdit.Edit ...

  2. 二、JavaScript语言--JS基础--JavaScript进阶篇--流程控制语句

    1.if语句--做判断 if语句是基于条件成立才执行相应代码时使用的语句. 语法: if(条件) { 条件成立时执行代码} 注意:if小写,大写字母(IF)会出错! 假设你应聘web前端技术开发岗位, ...

  3. C#之流程控制语句

    通过一系列的学习,我们知道尽管计算机可以完成工作,但实质上这些工作都是按照我们事先编好的程序执行的,所以,程序是计算机的灵魂,计算机程序执行的控制流程由三种基本的控制结构控制,即顺序结构,选择结构,循 ...

  4. java-04流程控制语句

    这里先简单介绍几种流程控制语句 包括if/if-else.switch语句 1.三大流程控制结构 所谓流程控制,就是说要控制程序的执行方式,根据不同的情况执行不同的代码,从而得到不同情况下的不同结果. ...

  5. JavaScript的流程控制语句

    JS的核心ECMAScript规定的流程控制语句和其他的程序设计语言还是蛮相似的.我们选择一些实用的例子来看一下这些语句.顺序结构我们在这里就不再提到,直接说条件和循环以及其他语句.一.条件选择结构  ...

  6. JavaScript进阶 - 第4章 跟着我的节奏走(流程控制语句)

    第4章 跟着我的节奏走(流程控制语句) 4-1 做判断(if语句) if语句是基于条件成立才执行相应代码时使用的语句. 语法: if(条件) { 条件成立时执行代码} 注意:if小写,大写字母(IF) ...

  7. PHP流程控制语句(if,foreach,break......)

    背景:PHP程序中,必不可少的要用到流程控制语句.这次对于流程控制语句进行一些总结. 条件控制语句和循环控制语句是两种基本的语法结构,它们都是用来控制程序执行流程.也是构成程序的主要语法基础. 一.程 ...

  8. 流程控制语句反汇编(1)(Debug版)

    // 流程控制语句反汇编 //Author:乾卦 Date:2014-5-8 #include<stdio.h> int main() { ,b=; if(a>b) { a=b; } ...

  9. MySQL全面瓦解20:可编程性之流程控制语句

    背景 说到流程控制语句,我们在程序语法中用的比较多,比如C#的if..else...,while...,?: 等.同样的,在MySQL中,也有一些流程控制的语法,方便我们在写函数.存储过程的时候对逻辑 ...

  10. 『无为则无心』Python基础 — 13、Python流程控制语句(条件语句)

    目录 1.流程控制基本概念 2.选择结构(条件语句) (1)条件语句概念 (2)if语句语法 (3)if...else...语句 (4)多重判断 (5)if语句嵌套 3.应用:猜拳游戏 4.三元运算符 ...

随机推荐

  1. Axure 单键快捷键

    如果怕误操作,可以把它关闭

  2. SpringBoot 接口并发限制(Semaphore)

    可以使用 JMeter 辅助测试 https://blog.csdn.net/weixin_45014379/article/details/124190381 @RestController @Re ...

  3. 以 Golang 为例详解 AST 抽象语法树

    前言 各位同行有没有想过一件事,一个程序文件,比如 hello.go 是如何被编译器理解的,平常在编写程序时,IDE 又是如何提供代码提示的.在这奥妙无穷的背后, AST(Abstract Synta ...

  4. 【白话科普】聊聊 DNS 的那些小知识

    你是否在上网时,遇到过这样的情况:QQ 能正常发送消息,但是网页却打不开,查看网络连接又正常显示.面对这种情况很多小伙伴都感到有些无措.那究竟要怎么处理,这究竟是怎么回事呢? 上网查询得知,一般情况下 ...

  5. CVPR2022 前沿研究成果解读:基于生成对抗网络的深度感知人脸重演算法

    凭借在人脸生成领域的扎实积累和前沿创新,阿里云视频云与香港科技大学合作的最新研究成果<基于生成对抗网络的深度感知人脸重演算法 >(Depth-Aware Generative Advers ...

  6. 如何写个死循环,既不独占线程,又不阻塞UI线程?

    如果死循环独占线程,500个死循环要占用500个线程,如果死循环不独占线程,500个死循环,用200个线程也行,用20个线程也行,无非是执行的慢点 这样可以把同步操作改写为异步,并且节省线程占用 问个 ...

  7. CMake 禁用 MSVC 编译警告 C4819

    warning C4819:该文件包含不能在当前代码页(936)中表示的字符.请将该文件保存为 Unicode 格式以防止数据丢失 if (win32) add_complie_options(/W4 ...

  8. Hottest 30 of codeforce

    1. 4A.Watermelon 题目链接:https // s.com/problemset/problem/4/A 题意:两人分瓜,但每一部分都得是偶数 分析:直接 对2取余,且 w != 2 # ...

  9. springboot 实现接收前端发来的图片和视频以及在页面上展示图片和视频

    springboot 实现接收前端发来的图片和视频以及在页面上展示图片和视频 一.效果: 1.上传图片 2.显示上传的图片 3.上传的视频 4.显示上传的视频 二.代码 没依赖特殊的包,引入sprin ...

  10. 二、java发送https的各类请求

    导航 一.java发送http的各类请求 二.java发送https的各类请求 java开发中需要调用其他服务的对外提供的https请求,上一篇写的是调用http,处理方式不太一样,可以参考如下代码: ...