用Ollydbg手脫Armadillo V3.60加殼的DLL

來源:互聯網
上載者:User
Armadillo加殼DLL的脫殼筆記到現在還沒兄弟整理放上來,《加密與解密》中也沒有提及。這些天相當鬱悶,為了轉移一下心境,用了半天時間寫下這點東西,其實標準殼的DLL關鍵是重定位表的問題啦。
   
借用《加密與解密》第2版光碟片中附帶的EdrLib.dll為例子來示範吧,況且看雪老師還寫了EdrTest.exe,脫殼後測試很方便啦。
用Armadillo V3.60的Standard Protection Plus Debug-Blocker方式來給EdrLib.dll加殼,如果選擇CopyMem-II方式給DLL加殼,則Armadillo會警告的。看來forgot是看不到雙進程的DLL啦,呵呵。
   
—————————————————————————————————
一、Magic Jump + DUMP
         
           
先用LordPE看看加殼後的DLL資訊:基址=00400000,進入點=00029A93
   
Ollydbg1.10C調試DLL確實方便,我們不需要在入口插入CC(SoftIce調試DLL),也不需要藉助DLL_Loader.exe,所要做的就是在DLL上點右鍵,選擇“Open With Ollydbg”;當然,你要先設定菜單關聯,把Ollydbg添加進系統資源管理員裡啦。或者你願意用Ollydbg直接載入DLL也行啦。
   
設定Ollydbg忽略所有的異常選項。老規矩:用IsDebug 1.4外掛程式去掉Ollydbg的調試器標誌。
   

代碼:--------------------------------------------------------------------------------
00899A93   55             push ebp//進入OD後停在這
00899A94   8BEC           mov ebp,esp
00899A96   53             push ebx
00899A97   8B5D 08         mov ebx,dword ptr ss:[ebp+8]
00899A9A   56             push esi
00899A9B   8B75 0C         mov esi,dword ptr ss:[ebp+C]
00899A9E   57             push edi
00899A9F   8B7D 10         mov edi,dword ptr ss:[ebp+10]
00899AA2   85F6           test esi,esi
00899AA4   75 09           jnz short EdrLib.00899AAF
--------------------------------------------------------------------------------

   
偶們下斷:BP GetModuleHandleA+5,Shift+F9運行,注意看堆棧:

代碼:--------------------------------------------------------------------------------
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
注意看BP GetModuleHandleA+5 時的堆棧變化:
       
0006BFA0   00A2C807 返回到 00A2C807 來自 kernel32.GetModuleHandleA
0006BFA4   00A3D6C8 ASCII "kernel32.dll"
0006BFA8   00A3E67C ASCII "VirtualAlloc"
   
0006BFA0   00A2C824 返回到 00A2C824 來自 kernel32.GetModuleHandleA
0006BFA4   00A3D6C8 ASCII "kernel32.dll"
0006BFA8   00A3E670 ASCII "VirtualFree"
   
0006BD18   00A1799B 返回到 00A1799B 來自 kernel32.GetModuleHandleA
0006BD1C   0006BE54 ASCII "kernel32.dll"//可以返回了 ★
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
--------------------------------------------------------------------------------

   
看到上面的樣子就可以取消斷點,Alt+F9返回程式,修改Magic Jump了
   

代碼:--------------------------------------------------------------------------------
00A17995   FF15 C480A300     call dword ptr ds:[A380C4] ; kernel32.GetModuleHandleA
00A1799B   8B0D E011A400     mov ecx,dword ptr ds:[A411E0]//返回這裡
00A179A1   89040E         mov dword ptr ds:[esi+ecx],eax
00A179A4   A1 E011A400       mov eax,dword ptr ds:[A411E0]
00A179A9   393C06         cmp dword ptr ds:[esi+eax],edi
00A179AC   75 16           jnz short 00A179C4
00A179AE   8D85 B4FEFFFF     lea eax,dword ptr ss:[ebp-14C]
00A179B4   50             push eax
00A179B5   FF15 CC80A300     call dword ptr ds:[A380CC] ; kernel32.LoadLibraryA
00A179BB   8B0D E011A400     mov ecx,dword ptr ds:[A411E0]
00A179C1   89040E         mov dword ptr ds:[esi+ecx],eax
00A179C4   A1 E011A400       mov eax,dword ptr ds:[A411E0]
00A179C9   393C06         cmp dword ptr ds:[esi+eax],edi
00A179CC   0F84 AD000000     je 00A17A7F//Magic Jump ★   改為JMP!
00A179D2   33C9           xor ecx,ecx
00A179D4   8B03           mov eax,dword ptr ds:[ebx]
00A179D6   3938           cmp dword ptr ds:[eax],edi
00A179D8   74 06           je short 00A179E0
--------------------------------------------------------------------------------

   
   
現在我們Alt+M開啟記憶體查看視窗,看到這個DLL的給個區段
   

代碼:--------------------------------------------------------------------------------
00870000   00001000   EdrLib   00870000 (itself)   PE header
00871000   00003000   EdrLib   00870000 .text //★ 這裡下 記憶體訪問 斷點
00874000   00001000   EdrLib   00870000 .rdata     exports
00875000   00001000   EdrLib   00870000 .data     data
--------------------------------------------------------------------------------

   
在第2個00871000的.text段上設定 記憶體訪問 斷點,F9運行,中斷在OEP
   

代碼:--------------------------------------------------------------------------------
008711C9   55             push ebp//OEP啦 ★
008711CA   8BEC           mov ebp,esp
008711CC   53             push ebx
008711CD   8B5D 08         mov ebx,dword ptr ss:[ebp+8]
008711D0   56             push esi
008711D1   8B75 0C         mov esi,dword ptr ss:[ebp+C]
008711D4   57             push edi
008711D5   8B7D 10         mov edi,dword ptr ss:[ebp+10]
008711D8   85F6           test esi,esi
008711DA   75 09           jnz short EdrLib.008711E5
008711DC   833D 60538700 00   cmp dword ptr ds:[875360],0
008711E3   EB 26           jmp short EdrLib.0087120B
008711E5   83FE 01         cmp esi,1
008711E8   74 05           je short EdrLib.008711EF
008711EA   83FE 02         cmp esi,2
008711ED   75 22           jnz short EdrLib.00871211
--------------------------------------------------------------------------------

   
用LordPE選中Ollydbg的loaddll.exe的進程,在下面的列表裡選擇EdrLib.dll,然後完整脫殼,得到dumped.dll。
   
   
—————————————————————————————————
二、輸入表
   
   
因為已經修改了Magic Jump,所以現在可以得到完整的輸入表。隨便從程式找個API調用:
008710FD   FF15 20408700     call dword ptr ds:[874020]; kernel32.GetVersion
在轉存中跟隨874020,上下看到許多函數地址,很明顯的可以找到IAT開始和結束的地址:
   

代碼:--------------------------------------------------------------------------------
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
IAT:
       
00874000 1D 51 C4 77 1C 3A C4 77 3E E7 C4 77 CC D2 C4 77 .Q.w.:.w>..w...w
00874010 50 88 A1 00 F1 7E E5 77 E1 C9 E5 77 38 C9 E5 77 P....~.w...w8..w
00874020 86 C4 E5 77 B5 5C E5 77 B4 16 E4 77 90 9C E5 77 ...w.\.w...w...w
00874030 C4 7C E5 77 39 9B E5 77 B4 C5 E5 77 29 2B E5 77 .|.w9..w...w)+.w
00874040 61 8B E5 77 31 C9 E5 77 3D 9C E5 77 06 84 E5 77 a..w1..w=..w...w
00874050 7A 17 E4 77 75 32 F5 77 99 A0 E5 77 B1 C5 E7 77 z..wu2.w...w...w
00874060 72 46 E5 77 24 99 E5 77 02 77 E4 77 E1 7E E5 77 rF.w$..w.w.w.~.w
00874070 0B 6E E5 77 26 C7 E5 77 34 9E E5 77 97 15 F5 77 .n.w&..w4..w...w
00874080 8C 9D E5 77 08 99 E5 77 1F E2 F7 77 00 E3 F7 77 ...w...w...w...w
00874090 F8 16 F5 77 9F 84 E5 77 3F A1 E5 77 03 C7 E4 77 ...w...w?..w...w
008740A0 0A 98 E5 77 2F 72 F5 77 FD A5 E5 77 D8 05 E6 77 ...w/r.w...w...w
008740B0 CE 7C E5 77 05 74 E5 77 F9 81 E5 77 EB 41 E4 77 .|.w.t.w...w.A.w
008740C0 66 C8 E5 77 3E 18 F6 77 C3 88 A1 00 00 00 00 00 f..w>..w........
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
--------------------------------------------------------------------------------

   
開始地址=00874000
結束位址=008740C9
   
但是現在直接用ImportREC選取EdrLib.dll,填入RVA=00004000、大小=C9,卻提示“不能載入當前進程相關資料資訊!”
看看ImportREC的日誌:
映像基地址:00400000 大小:00097000
->> 模組被選擇! : e:\試煉場\脫殼學習\dll脫殼\armadillo\edrlib.dll\edrlib.dll
原來ImportREC顯示EdrLib.dll的基址還是00400000,呵呵
   
如果填入RVA=00474000、大小=C9,可以得到輸入表,卻無法完成修複抓取檔案。為何?都是重定位惹的禍啦。
於是懶人如我就想了個移花接木的辦法:再開啟一個Ollydbg,載入Win98的NotePad.EXE,然後把00874000-008740C9的資料複製、粘貼進NotePad.EXE的00404000-004040C9,然後用ImportREC選擇NotePad.EXE進程,填入RVA=00004000、大小=C9,得到輸入表,CUT掉垃圾指標,改OEP=000011C9,就可以FixDump啦!
   
   
—————————————————————————————————
三、重定位表 修複
   
   
麻煩就在這裡!因為Armadillo加殼DLL的重定位表處理方面沒有找到資料可以參考。後來我發現Armadillo加殼DLL沒有加密重定位表!終於鬆了口氣呀,我們所要做的就是找到DLL原來的重定位表的RVA和大小就行了!
   
我們可以從程式中找到某處需要重定位的地方,比如OEP附近的:
008711DC   833D 60538700 00   cmp dword ptr ds:[875360],0
這裡的[875360]肯定是重定位之後的,我們重新Load後對008711E0處下硬體或者記憶體訪問/寫入斷點,然後監視程式何時把008711E0處的40變化為87就能找到重定位處理的程式碼片段了!但是這樣比較麻煩,琢磨了半天(呵呵,時間都花在這裡了),提供一個簡便尋找重定位處理程式碼片段的方法!
   
用Ollydbg重新載入EdrLib.dll,下斷:BP GetModuleHandleA+5,Shift+F9運行,注意看堆棧:
   

代碼:--------------------------------------------------------------------------------
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
注意看BP GetModuleHandleA+5 時的堆棧變化:
   
0006BFA0   00A2C807 返回到 00A2C807 來自 kernel32.GetModuleHandleA
0006BFA4   00A3D6C8 ASCII "kernel32.dll"
0006BFA8   00A3E67C ASCII "VirtualAlloc"
   
0006BFA0   00A2C824 返回到 00A2C824 來自 kernel32.GetModuleHandleA
0006BFA4   00A3D6C8 ASCII "kernel32.dll"
0006BFA8   00A3E670 ASCII "VirtualFree"
   
0006BD18   00A1799B 返回到 00A1799B 來自 kernel32.GetModuleHandleA
0006BD1C   0006BE54 ASCII "kernel32.dll"//返回修改Magic Jump的地方 ★
   
0006BD18   00A1799B 返回到 00A1799B 來自 kernel32.GetModuleHandleA
0006BD1C   0006BE54 ASCII "user32.dll"
   
0006BD18   00A1799B 返回到 00A1799B 來自 kernel32.GetModuleHandleA
0006BD1C   0006BE54 ASCII "advapi32.dll"
   
0006BFA4   00A3134F 返回到 00A3134F 來自 kernel32.GetModuleHandleA
//★ 時機到啦
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
--------------------------------------------------------------------------------

   
這裡是以前返回修改Magic Jump的地方,現在我利用這個時機來搞定重定位表!
   
我們Alt+M開啟記憶體查看視窗,看到這個DLL的各個區段:
   

代碼:--------------------------------------------------------------------------------
00870000   00001000   EdrLib   00870000 (itself)   PE header//★ 這裡下 記憶體訪問 斷點
00871000   00003000   EdrLib   00870000 .text
00874000   00001000   EdrLib   00870000 .rdata     exports
00875000   00001000   EdrLib   00870000 .data     data
--------------------------------------------------------------------------------

   
這次我在第1個00870000的PE header段上設定 記憶體訪問 斷點,F9運行,程式中斷在00A32393處!

代碼:--------------------------------------------------------------------------------
00A32335   87FA           xchg edx,edi
00A32337   C705 DCDBA300 E4E4A>mov dword ptr ds:[A3DBDC],0A3E4E4
00A32341   A1 9C55A400       mov eax,dword ptr ds:[A4559C]
00A32346   8B00           mov eax,dword ptr ds:[eax]
//[EAX]=[008F86D1]=00006000   ★ 這個00006000就是重定位表的RVA!
00A32348   8985 48ECFFFF     mov dword ptr ss:[ebp-13B8],eax
00A3234E   A1 9C55A400       mov eax,dword ptr ds:[A4559C]
00A32353   83C0 04         add eax,4
00A32356   A3 9C55A400       mov dword ptr ds:[A4559C],eax
00A3235B   A1 9C55A400       mov eax,dword ptr ds:[A4559C]
00A32360   8B00           mov eax,dword ptr ds:[eax]
//[EAX]=[008F86D5]=000003B0   ★ 這個000003B0就是重定位表的大小!
00A32362   8985 7CECFFFF     mov dword ptr ss:[ebp-1384],eax
00A32368   A1 9C55A400       mov eax,dword ptr ds:[A4559C]
00A3236D   83C0 04         add eax,4
00A32370   A3 9C55A400       mov dword ptr ds:[A4559C],eax
00A32375   83BD 48ECFFFF 00   cmp dword ptr ss:[ebp-13B8],0
00A3237C   74 6F           je short 00A323ED
00A3237E   83BD 7CECFFFF 00   cmp dword ptr ss:[ebp-1384],0
00A32385   74 66           je short 00A323ED
00A32387   8B85 0CEBFFFF     mov eax,dword ptr ss:[ebp-14F4]
00A3238D   8B8D 1CEBFFFF     mov ecx,dword ptr ss:[ebp-14E4]
00A32393   3B48 34         cmp ecx,dword ptr ds:[eax+34]; LOADDLL.00400000
//中斷在這裡!
00A32396   74 55           je short 00A323ED//如與映像基址不符則重定位處理!★
00A32398   FFB5 7CECFFFF     push dword ptr ss:[ebp-1384]
00A3239E   8B85 1CEBFFFF     mov eax,dword ptr ss:[ebp-14E4]
00A323A4   0385 48ECFFFF     add eax,dword ptr ss:[ebp-13B8]
00A323AA   50             push eax
00A323AB   8B85 0CEBFFFF     mov eax,dword ptr ss:[ebp-14F4]
00A323B1   FF70 34         push dword ptr ds:[eax+34]
00A323B4   FFB5 1CEBFFFF     push dword ptr ss:[ebp-14E4]
00A323BA   E8 A8100000       call 00A33467//重定位處理CALL ★
00A323BF   83C4 10         add esp,10
00A323C2   0FB6C0         movzx eax,al
00A323C5   85C0           test eax,eax
00A323C7   75 24           jnz short 00A323ED
00A323C9   8B45 08         mov eax,dword ptr ss:[ebp+8]
00A323CC   8B00           mov eax,dword ptr ds:[eax]
00A323CE   C700 07000000     mov dword ptr ds:[eax],7
00A323D4   68 D4E4A300       push 0A3E4D4         ; ASCII "Location CPG"
00A323D9   8B45 08         mov eax,dword ptr ss:[ebp+8]
00A323DC   FF70 04         push dword ptr ds:[eax+4]
00A323DF   E8 68530000       call 00A3774C         ; jmp to MSVCRT.strcpy
00A323E4   59             pop ecx
00A323E5   59             pop ecx
00A323E6   33C0           xor eax,eax
00A323E8   E9 BB030000       jmp 00A327A8
--------------------------------------------------------------------------------

   
呵呵,00A323BA的CALL裡面就是重定位處理的核心,如果採用在重定位後的地址下記憶體斷點的方法,最終會中斷在這個CALL裡面的。其實在這個CALL的上面我們就可以得到DLL原先的重定位表的RVA和大小!
   
下硬體執行斷點:HE 00A32346,Ctrl+F2重新載入這個DLL,Shift+F9運行,程式中斷在00A32346處!分析見上。
   
   
—————————————————————————————————
四、修正 + 最佳化
   
   
用LordPE修正dumped_.dll的重定位表RVA=00006000、大小=000003B0,儲存之。
如果在00A32396處修改為JMP跳過重定位處理,則不需要修改DLL的基址,否則修改基址為OEP處看到的基址,如這裡為00870000
   
用LordPE刪除dumped_.dll的text1和其下的adata、data1、reloc1、pdata共5個區段,然後去掉“脫殼修複”和“清除重定位表”選項,重建PE簡單最佳化一下脫殼後的檔案,608K->17K,暈,比加殼前的原檔案還小了。
   
脫殼後的DLL用PEiD看依舊顯示“Armadillo 2.51-3.xx DLL Stub -> Silicon Realms Toolworks”,呵呵。用FI看顯示“MS VC++ v6.0 {DLL} ”。如果想測試脫殼後的DLL,可以把UnPacked-EdrLib.dll重新命名為EdrLib.dll,然後運行EdrTest.exe就知道是否脫殼成功了。
   
其實熟悉之後完全可以一次完成脫殼,為了說的詳細點,所以分了幾次。經驗來自於不斷的實踐、總結和積累。
拙文一篇,僅供各位對DLL脫殼感興趣的兄弟參考。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.