【摘錄】反編譯Delphi軟件DEDE的使用


elphi/C++ Builder采用控件拖放的方式來完成界面的設計,並和事件聯系起來。而這些信息以資源(RCDATA)的方式存放於可執行文件中。DeDe便利用這個原理進行反編譯,獲取相關信息,將界面與事件聯系關系還原,但事件的匯編代碼不能還原。DeDe公開了源代碼,感興趣的讀者可以研究一下。

1.主要功能 
用DeDe可以查看Delphi程序窗體的屬性,可以查看按鈕對應的事件,並將事件代碼反匯編出來,其能識別出Delphi庫函數,具有良好的可讀性。另外,還可以把事件輸出到map文件中供其他工具使用。

2.配置 
(1)DSF文件

①DSF文件的含義

DSF文件內容來自不同版本BPL庫文件的輸出符號表。DeDe反匯編引擎使用這些符號表對生成的ASM代碼文件添加類成員方法調用的注釋,這非常類似於IDA Pro的FLIRT技術。如果沒有加載任何BPL符號表文件,對BPL類的調用就無法以注釋的格式說明。

②加載DSF文件

經由“File/Load Symbol File”菜單,就可加載所需要的DSF文件。程序若能正確識別出相應版本的Delphi程序,會自動加載DSF文件。若希望每次啟動DeDe的同時自動加載若干DSF文件,選中“Options/Configuration”菜單,在Symbols選項卡中就可完成本項工作。如果想查看包含在某個特定DSF文件中的輸出符號表,選擇“Options/Symbols”。

③為何需要創建DSF文件

處理使用自定義構件(即不是Delphi安裝的構件)的程序時,如果有這些自定義構件的BPL,並且為它們創建了DSF文件,那么DeDe將會注釋所有對這些自定義構件的調用。創建DSF的速度也是很快的。

(2)DOI文件

DOI意思是Delphi Class Offset Information(Delphi類偏移信息),該技術使用偏移信息識別類成員:方法和域(實例變量,屬性)。DOI文件包含用於識別的必要數據。DeDe仿真指令的執行來查找使用這些偏移的引用所在。例如,在繼承自TForm類的任何子類的偏移0xCC處,代表指向ShowModal方法的指針。當遇到類似call [reg + $00CC]的調用時,仿真器就知道寄存器包含的對象是引用TForm.ShowModal方法的TForm子類。DOI文件應該存放在DSF文件夾內。

下面是一個生成的帶有DOI幫助信息的簡單示例。

* Reference to control LogMemo : TMemo 
004E4E7C   8B80F4020000       mov  eax, [eax+$02F4]
* Reference to field TMemo.Lines : TStrings 
004E4E82   8B8004020000       mov  eax, [eax+$0204]
* Possible String Reference to: 'Loading Export Names ...' 
004E4E88   BA0C584E00          mov dx, $004E580C
004E4E8D   8B08                  mov ecx, [eax]
* Reference to method TStrings.Add(string) 
004E4E8F   FF5134                call    dword ptr [ecx+$34]

使用DOI文件,只需復制*.DOI文件到DSF文件夾即可。DOI數據會自動插入到生成的代碼文件中。
(3)字符串參考的含義
在DeDe中,如果處理含有非英文字符串的程序,則選擇“Option/Configuration”菜單,在References選項卡中可以設置DeDe反編譯引擎查找字符串參考時使用的字符集。
  


注意:如果使用全部的字符集合#32~#255,則可能得到殘缺的字符串參考。Delphi程序一般不用Unicode字符串,這也是該選項沒有包括在字符串參考配置中的原因。 
3.基本操作  
DeDe安裝很簡單。安裝好后直接執行主程序,出現如圖7.1所示的主界面。單擊  按鈕打開光盤映像文件中的DE_Delphi文件,然后單擊“Process”按鈕進行反編譯。DeDe先將被分析的文件裝載到內存中,再進行反編譯,因此對一些壓縮加殼的程序也能反編譯。
CLasses Info:顯示程序中使用的類信息;
Units Info:顯示程序中使用的單元信息;
Forms:顯示程序中的窗體信息,這部分可以用資源編輯工具修改;
Procedures:顯示程序的過程信息;
Project:可將當前項目保存;
Exports:導出符號文件。

 

圖7.1  DeDe界面


在此顯示了Events(事件)和Controls(控件)兩方面的內容(見圖7.2)。Button1Click事件對應的是“確定”按鈕,雙擊可打開代碼窗口。該窗口顯示當前事件對應的匯編代碼,右邊控制條顯示全局變量和局變量。雙擊某個表達式,可以加注釋。在跳轉指令、CALL指令上雙擊可跳到相應代碼上。




圖7.2  查看事件按鈕


設目標實例DE_Delphi的用戶名為Name[],具體代碼如下:
* Reference to control TMainForm.Edit1 : TEdit  ;用戶名框控件
004502C6        mov      eax, [esi+$02F8]
* Reference to: controls.TControl.GetText(TControl):System.String;
004502CC     call     0042F4F8
004502D1     cmp     dword ptr [ebp-$0C],+$00    ;判斷是否輸入字符
004502D5     jnz      004502F5
……
* Reference to: controls.TControl.GetText(TControl):System.String;
004502FE     call    0042F4F8
00450303     mov      eax, [ebp-$10]            ;指向用戶名
* Reference to: system.@LStrLen:Integer;
00450306     call    004044C4
0045030B     cmp      eax, +$04                    ;判斷是否輸入了4個字符
0045030E     jnl     0045032E
……
* Reference to: controls.TControl.GetText(TControl):System.String;
00450345     call    0042F4F8
0045034A     mov     eax, [ebp-$14] 指向Name[]
* Reference to: system.@LStrLen:Integer;
0045034D     call    004044C4                     ;得到用戶名長度
00450352     mov     ebx, eax                     ;將長度放到ebx中作為計數器
00450354     test    ebx, ebx
00450356     jle     00450381  
00450358     mov     edi, $00000001             ;edi=1
0045035D     /mov    eax, [ebp-$08]             ;指向Name[]
00450360    |movzx  eax, byte ptr[eax+edi-$01]   
00450365     |lea     ecx, [ebp-$18]
00450368    |mov    edx, $00000002
*Referenceto: sysutils.IntToHex(System.Integer;System.Integer)
0045036D     |call   00408310                   ;inttohex(ord(Name[i]),2)
00450372     |mov     edx, [ebp-$18]             ;[ebp-$18]指向Name[i]16進制
00450375     |lea     eax, [ebp-$04]             ;[ebp-$04]變量是指向Sn指針的指針
* Reference to: system.@LStrCat;
00450378     |call        004044CC                ;將兩個串連起來,設為Sn
0045037D     |inc     edi                            ;i+1
0045037E     |dec     ebx                            ;計數器減1
0045037F     \jnz     0045035D                     ;循環
……
* Reference to: controls.TControl.GetText(TControl):System.String;
0045038A     call    0042F4F8                     ;取輸入的序列號
0045038F     mov     eax, [ebp-$1C]             ;[ebp-$1C]是輸入的序列號指針
00450392     mov     edx, [ebp-$04]             ;[ebp-$04]中存放的是正確的序列號
* Reference to: system.@LStrCmp;
00450395     call     00404608                ;比較兩個臨時變量
0045039A     jnz     004503B7
由於DeDe的符號識別技術,使得上述代碼可讀性非常容易理解。
在圖7.2中有兩個按鈕值得注意:
DPR按鈕:是反匯編項目文件.dpr,該文件控制或記錄程序中的所有文件。
OFFS按鈕:反匯編指定地址的代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM