ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

反汇编代码中的优化方式

2022-05-14 09:01:32  阅读:202  来源: 互联网

标签:常量 text 代码 eax 反汇编 printf push 优化


反汇编代码中的优化方式

一优化方式

优化方式分类

汇编中的加法、减法、乘法、除法 、 取模等等 都是优化方式。

优化方式的分类

  • 常量折叠
  • 常量传播
  • 变量去除
  • 归并优化
  • Cpu流水线优化
  • 数学变换
  • 不可达分支优化
  • 代码外提优化
    优化前提是在Release下且开启o2选项化速度的前提Debug版本也会优化更多的是方便程序员调试。所以在不影响调试的前提下才会进行优化。

常量折叠

int n = 0;
int m = 1;
printf("%d",7+8);
printf("%d",n+6);
printf("%d",n+m);

所谓常量折叠就是在编译前所遇到的常量。是可以就进行计算的。那么就会优化为一个常量值。

例如上面的7+8不会产生add指令 而是在程序编译后直接称为15(0XF)

printf("%d", 7 + 8);
00671873  push        0Fh  
00671875  push        offset string "%d" (0677B30h)  
0067187A  call        _printf (06710CDh)  
0067187F  add         esp,8  
printf("%d", n + 6);
00671882  mov         eax,dword ptr [n]  
00671885  add         eax,6  
00671888  push        eax  
00671889  push        offset string "%d" (0677B30h)  
0067188E  call        _printf (06710CDh)  
00671893  add         esp,8  
printf("%d", n + m);
00671896  mov         eax,dword ptr [n]  
00671899  add         eax,dword ptr [m]  
0067189C  push        eax  
0067189D  push        offset string "%d" (0677B30h)  
006718A2  call        _printf (06710CDh)  
006718A7  add         esp,8  

常量折叠含义就是常量会在编译器给你算出来。

常量传播

常量传播也叫常量扩散 指的就是 变量在写入或者读取的时候没有传递内存地址(&)也没有传指针或者引用来修改值得时候就会发生常量传播。
说白了就是 你没有修改我变量得代码。那么这个变量我就可以认为是常量。

int n = 0;
printf("%d",n+6);

那么进行常量传播之后,n因为没有对其修改。也没有对其进行传地址得操作。所以编译器就会把它变为常量。

int n = 0;
printf("%d",0+6);

而看到这里想大家明白了 又符号常量折叠所以代码继续变化。

int n = 0 ;
printf("%d",6);

这里进行了两次优化,一次是常量传播 一次是常量折叠

变量去除

变量去除是指你程序中定义了变量但是对其没有进行修改。然后进行常量传播,常量折叠一步一步给优化掉

int n = 0;
int m = 1;
printf("%d",n+m);

程序首先发现n m 两个变量相加。但是看了一下上面。发现没有对其进行修改。所以代码就会改变如下:

printf("%d",0+1);

而0+1符号常量折叠。所以最终代码就变为了

printf("%d",1);

对应反汇编

.text:00401018                 push    1
.text:0040101A                 push    offset aD       ; "%d"
.text:0040101F                 call    _printf

归并优化

归并优化。如果可以一起优化那么我就一起优化。
我们知道printf属性C调用约定。所以需要外平栈而且它是可变参。通过你push参数个数得不同。外平栈的大小也会相应改变
比如:

.text:00401040 sub_401040      proc near               ; CODE XREF: start-8D↓p
.text:00401040                 push    0Fh
.text:00401042                 push    offset unk_417A8C
.text:00401047                 call    sub_401010
.text:0040104C                 push    6
.text:0040104E                 push    offset unk_417A8C
.text:00401053                 call    sub_401010
.text:00401058                 push    1
.text:0040105A                 push    offset unk_417A8C
.text:0040105F                 call    sub_401010
.text:00401064                 add     esp, 18h
.text:00401067                 xor     eax, eax
.text:00401069                 retn
.text:00401069 sub_401040      endp

一个参数是4字节。所以累计总共push了6个参数4*6=24个字节。所以平栈也需要24个字节

Cpu流水线优化

Cpu流水线优化其实说白了就是打乱指令执行顺序。而不影响原有功能。这个在我们反汇编的时候需要注意。正常的汇编代码都是平平整整顺顺虚虚 让人一眼看的很舒服,而且反汇编编出高级代码也很快

这里以简单的汇编为例子 因为我们要很多代码才会遇到流水线优化。这里我模拟一下

正常的汇编代码指令顺序

xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov eax,1
add eax,2
mov ebx,eax
mov ecx,3

打乱的流水线

xor eax,eax
mov eax,1
xor ecx,ecx
add eax,2
mov ecx,3
xor ebx,ebx
mov ebx,eax

汇编代码就很简单。
我们着重看一下打乱的汇编
在没打乱之前代码平平整整。打乱之后发现很多汇编进行了穿插
比如

mov eax 1
xor ecx,ecx

在Cpu执行mov eax,1的时候。可以直接执行xor ecx,ecx这样的好处是下行汇编不依赖上一行汇编。之前的指令是下一行指令依赖上一行指令。那么Cpu如果在执行第二行的时候发现你依赖于上一行汇编那么就会等待。

mov eax,1
add eax,2

第一行执行了mov eax,1 那么第二行又使用了eax。那么第二行执行的时候就要等待第一行。
而打断的好处就是 我执行第一行的时候也可以执行第二行而且不会影响你的结果。也可以提升速度。

数学变换优化

数学变化优化:如果操作的数是无意义的。那么就会进行优化.

i=10;
b=11;
i=b+10;
i=b-0;
i=b*3;
i=i/3;

那么以上高级代码直接进行优化 优化为

i=b;

不可达分支优化

不可达分支则是分支永远都不会走。那么也不会产生汇编代码。也没有存在的意义

a=10;
if(a==10)
{
xxxx
}
else
{
xxxx
}

上面已经知道a就是个常量。值就是10.那么会走if块。而else永远不会走。那么就会将else优化掉。当然实际情况中代码肯定不多。不会像我一样简单的写一个a=10去判断。

代码外提优化

所谓代码外提是在循坏的时候进行优化。循环体内部没有产生修改此变量的代码。就会进行优化

int x = xxx;
while(x>y/3)
{
xxxx....
x--;
}

循环体内部并没有操作y/3所以这个值都会放到外面执行则会优化为

t= y/3
while(x>t)
{
xxxx....
x---;
}

而t变量很可能也会经过上面的几种优化变为寄存器变量

去掉优化方式

代码混淆与优化是对立的。所以学习一下优化方便我们更好的人肉优化混淆代码 .
上面所说。都是编译器已经识别到了你的程序没有传地址传地址等。所以我们想办法就是不让他优化。

标签:常量,text,代码,eax,反汇编,printf,push,优化
来源: https://www.cnblogs.com/doubleconquer/p/16262599.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有