逆向知识第十讲,循环在汇编中的表现形式,以及代码还原

        逆向知识第十讲,循环在汇编中的表现形式,以及代码还原

一丶do While在汇编中的表现形式

1.1高级代码:

  

#include "stdafx.h"int main(int argc, char* argv[])
{int nSum = 0;int i = 0;do {nSum = nSum + i;} while (i <=100);return 0;
}

高级代码很简单,只是一个简单的求1~100的累加

1.2 Debug版本下的汇编表现形式

代码定式很简单

ADDR

  .....do While逻辑代码块

  xxxx 条件

  JXX  Addr

注意,在 do while中, 汇编代码的语义和高级代码语义是一样的.

比如我们以前的if   jle的时候(也就是小于等于) 我们的if则会写成  > (jg)也就是反向还原,而循环地址向上增量的条件不用取反

代码还原:

  do

    int nVar4 = nvar4 + nvar8;

  while(nVar8 <= 100)  注意条件,jle就是jle

还需要注意的是,地址是低地址,也就是跳转是往上跳转的

 

1.3 Release版本下的优化

高级代码:

  

int main(int argc, char* argv[])
{int nSum = 0;int i = 0;do {nSum = nSum + i;i++;} while (i <= argc);printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");return argc;
}

Release版本下的汇编代码:

  

代码也是最精简的了.和Debug一样,只不过优化为寄存器使用了.效率更快.

 

二丶while 循环在汇编中的表达形式

2.1高级代码:

#include "stdafx.h"int main(int argc, char* argv[])
{int nSum = 0;int i = 0;while(i <= 100) {printf("%d",nSum);nSum = nSum + i;}return argc;
}

2.2 Debug版本下的汇编表达形式

请注意,while循环回合if else的汇编代码类似

但是又有质的不同,在if else中, else语句块,其JMP跳转的地址是往增量地址跳转的,而在while中其跳转的地址是往减量地址跳转的

汇编代码定式:

LowAddr

    jxxx  HighAddr

    ....... while语句块代码

    JMP  LowAddr

HighAddr

可以看出,while循环有两个跳转

上下界的分别

jg  highaddr  找到while循环的下界

jmp  lowaddr 找到while循环的上界

注意,这里的定式我并没有写条件,因为条件只要会影响标志位即可,有可能不是cmp,反正能影响标志位的即可.

代码还原:

  while(nvar8 <= 100)  (语义相反,只有do while的语义按正常还原 jg(高于),相反则是小于等于)

  {

    printf("%d",nvar4);

    nvar4 = nvar4 + nvar8;

  }

PS: 在第一个跳转之前的所有代码,都作为while循环中的条件

 

三丶for循环在汇编中的表达形式

3.1高级代码:

int main(int argc, char* argv[])
{int nSum = 0;int i = 0;for(i = 0; i < 100;i++) {printf("%d",nSum);nSum = nSum + i;}return argc;
}

 

3.2Debug下的汇编表现形式

 

  

 

 for循环因为有了 步长的概念,所以Debug下的代码可能有点难看懂

说下代码定式把

  JMP  forCMPaddr  跳转到代码比较

FOR_STEMAddr

    for_Step    其代码是步长代码 (i++ j++)

forCMPaddr

  for_cmp     代码比较

  jxxx  forEndAddr  和while循环类似,跳转到结尾,条件不成立则退出,看此跳转则找到for循环的下界

  .....循环体

   JMP FOR_STEMADDR 执行完循环体之后,执行步长代码.

FOR_ENDADDR

修改为代码定式模样

 

 代码还原:

第一步: JMP FOR_CMP 所以找到for循环的比较代码位置

第二步: 找到jxx For_end 找到for循环的下界.则当前位置是代码的上界

第三步: jmp FOR_STEP 找到for循环的步长部分

for(nVar8 = 0; nVar8 < 100; nVar8++)

{

  printf("%d",nVar4);

  nVar4 = nVar4 +nVar8;

}

还原for的时候,主要是找到 比较部分,代码步长部分.以及循环体部分.

 

          浅谈Release版本下的循环

上面版本都是Debug版本下的表达形式,但是Release版本下则会优化

主要从几方面来讲解

1.减少跳转的优化方式

2.常量传播的优化方式

3.代码外提的优化方式

4.强度削弱的优化方式

 

一丶While在汇编中的Release的优化

因为dowhile是最优化的方式了,所以没有更好的优化方式了

1.1 while循环下的减少跳转的优化方式

 首先说下为什么减少跳转.

我们知道,do while就一个跳转,而while在Debug版本下是两个跳转,for循环在Debug版本下是3个跳转

那么如果减少了跳转,那么则会大大的增加效率.

1.1.2高级代码:

  

#include "stdafx.h"int main(int argc, char* argv[])
{int nSum = 0;int i = 0;while(i <= argc) {nSum = nSum + i;i++;} printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");printf("HelloWorld");return argc;
}

1.1.3 Release版本下的代码

看到这个汇编代码,我们发现jl的时候,是和if相似的.

而 jle的时候,地址是减量跳转,则是do while的条件

那么此时我们可能会还原成 if里面包含do while

但其实,也是这样还原的.这样是为了减少跳转

说下为什么减少跳转

1.首先判断,如果不成立,则不执行循环语句块

2.当第一个条件成立,则循环语句块,此时我知道你的条件是成立的,所以我只需要变为do while去循环即可.

这样就减少跳转了,比如我们的while循环20000次,那么跳转就要 *2,那么此时变成if 包含do while的时候

那么此时跳转就是 200001次,大大的优化了效率

还原代码:

if(argc >= 0)

{

  do

    ecx = ecx + eax;

    eax ++;

  while(eax <= argc )

}

识别此类的循环要注意

1.首先if中的条件和 do while中的条件有相关性

2.注意如果是dowhile那么其地址跳转是往减量跳转.

当然如果你喜欢还原为while那么也是可以了

while (eax <= argc)

{

  ecx = ecx + eax;

  eax ++;

}

第一种还原方式,如果条件有相关性,则还原出的汇编代码是和这个的二进制代码是一摸一样的.2.

 1.2 常量传播下的优化方式

在常量传播下,则直接变成了do while了.

看下高级代码:

int nSum = 0;int i = 0;while(i < 100){nSum = nSum + i;i++;}

常量传播后,则i变成了常量.所以直接变成do while即可.

Release汇编

 

1.3代码外提优化

高级代码:

int nSum = 0;int i = 0;while(i < argc /7){nSum = nSum + i;i++;}

其中 argc/7并没有在循环体中使用所以可以单独提取出来.

int temp = argc / 7;

while(i < temp)...

Release版本下的汇编代码:

上面则是代码外提的情况,此时还原代码也可以还原为 if 包含do while的形式

PS: 代码外提不支持函数

比如 

  for(i = 0; i < strlen("hello");i++) ... 其中 strlen是函数,所以不会代码外提

二丶减少跳转优化(For循环)

for循环在Debug版本下有三层跳转.那么减少跳转之后,则和上方while一样,也变为if包含 do While了.

PS: 注意,在常量传播下,所有的循环都变成了do while类型去执行循环了

PS: 注意,代码外提的情况下,所有循环都变成 if 加 do while的形式,代码放到外面执行了.

2.1高级代码:

 int nSum = 0;int i = 0;for (i = 0; i < argc; i++){nSum = nSum + i;i++;}

Release版本下的汇编

 

其也变成了if 包含do while循环的形式

还原代码同上

.

             循环中的Break和Continue的区别

循环中有continue和break

其中continue是跳过当前循环进行下一次循环.

break是跳出循环体

所以我们知道了,break会跳出循环.而continue不会跳出循环.\

一丶观看For循环的Debug版本.和Releas版本,观察continue和break的区别.

1.1高级代码

 int nSum = 0;int i = 0;for ( i = 0; i < argc ;i++){nSum = nSum + i;if(argc == 0){break;}else if(argc == 1){continue;}i++;}

1.2Debug汇编break和Continue的表达形式.

break执行会跳出循环体,而continue则会跳转到补偿代码执行

1.3Release版本下的汇编

也可以看出,break会跳出循环,而continue则不会跳出循环

总结:

1. do while总结

  Debug版本下

  1.do while有一次跳转,其中跳转的代码是往减量地址跳转(低地址)

  2.还原心得,因为其地址往减量跳转,所以汇编语义与高级语言语义一样,正常代码还原

  Release版本下

  1.常量传播下,直接就是do while了,和Debug版本下一样,一次跳转,还原方式正常跳转

  

 2. While循环总结

  Debug版本下

  1.有两次跳转,代码特别像 if else,但是又有质的不同,其中第一次跳转其地址是往增量跳转,第二次跳转其地址是往减量地址跳转(if else则都是往增量地址跳转)

  2.还原心得,第一次跳转之前的代码都作为while循环中的条件,其条件是反向还原,语义相反.第一次跳转可以找到while的下界,其当前位置则是while的上界.

    Release版本下

  1.常量传播的优化方式下,其代码会变成do while执行

  2.代码外提的情况下,其代码会变成if 包含 do while执行,其中代码的条件外提.注意,函数不可以作为代码外提

  3.还原心得: 如果是 if包含do while的形式,则判断两个条件是否有相关性.如果有相关性则可以还原成while或者自己喜好的 if +do while的形式.

  4.第一次跳转是相反语义,第二次跳转是正常语义.

3.for循环总结

   Debug版本下

    1.for循环因为有步长的问题,所以多一次跳转. 其中 第一步跳转到 条件位置处,第二此跳转则判断条件是否成立,不成立则退出,此时找到for的下界,当前位置可以当做if的上界.

     条件成立之后代码继续执行,则此时又来了一次跳转,此跳转跳转到步长执行代码

   Release版本下

  1.常量传播方式下 代码变为do while执行

  2.代码外提情况下,代码变成了 if + do while的形式 

转载于:https://www.cnblogs.com/iBinary/p/7869304.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467288.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

做技术知道了哪些事情代表自己成熟了?

如果技术圈是一个江湖&#xff0c;每个人初入江湖的时候都懵懵懂懂的&#xff0c;从懵懂到老练&#xff0c;从老练到老油条&#xff0c;这个是一个过程&#xff0c;过程中总是有一些比较有用的观点&#xff0c;这些观点&#xff0c;就表示你从小白上升到老白的过渡。这些观点&a…

数据结构复习笔记(2)

1&#xff0c; 若入栈的元素为n,则可得到的输出序列数量为 (2n)!/(n1)(n!)(n!)。2&#xff0c; 用两个长度相同的栈S1,S2构造一个队列。在S1中进行入队操作&#xff0c;S2中进行出队操作 &#xff0c;判断队列空的条件是&#xff0c;S1和S2同时为空&#xff0c;判断队列满的条…

用于MCU,基于FreeRTOS的micro(轻量级)ROS

编辑整理&#xff1a;strongerHuang作者&#xff1a;Francesca Finocchiaro关注我的读者中应该有部分是做ROS相关的工作&#xff0c;今天就来分享一个基于FreeRTOS的micro&#xff08;微型&#xff09;ROS。一、关于ROSROS&#xff1a;Robot Operating System,&#xff0c;即机…

【干货】同步与互斥的失败例子

韦东山老师最新录制的驱动大全之<<同步与互斥>>收费视频已经在淘宝上架销售 &#xff0c;一共7节&#xff0c;良心价29元&#xff0c;同时已经同步到CSDN , 51CTO , 电子发烧友&#xff0c;腾讯课堂等平台。本文是其中一节《同步与互斥的失败例子》视频配套文档&am…

TCP三次握手

以下是我做的实验 &#xff0c;180.97.33.108 是百度 以下是我自己画的图 转载于:https://www.cnblogs.com/heben/p/7879439.html

Linux中断子系统-通用框架处理

背景Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio1. 概述《Linux中断子系统&#xff08;一&#xff09;-中断控制器及驱动分析》讲到了底层硬件GIC驱动&#xff0c;以及Arch-Specif…

接口测试工具-fiddler的运用

本篇主要介绍一下fiddler的基本运用&#xff0c;包括查看接口请求方式&#xff0c;状态响应码&#xff0c;如何进行接口测试等 一&#xff0e;Fiddler的优点 独立的可以直接抓http请求小巧、功能完善快捷、启动就行代理方便二&#xff0e;什么是Fiddler Fiddler是一个http协议调…

微电子科学与工程要学计算机吗,微电子科学与工程专业就业前景如何 有前途吗...

微电子科学与工程专业就业前景如何&#xff1f;有前途吗&#xff1f;下面小编为大家整理了相关内容&#xff0c;以供参考&#xff0c;一起来看看吧&#xff01;微电子科学与工程专业就业前景微电子科学与工程专业近年来也逐渐热火起来了&#xff0c;竞争力也很大。微电子专业一…

我的丈母娘

2020年9月17日12点46分&#xff0c;刚进入新居我终于还是要写这篇文章了&#xff0c;想了很久&#xff0c;我觉得写一篇文章来记录下我的丈母娘。前段时间&#xff0c;小云妈妈骑车不小心把鼻子给摔破了&#xff0c;很严重&#xff0c;二哥马上回家带老人到医院检查并做了手术。…

OpenGL程序运行提示“glut32.dll丢失问题”

调试环境&#xff1a; Win10 (x64) &#xff0c;VS2015 解决方案 &#xff08;1&#xff09;将gult32.dll&#xff0c;glut.dll复制到C:\WINDOWS\SysWOW64 (如果是32位操作系统&#xff0c;则是WINDOWS\system32这个文件下) &#xff08;2&#xff09;将GL文件夹的路径添加到vs…

华为突然宣布,对物联网下手了!

5G时代到来物联网技术的应用离我们越来越近智慧交通、智能家庭、智慧园区越来越多的融入到我们的生活当中但国内物联网人才短缺每年人才缺口达百万之多作为5G技术的先锋华为云特别推出【IoT物联网开发全栈成长计划】三大阶段&#xff0c;从学习到实践全流程提升物联网开发技能还…

Linux内核品读 /基础组件/ 模块机制快速入门

哈喽&#xff0c;我是杰克吴&#xff0c;继续记录我的学习心得。一、关于兴趣的几点思考1. 享受不是兴趣&#xff0c;愿意付出才是&#xff1a;兴趣很容易跟享受混淆。享受是被动的&#xff0c;无需付出&#xff1b;而兴趣则要求你甘愿为了这件事情付出努力。2.任何事情&#x…

台式计算机时间不准,每天开机电脑时间都不正确怎么办?试试这个办法!

原标题&#xff1a;每天开机电脑时间都不正确怎么办&#xff1f;试试这个办法&#xff01;上面电脑运用时间长了&#xff0c;经常会出现开机提示时间不正确&#xff0c;在系统上设置好时间后&#xff0c;第二天开机电脑时间还不正确&#xff0c;是什么原因呢&#xff1f;无论是…

c语言从1打印到100再打印到1该如何编写?

我觉得这是一个送分题&#xff0c;奈何知乎人才太多了&#xff0c;给出了各种古怪的写法&#xff0c;如果是做项目的话&#xff0c;我比骄建议一些正常的写法&#xff0c;就是大家都能看得懂的&#xff0c;不要搞什么花里胡哨&#xff0c;不过你要是交流的话&#xff0c;既然是…

有人知道 I3C 吗?

我们知道I2C、SPI、UART、但是应该很少有人知道I3C&#xff0c;不过它确实是存在的。在完善的I2C接口标准之后&#xff0c;I3C即将进入嵌入式市场。I3C标准由MIPI联盟开发&#xff0c;现已扩展到更广泛的市场&#xff0c;该标准将I2C&#xff0c;UART和SPI组合为10Mbit / s&…

清华北大计算机考研报录比,2020年考研,清华北大报考人数对比,占考研总人数14%...

原标题&#xff1a;2020年考研&#xff0c;清华北大报考人数对比&#xff0c;占考研总人数14%2020年考研341万人同进考场&#xff0c;考研报名人数超过300万人&#xff0c;创造历史新高。因此2020年考研被公认为考研难度最大的一年。341万考研人&#xff0c;有多少人报考清华北…

我同学

周六在朋友圈提到的&#xff0c;我有一个在三星工作、从事camera方向研究的同学&#xff0c;他在去三星之前已经做了很多年camera了&#xff0c;之前在知识星球也给大家推荐了他的技术公众号&#xff0c;对喜欢或者从事camera研究的会非常有帮助&#xff0c;建议大家关注一下。…

Uva 201 Squares (暴力 + 枚举)

【题意】 给出 n*n 的 点 H 横向 V 纵向 &#xff08;注意&#xff09; V 想 I,j 相反 问 边 为1 &#xff0c;2 &#xff0c; 3 。。。。 n 的 正方向有几个 【思路】 n 很小 直接暴力 枚举 枚举 两个点&#xff0c; 看看 从 左上角 到右下角 &#xff08;变成为 s的…

自己都不觉得自己值钱,别人怎么觉得你值钱?

今天跟一个同学聊天&#xff0c;他最近正在找工作&#xff0c;找了一家外包企业拿到offer&#xff0c;对方开了薪资&#xff0c;他问我「发哥&#xff0c;这个薪资没有问题吧&#xff1f;」。薪资这个问题&#xff0c;我之前已经给出过建议&#xff0c;新企业的薪资最好能能让你…

ASP.NET AJAX入门系列(10):Timer控件简单使用

本文主要通过一个简单示例&#xff0c;让Web页面在一定的时间间隔内局部刷新&#xff0c;来学习一下ASP.NET AJAX中的服务端Timer控件的简单使用。主要内容Timer控件的简单使用1&#xff0e;添加新页面并切换到设计视图。2&#xff0e;如果页面没有包含ScriptManager控件&#…