[轉載]花指令

[轉載]花指令

原始鏈接:http://blog.csdn.net/zran/archive/2006/03/19/628771.aspx
本文作者:sodme
本文出處:http://blog.csdn.net/sodme
聲明:本文可以不經作者同意任意轉載、複製、引用。但任何對本文的引用,均須註明本文的作者、出處以及本行聲明信息。

可能很多人都聽說過花指令,但限於平時的開發所限,可能較少接觸到。日前,跟同事討論了一些有關花指令的問題,現將自己的體會總結一下。

這篇文章將討論以下問題:

一、什麼是花指令?它的原理是什麼?
二、在什麼地方使用花指令?如何使用花指令?
三、如何識別花指令?如何去除花指令?
四、一些典型的花指令實例

什麼是花指令?當然不是"flower code",呵呵,實際上,把它按照“亂指令”來理解可能更貼切一些,它的真正英文名應該叫"thunkcode"吧(不確定,呵呵)。我們知道,彙編語言其實就是機器指令的符號化,從某種程度上看,它只是更容易理解一點的機器指令而已。每一條彙編語句,在彙編時,都會根據cpu特定的指令符號表將彙編指令翻譯成二進制代碼。而日常應用中,我們通過VC的IDE或其它如OD等反彙編、反編譯軟件也可以將一個二進制程序反彙編成彙編代碼。機器的一般格式爲:指令+數據。而反彙編的大致過程是:首先會確定指令開始的首地址,然後根據這個指令字判斷是哪個彙編語句,然後再將後面的數據反匯編出來。由此,我們可以看到,在這一步的反彙編過程中存在漏洞:如果有人故意將錯誤的機器指令放在了錯誤的位置,那反彙編時,就有可能連同後面的數據一起錯誤地反匯編出來,這樣,我們看到的就可能是一個錯誤的反彙編代碼。這就是“花指令”,簡而言之,花指令是利用了反彙編時單純根據機器指令字來決定反彙編結果的漏洞。

先舉個例子(記爲A代碼段):
   jz   label
   jnz  label
   db thunkcode
label:

以上是一個相當簡單的花指令塊,其中thunkcode是由應用者自己隨便寫的機器指令字,當然,你寫的這個機器指令字不能是單字節指令(比如nop, clr,等),否則,你的花指字就相當於白加了。那麼,你要如何來使用這段代碼呢?

假設我們待加密的代碼塊如下(記爲B代碼段):
   mov ax, 8
   xor ax, 77
   ...

我們假設這B代碼段是我們的加密算法所在的代碼段,現在我們想要對B代碼段進行保護,可以直接將A花指令塊加到mov指令之前,形如:
   jz   label
   jnz  label
   db thunkcode
label:
   mov ax, 8
   xor ax, 77
   ...

其中,對於thunkcode,在實際使用時,可以使用任何一個多字節指令的機器指令字來代替,這樣就會欺騙反彙編軟件將它連同後面的mov指令的前邊某一部分反彙編成一個多字節指令。這樣,我們的目的也就達到了。

由上可以看到,使用了花指令的地方,一般都會出現這樣的現象:一個跳轉指令,跳轉到了某條語句的中間位置,而不是這條語句的開始位置。每當出現這種情況時,我們就可以斷定,這裏出現了花指令。

顯然地,破解它的辦法,就是在那個跳轉到的目的地址之前將中間的代碼全部nop掉。

當然,爲了加強難度,我們可以將若干個花指令結合起來使用。比如:
   jz   label
   jnz  label
   db thunkcode
label:
   jz   label2
   jnz  label2
   db thunkcode
lable2
   mov ax, 8
   xor ax, 77
   ...

也當然,針對這種情況的破解只要一層層解開它即可:我們可以先破解到以label爲首字節的指令出現爲止,然後再根據新的結果,破解到以label2爲首字節的指令出現爲止,雖然這樣麻煩點,但還是不難的。

但是,如果把下面的這段代碼再同其它花指令結合起來使用,可能就更復雜了:
   call   label_1
   db      thunkcode
   jmp      label_2
   db      thunkcode
label_1: 
   pop      eax
   jmp      label_3
   db      thunkcode,thunkcode,thunkcode
label_3:  
   inc      eax
   jmp    label_4
   db      thunkcode,thunkcode,thunkcode
label_4:  
   jmp      eax
   db      thunkcode
label_2:  
   ....


這裏還有一段:
   call label_1
   db  thunkcode,thunkcode
   jmp  label_4
label_1:
   pop  eax
   jmp  label_2
   db  thunkcode,thunkcode
label_2:
   add  eax,2
   jmp  label_3
   db  thunkcode
label_3:
   push eax
   ret
   db  thunkcode
label_4: ....

爲了加強難度,儘可能地用call和push實現間接跳轉,當然,矛矛盾盾,只是時間長點而已,世上沒有絕對安全的系統。
<以上代碼來源於看雪的"軟件加密技術內幕"一書>
發佈了7 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章