C反彙編例項(詳細註解版)(三)

2021-05-23 17:07:45 字數 3789 閱讀 1051

上次我分析了一下,

debug

模式下反彙編後的演算法部分**,天才的您可能覺得不算糟,想再搞點花樣,那麼本文就能滿足你的需求。天書夜讀上其實還貼出來了

release

模式下的**,它經過

vc編譯器

o2的優化,我初次看到反彙編**時,還真汗了一把。不過定下心來細細品位還是可以看懂的,儘管正如原書所說,連語句的對應順序也已經不見了。。。

廢話不多說,先貼出**大夥「飽飽眼福」。。。

00401000 mov eax,dword ptr [esp+4]

00401004 mov edx,dword ptr [esp+0ch]

00401008 mov ecx,dword ptr [esp+8]

0040100c push ebx

0040100d push esi

0040100e add eax,4

00401011 push edi

00401012 add edx,8

00401015 mov esi,3

0040101a lea ebx,[ebx]

00401020 mov ebx,dword ptr [eax]

00401022 imul ebx,dword ptr [ecx+0ch]

00401026 mov edi,dword ptr [ecx+18h]

00401029 imul edi,dword ptr [eax+4]

0040102d add edi,ebx

0040102f mov ebx,dword ptr [eax-4]

00401032 imul ebx,dword ptr [ecx]

00401035 add edi,ebx

00401037 mov dword ptr [edx-8],edi

0040103a mov ebx,dword ptr [eax]

0040103c imul ebx,dword ptr [ecx+10h]

00401040 mov edi,dword ptr [ecx+1ch]

00401043 imul edi,dword ptr [eax+4]

00401047 add edi,ebx

00401049 mov ebx,dword ptr [eax-4]

0040104c imul ebx,dword ptr [ecx+4]

00401050 add edi,ebx

00401052 mov dword ptr [edx-4],edi

00401055 mov ebx,dword ptr [eax+4]

00401058 imul ebx,dword ptr [ecx+20h]

0040105c mov edi,dword ptr [ecx+14h]

0040105f imul edi,dword ptr [eax]

00401062 add edi,ebx

00401064 mov ebx,dword ptr [eax-4]

00401067 imul ebx,dword ptr [ecx+8]

0040106b add edi,ebx

0040106d mov dword ptr [edx],edi

0040106f add eax,0ch

00401072 add edx,0ch

00401075 dec esi

00401076 jne myfunction+20h (401020h)

00401078 pop edi

00401079 pop esi

0040107a xor eax,eax

0040107c pop ebx

**確實精簡了不少,也精簡地一點對應關係也找不到了。。。這份彙編**,比(二)中其實要完整,因為它把整個函式呼叫到返回的**都列出來了,儘管也早精簡得不是標準的函式彙編**了,由此可見

vc編譯器的優化能力之強令人嘆為觀止。。。

老規矩,對上述彙編**的部分內容先作一簡析。

第一.細心的讀者一定已經發現,(二)中的

(間接定址符)包含的都是活生生的變數名,而在

release

中已經變為暫存器的表示式,當然我們可以根據引數入棧的順序來推導出哪個是哪個,這會在後續有所說明。

第二.正常的函式呼叫過程開始都會先將

ebp入棧,而後將

ebp用作

esp的暫存暫存器,而在這裡,從頭至尾就沒有出現過

ebp,當然主要是因為

esp並沒有被函式用做特殊用途,再追溯根源一點,是因為迴圈變數

i被更高速的暫存器

esi所替代,而

j這個迴圈。。。很神奇的由於只有3次,居然被編譯器展開成三個等效計算過程給代替了。

第三.最後一點也不是很重要,就是暫存器壓棧的指令原本是放在最前的,現在又很神奇地被嵌在了資料計算語句之間。這點更加體現了經過優化的**比較不符合人的常識,但更契合高效能的需要。

現在我們從頭開始,一段段看: ;

隨著c, b, a

順序入棧,堆疊向位址減小的方向發展,故而可以容易推斷出

00401000 mov eax,dword ptr [esp+4]

; 對應a

00401004 mov edx,dword ptr [esp+0ch]

; 對應c

00401008 mov ecx,dword ptr [esp+8]

; 對應b

; 40100c, 40100d, 401011

三個指令是常規的暫存器儲存工作

0040100c push ebx

0040100d push esi ;

這裡給eax與edx分別加上乙個值的目的,後面會得知

0040100e add eax,4

00401011 push edi

00401012 add edx,8 ;

使用esi暫存器作為迴圈變數,提高執行速度

00401015 mov esi,3 ;

下面一行指令儘管看不出什麼用處,但我倒不是很贊同原書上的說法, ;

如果有哪位大俠知道,請告知下大家,謝謝

0040101a lea ebx,[ebx]

esi

迴圈體

; 可以看到,上面這個迴圈體每次處理的是a與c對應的一行資料,如上面的註解是針對第0 ;

行的情況,而下面兩個指令就是把a與c分別下移一行,即下次將處理a與c的第1行,只要 ;

把上面註解中c[0][x]改為c[1][x],a[0][y]改為a[1][y],依次類推……

0040106f add eax,0ch

00401072 add edx,0ch ;

迴圈變數esi減1,若還不為0,則迴圈未結束,跳轉後接著迴圈

00401075 dec esi

00401076 jne myfunction+20h (401020h) ;

函式結束時常規的暫存器恢復工作,依次恢復edi, esi, ebx,和儲存順序相反

00401078 pop edi

00401079 pop esi

0040107a xor eax,eax

; 返回值在

eax裡,異或運算,把

eax清零,即返回值是0

0040107c pop ebx

其實對c反彙編的技術還有很多,這裡只是舉個例子給大家起乙個拋磚引玉的作用,要完全領悟還得靠自己去學習去多多實踐。

本系列三篇文章就結束了,首先感謝《天書夜讀》的作者,另外如果由於我語文或技術水平有限導致理解有些困難的話,那我先說聲

sorry

C反彙編例項(詳細註解版)(三)

上次我分析了一下,debug 模式下反彙編後的演算法部分 天才的您可能覺得不算糟,想再搞點花樣,那麼本文就能滿足你的需求。天書夜讀上其實還貼出來了 release 模式下的 它經過 vc編譯器 o2的優化,我初次看到反彙編 時,還真汗了一把。不過定下心來細細品位還是可以看懂的,儘管正如原書所說,連語...

C反彙編例項(詳細註解版)(一)

呵,好久沒寫 csdn 文章了,來湊個熱鬧。最近我閱讀了楚狂人 wowocock 寫的 天書夜讀 試讀本,對 c反彙編感觸頗深,書中有一例演算法反彙編,其對彙編的閱讀確實富有挑戰,而該書中也未詳解,在此,我謹將此例詳細分析如下,幫助大家更好理解 c反彙編 若有任何錯誤,請大家批評指正!該例的要求是求...

C反彙編例項(詳細註解版)(二)

那麼有了上述三方面的基礎,我們就可以來逐一解讀那段 傳奇 的彙編 了。初始化i 00411a3e mov dword ptr i 0 跳轉至條件判斷 00411a45 jmp myfunction 30h 411a50h 迴圈表示式,對i每輪加1 00411a47 mov eax,dword ptr...