[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. 火山引擎 DataTester 推出可视化数据集成方案

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着数字化的长期演进,企业中往往存在多个运行在不同平台的数字系统,这些数据源彼此独立,数据跨系统间的交流.共享和融 ...

  2. AI Studio 基本操作

    https://aistudio.baidu.com/aistudio/projectdetail/6182202 项目启停 执行和调试 添加代码或文件 运行代码 %cd /home/aistudio ...

  3. 创建一个简单的Docker镜像

    1. 创建 Dockerfile 文件.index.html测试页面 [root@localhost docker]# vi Dockerfile FROM nginx:1.17.6 #基于 ngin ...

  4. ThreadPoolExecutor 使用

    ThreadPoolExecutor 介绍 简写: package com.vipsoft.Thread; import java.util.concurrent.*; import java.uti ...

  5. Intellij 查找排除JAR包的依赖关系(Maven Helper)

    Intellij 查找排除JAR包的依赖关系(Maven Helper) 安装插件 Windows 类似

  6. 别再问我 2050 可以干什么,Make a Movie in a Day!

    2050 的每个年青人都是新物种.越是不可能见面的人见了面,就越会有奇迹发生,2050 努力让年青人见上另一位年青人,激发新的创造力.一起来 2050 看看? 2050 是什么? 2050 大会是由阿 ...

  7. UVA - 10391:Compound Words (字符串水题)

    题目大意 给定若干单词,按字典序输出由两个单词拼接而成的单词 思路分析 用set存储所有单词,枚举每个单词word,遍历word的所有左右子串组合情况,若左右子串均在set中,说明符合题意.时间复杂度 ...

  8. 1 分钟在 Serverless 上部署现代化 Deno Web 应用

    作者 | 连喆人(掌上乾坤公司) 本文选自 "Serverless 函数计算征集令" 征文 利用 Serverless 的水平扩展与按量付费优势, 结合自定义运行时, 实现 Web ...

  9. java进阶(7)--Object类-toString()/equals()/finalize()/hashCode()

    一.object类介绍 object类这个老祖宗中的方法,所有子类通用,直接或间接继承. 学习常用方法即可 列表 prtected object clone()             //对象克隆 ...

  10. Liunx常用操作(十)-VI编辑器-命令模式命令

    vI编辑器三种模式 分别为命令模式.输入模式.末行模式.