如果想成為一名真正的資安防護專業人員或電腦鑑識調查員,那麼了解軟體在原始碼的工作原理是必然不可少的。您需要能夠分析漏洞如何被利用的原始碼,或者分析惡意軟體原始程序才能真正理解它。反組譯是將二進位可執行檔轉換為更易於人類理解的高階語言的過程。通常這意味著將可執行程式轉換組合語言,再反編譯成為 C或其他高階語言的原始碼。
執行檔是程式設計者的最終產出,程式設計者會透過對功能及須求的理解,轉成自己熟悉的程式語言,再透過 Compiler 編譯程式碼,最終變成執行檔。
上述的流程反過來,就是逆向工程,由一個執行檔,透過 Disassembler、Decompiler 最後回復成一個可讀的原始碼。
當我們要解析一些駭客程式或病毒程式的原理或特徵,就須要透過逆向工程,還原其程式流程原理。整個過程像是名偵探柯南或是福爾摩斯,在命案現場中透過僅有的線索並仔細觀察,抽絲剝繭地逐漸還原真相。例如: 分析病毒,可透過程式碼以及一些文字,推測病毒有哪些行為特徵,或對特定字串的文件檔進行感染、特定字串的網址進行某種文件的下載等等。
我們用一個簡單的例子,說明如何進行逆向工程。
編寫一個簡單的程式
下載編譯器 & 編寫一小段程式
我們可以去下戴一個 FREE C++ 編譯器 Dec-C++。
https://sourceforge.net/projects/orwelldevcpp/
首先建立一個可以在Cmd 下執行的程式
這程式很簡單,要求使用者輸入一個密碼 ( Key ),若密碼等於 10,則印出"key OK"。
#include <stdio.h> #include <string.h>
int main(int argc,char** argv) { int Key;
scanf( "%d",&Key); if ( Key == 10 ) { printf("key OK\n"); } return 0; } |
編譯成功在程式碼的目錄一下看到 Test1.Exe;並在 DOS 下驗証,如果密碼對了,會印出’key OK’。
使用 MadEdit分析一下 EXE 的組成
我們可以進一步使用如 MadEdit 等工具編輯2 進位檔。檢視 Test1.Exe 檔案的實際內容,前 2 位元是 ‘MZ’表示這是一個 PE 檔。
找出字串’key OK’在檔案中的位置,可視為進行逆向工程的定位點。如果一個副程式參考了這個位置,可以判斷,這可能是一個輸出用的副程式,而且已經通過密碼驗証。
在這個副程式再往上一些位置,就可以找到判斷密碼正確與否的程式位置。
反組譯 ( Deassambler )
MadEdit 觀看Test1.EXE ,只能對這個檔案帶來直覺的概觀,要進一步分析 Test1.Exe 還須要強大的工具才行。推薦公認最好的 IDA Pro 這個工具。IDA Pro從程式碼的反組譯開始,然後分析程式流程、變數和函數呼叫。 然而IDA Pro 需要付費,加上必須要有足夠的程式基礎門檻,對初學者來說不容易駕馭。
反組譯的分析
使用 IDA Pro 64 開啟 Test1.Exe 後,會自動分析其內容,並進行反組譯,可以用 2 種方式表示反組譯的結果,一個是結構圖,一個是程式列表。
結構圖 |
程式列表 |
![]() |
|
反編譯 ( Decompiler )
IDA Pro 可以進一步做簡單的分析,並嘗試著將組合語言進一步轉成 C 碼在 IDA Pro 中,我們可以使用 F5,試試反編譯的結果,如下。
下面是原始碼和 IDA Pro 的虛擬碼比較。
原始碼 |
IDA Pro 的虛擬碼 |
#include <stdio.h> #include <string.h>
int main(int argc,char** argv) { int Key;
scanf( "%d",&Key); if ( Key == 10 ) { printf("key OK\n"); } return 0; } |
int __cdecl main(int argc,const char **argv,const char **envp) { int Key; // [rsp+2Ch] [rbp-4h]
_main(); scanf("%d",&Key); if ( Key == 10 ) puts("key OK"); return 0; } |
IDA Pro 的反編譯
IDA Pro 可以產生虛擬碼,但大多情況下無法拿來直接重新編譯,雖然虛擬碼不是真實程式碼,但可以協助我們理解邏輯程序,分析運作流程例如: 由虛擬碼中,我們很容易的看出,Test1.Exe 要求輸入一個密碼,而密碼如果等於 10 ,則會印出’key OK’。我們可以推斷出有一個正確的密碼 10 ,被作者寫死在程式中。
IDA Pro還有些變數分析的方法發現當初作者在寫式時,定義了一個 Local 變數 int Key。
因為 Dec-C++ 將一些原始碼的訊息寫入執行檔,保留給偵錯時使用。在發行版本前,改變 Compiler 參數,去掉偵錯用的訊息,這樣程式會小很多。
結論
我們用一個簡單的逆向工程例子,介紹使用一些工具,將一個未知的執行檔,轉成組合語言,或是更進一步轉成虛擬碼,並經由虛擬碼來瞭解這個執行檔的行為,希望本文對大家有幫助。