用ollydbg手脫ArmadilloV3.60加殼的DLL

來源:互聯網
上載者:User

用Ollydbg手脫ArmadilloV3.60加殼的DLL

作者:fly

【作者聲明】:只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!

【調試環境】:WinXP、Ollydbg1.10C、PEiD、LordPE、ImportREC

—————————————————————————————————

【脫殼過程】:

        

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.