日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

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

發(fā)布時間:2023/12/20 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 逆向知识第十讲,循环在汇编中的表现形式,以及代码还原 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

        逆向知識第十講,循環(huán)在匯編中的表現(xiàn)形式,以及代碼還原

一丶do While在匯編中的表現(xiàn)形式

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版本下的匯編表現(xiàn)形式

代碼定式很簡單

ADDR

  .....do While邏輯代碼塊

  xxxx?條件

  JXX? Addr

注意,在?do?while中,?匯編代碼的語義和高級代碼語義是一樣的.

比如我們以前的if? ?jle的時候(也就是小于等于)?我們的if則會寫成? > (jg)也就是反向還原,而循環(huán)地址向上增量的條件不用取反

代碼還原:

  do

    int nVar4 = nvar4 + nvar8;

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

還需要注意的是,地址是低地址,也就是跳轉(zhuǎn)是往上跳轉(zhuǎn)的

?

1.3 Release版本下的優(yōu)化

高級代碼:

  

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一樣,只不過優(yōu)化為寄存器使用了.效率更快.

?

二丶while?循環(huán)在匯編中的表達形式

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循環(huán)回合if?else的匯編代碼類似

但是又有質(zhì)的不同,在if?else中,?else語句塊,其JMP跳轉(zhuǎn)的地址是往增量地址跳轉(zhuǎn)的,而在while中其跳轉(zhuǎn)的地址是往減量地址跳轉(zhuǎn)的

匯編代碼定式:

LowAddr

    jxxx? HighAddr

    .......?while語句塊代碼

    JMP? LowAddr

HighAddr

可以看出,while循環(huán)有兩個跳轉(zhuǎn)

上下界的分別

jg? highaddr? 找到while循環(huán)的下界

jmp? lowaddr?找到while循環(huán)的上界

注意,這里的定式我并沒有寫條件,因為條件只要會影響標(biāo)志位即可,有可能不是cmp,反正能影響標(biāo)志位的即可.

代碼還原:

  while(nvar8 <= 100)? (語義相反,只有do?while的語義按正常還原?jg(高于),相反則是小于等于)

  {

    printf("%d",nvar4);

    nvar4 = nvar4 + nvar8;

  }

PS:?在第一個跳轉(zhuǎn)之前的所有代碼,都作為while循環(huán)中的條件

?

三丶for循環(huán)在匯編中的表達形式

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下的匯編表現(xiàn)形式

?

  

?

?for循環(huán)因為有了?步長的概念,所以Debug下的代碼可能有點難看懂

說下代碼定式把

  JMP? forCMPaddr? 跳轉(zhuǎn)到代碼比較

FOR_STEMAddr

    for_Step   ?其代碼是步長代碼 (i++ j++)

forCMPaddr

  for_cmp  ? ?代碼比較

  jxxx? forEndAddr? 和while循環(huán)類似,跳轉(zhuǎn)到結(jié)尾,條件不成立則退出,看此跳轉(zhuǎn)則找到for循環(huán)的下界

  .....循環(huán)體

 ? JMP FOR_STEMADDR?執(zhí)行完循環(huán)體之后,執(zhí)行步長代碼.

FOR_ENDADDR

修改為代碼定式模樣

?

?代碼還原:

第一步: JMP FOR_CMP?所以找到for循環(huán)的比較代碼位置

第二步:?找到j(luò)xx For_end?找到for循環(huán)的下界.則當(dāng)前位置是代碼的上界

第三步:?jmp FOR_STEP?找到for循環(huán)的步長部分

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

{

  printf("%d",nVar4);

  nVar4 = nVar4 +nVar8;

}

還原for的時候,主要是找到?比較部分,代碼步長部分.以及循環(huán)體部分.

?

          淺談Release版本下的循環(huán)

上面版本都是Debug版本下的表達形式,但是Release版本下則會優(yōu)化

主要從幾方面來講解

1.減少跳轉(zhuǎn)的優(yōu)化方式

2.常量傳播的優(yōu)化方式

3.代碼外提的優(yōu)化方式

4.強度削弱的優(yōu)化方式

?

一丶While在匯編中的Release的優(yōu)化

因為dowhile是最優(yōu)化的方式了,所以沒有更好的優(yōu)化方式了

1.1?while循環(huán)下的減少跳轉(zhuǎn)的優(yōu)化方式

?首先說下為什么減少跳轉(zhuǎn).

我們知道,do?while就一個跳轉(zhuǎn),而while在Debug版本下是兩個跳轉(zhuǎn),for循環(huán)在Debug版本下是3個跳轉(zhuǎn)

那么如果減少了跳轉(zhuǎn),那么則會大大的增加效率.

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版本下的代碼

看到這個匯編代碼,我們發(fā)現(xiàn)jl的時候,是和if相似的.

而?jle的時候,地址是減量跳轉(zhuǎn),則是do?while的條件

那么此時我們可能會還原成?if里面包含do?while

但其實,也是這樣還原的.這樣是為了減少跳轉(zhuǎn)

說下為什么減少跳轉(zhuǎn)

1.首先判斷,如果不成立,則不執(zhí)行循環(huán)語句塊

2.當(dāng)?shù)谝粋€條件成立,則循環(huán)語句塊,此時我知道你的條件是成立的,所以我只需要變?yōu)閐o?while去循環(huán)即可.

這樣就減少跳轉(zhuǎn)了,比如我們的while循環(huán)20000次,那么跳轉(zhuǎn)就要 *2,那么此時變成if?包含do?while的時候

那么此時跳轉(zhuǎn)就是 200001次,大大的優(yōu)化了效率

還原代碼:

if(argc >= 0)

{

  do

    ecx = ecx + eax;

    eax ++;

  while(eax <= argc )

}

識別此類的循環(huán)要注意

1.首先if中的條件和?do?while中的條件有相關(guān)性

2.注意如果是dowhile那么其地址跳轉(zhuǎn)是往減量跳轉(zhuǎn).

當(dāng)然如果你喜歡還原為while那么也是可以了

while (eax <= argc)

{

  ecx = ecx + eax;

  eax ++;

}

第一種還原方式,如果條件有相關(guān)性,則還原出的匯編代碼是和這個的二進制代碼是一摸一樣的.2.

?1.2?常量傳播下的優(yōu)化方式

在常量傳播下,則直接變成了do?while了.

看下高級代碼:

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

常量傳播后,則i變成了常量.所以直接變成do?while即可.

Release匯編

?

1.3代碼外提優(yōu)化

高級代碼:

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

其中?argc/7并沒有在循環(huán)體中使用所以可以單獨提取出來.

int temp = argc / 7;

while(i < temp)...

Release版本下的匯編代碼:

上面則是代碼外提的情況,此時還原代碼也可以還原為?if?包含do?while的形式

PS:?代碼外提不支持函數(shù)

比如?

  for(i = 0; i < strlen("hello");i++) ...?其中?strlen是函數(shù),所以不會代碼外提

二丶減少跳轉(zhuǎn)優(yōu)化(For循環(huán))

for循環(huán)在Debug版本下有三層跳轉(zhuǎn).那么減少跳轉(zhuǎn)之后,則和上方while一樣,也變?yōu)閕f包含?do While了.

PS:?注意,在常量傳播下,所有的循環(huán)都變成了do?while類型去執(zhí)行循環(huán)了

PS:?注意,代碼外提的情況下,所有循環(huán)都變成?if?加?do?while的形式,代碼放到外面執(zhí)行了.

2.1高級代碼:

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

Release版本下的匯編

?

其也變成了if?包含do?while循環(huán)的形式

還原代碼同上

.

             循環(huán)中的Break和Continue的區(qū)別

循環(huán)中有continue和break

其中continue是跳過當(dāng)前循環(huán)進行下一次循環(huán).

break是跳出循環(huán)體

所以我們知道了,break會跳出循環(huán).而continue不會跳出循環(huán).\

一丶觀看For循環(huán)的Debug版本.和Releas版本,觀察continue和break的區(qū)別.

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執(zhí)行會跳出循環(huán)體,而continue則會跳轉(zhuǎn)到補償代碼執(zhí)行

1.3Release版本下的匯編

也可以看出,break會跳出循環(huán),而continue則不會跳出循環(huán)

總結(jié):

1. do while總結(jié)

  Debug版本下

  1.do while有一次跳轉(zhuǎn),其中跳轉(zhuǎn)的代碼是往減量地址跳轉(zhuǎn)(低地址)

  2.還原心得,因為其地址往減量跳轉(zhuǎn),所以匯編語義與高級語言語義一樣,正常代碼還原

  Release版本下

  1.常量傳播下,直接就是do?while了,和Debug版本下一樣,一次跳轉(zhuǎn),還原方式正常跳轉(zhuǎn)

  

?2. While循環(huán)總結(jié)

  Debug版本下

  1.有兩次跳轉(zhuǎn),代碼特別像?if else,但是又有質(zhì)的不同,其中第一次跳轉(zhuǎn)其地址是往增量跳轉(zhuǎn),第二次跳轉(zhuǎn)其地址是往減量地址跳轉(zhuǎn)(if else則都是往增量地址跳轉(zhuǎn))

  2.還原心得,第一次跳轉(zhuǎn)之前的代碼都作為while循環(huán)中的條件,其條件是反向還原,語義相反.第一次跳轉(zhuǎn)可以找到while的下界,其當(dāng)前位置則是while的上界.

? ? Release版本下

  1.常量傳播的優(yōu)化方式下,其代碼會變成do?while執(zhí)行

  2.代碼外提的情況下,其代碼會變成if?包含?do?while執(zhí)行,其中代碼的條件外提.注意,函數(shù)不可以作為代碼外提

  3.還原心得:?如果是?if包含do?while的形式,則判斷兩個條件是否有相關(guān)性.如果有相關(guān)性則可以還原成while或者自己喜好的?if +do?while的形式.

  4.第一次跳轉(zhuǎn)是相反語義,第二次跳轉(zhuǎn)是正常語義.

3.for循環(huán)總結(jié)

   Debug版本下

  ? 1.for循環(huán)因為有步長的問題,所以多一次跳轉(zhuǎn).?其中?第一步跳轉(zhuǎn)到?條件位置處,第二此跳轉(zhuǎn)則判斷條件是否成立,不成立則退出,此時找到for的下界,當(dāng)前位置可以當(dāng)做if的上界.

  ? ?條件成立之后代碼繼續(xù)執(zhí)行,則此時又來了一次跳轉(zhuǎn),此跳轉(zhuǎn)跳轉(zhuǎn)到步長執(zhí)行代碼

   Release版本下

  1.常量傳播方式下?代碼變?yōu)閐o?while執(zhí)行

  2.代碼外提情況下,代碼變成了?if + do while的形式 

轉(zhuǎn)載于:https://www.cnblogs.com/iBinary/p/7869304.html

總結(jié)

以上是生活随笔為你收集整理的逆向知识第十讲,循环在汇编中的表现形式,以及代码还原的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。