用OD對Aspr加殼程式的手動脫殼及修復 (7千字)

看雪資料發表於2015-11-15

目標程式AlfaClock 1.60a(華軍下載)
工具 OllyDbg 1.09d
     LordPE
     ImportRec 1.60
一、脫殼:
用OD載入後去掉偵錯程式標誌(IsDebuggerPresent),F9執行,異常後按21次SHIFT+F9,
將Hex Dump視窗轉到4D6420,會看到如下資料,這裡從4D6420到4D6453是Aspr要修改的
地方,主要是:
      1.4D6420  字串指標,若這個指標指向空串,表示未註冊
      2.4D6428  字串指標,這個指標不能指向空串,Aspr讓它指向7Rk1OABg9ag=
      3.4D6430-4D643B是三個函式的入口地址,Aspr會修改這三個指標,使其指向
        殼中的三個函式!
      4.4D6440  Share 版的使用天數,4D6444  剩下的天數
      5.從4D6448-4D6453是程式驗證殼存在的標記
004D6420  00 00 00 00 00 00 00 00 00 00 00 00 00 8D 40 00  .............@.
004D6430  70 1B 4D 00 9C 1B 4D 00 9C 1B 4D 00 00 00 00 00  pM.?M.?M.....
004D6440  FE FF FF FF FE FF FF FF 00 00 00 00 FE FF FF FF  ??....?
004D6450  FE FF FF FF 
(從上面的敘述你應該知道修復程式時你要幹什麼了吧)go on
再按 5次SHIFT+F9,程式停在這裡:
00FD3D03  XOR DWORD PTR DS:[EAX],EAX
00FD3D05  POP DWORD PTR FS:[0]
00FD3D0C  POP EAX
00FD3D0D  CMP DWORD PTR DS:[FD7EBC],0
00FD3D14  JE SHORT 00FD3D2A
00FD3D16  PUSH 0C
00FD3D18  MOV ECX,0FD7EBC
00FD3D1D  LEA EAX,DWORD PTR SS:[EBP-8]
00FD3D20  MOV EDX,4
00FD3D25  CALL 00FD1010
00FD3D2A  PUSH DWORD PTR SS:[EBP-4]
00FD3D2D  PUSH DWORD PTR SS:[EBP-8]
00FD3D30  MOV EAX,DWORD PTR SS:[EBP-C]
00FD3D33  CMP DWORD PTR DS:[EAX],0
00FD3D36  JE SHORT 00FD3D3A
00FD3D38  PUSH DWORD PTR DS:[EAX]
00FD3D3A  PUSH DWORD PTR SS:[EBP-10]
00FD3D3D  PUSH DWORD PTR SS:[EBP-14]
00FD3D40  RETN
我們馬上要進入原程式了,再看看Hex Dump視窗:
004D6420  51 39 FC 00 00 00 00 00 30 A3 FE 00 00 8D 40 00  Q9?....0 ̄..@.
004D6430  A4 14 FD 00 40 14 FD 00 74 14 FD 00 FE FF FF FF  ??@?t??
004D6440  1E 00 00 00 0D 00 00 00 FE FF FF FF 00 00 00 00  .......?....
004D6450  00 00 00 00 
看到修改了?這時,可以DUMP程式了,用LordPE,操作就不講了吧。

二、修復IAT:
在上面的RETN處設斷,SHIFT+F9,斷點處停下後F2清除斷點再F8,來到:
00FE7CF0  PUSH EAX       ;停在這裡
00FE7CF1  POP ESI
00FE7CF2  CALL 00FE7D01
00FE7CF7  PUSH 5B
00FE7CF9  CLC
00FE7CFA  SAL DWORD PTR DS:[ESI],1

稍往下滾動滑鼠,看到
00FE7D5F  MOV EDI,ECX
00FE7D61  MOV DWORD PTR DS:[EAX],EBX
00FE7D63  MOV DX,0DC32
00FE7D67  SUB EAX,4
00FE7D6A  MOV DX,CX
00FE7D6D  SUB ECX,1
00FE7D73  JNZ 00FE7D90
00FE7D79  JPE 00FE7D84        <-游標移到這裡按F4
00FE7D7F  OR DX,0DEAD
00FE7D84  JMP 00FE7DB6

游標移到FE7D79(JPE 00FE7D84)再F4,下面,Aspr下面要執行是
1.執行Stolen code
2.銷燬來到這裡的程式段
有興趣的可以跟,我選擇的是直接進入原程式。於是再稍往下滾動滑鼠,看到

00FE7DC0  PUSHAD
00FE7DC1  PUSHFD
00FE7DC2  CLD
00FE7DC3  MOV EDI,0
00FE7DC8  MOV ECX,0
00FE7DCD  REP STOS BYTE PTR ES:[EDI]
00FE7DCF  POPFD
00FE7DD0  POPAD
00FE7DD1  RETN

游標移到RETN處F4,再F8就進入原程式了:

00406324  JMP DWORD PTR DS:[4D9280]       <-停在這裡
0040632A  MOV EAX,EAX
0040632C  JMP DWORD PTR DS:[4D927C]
00406332  MOV EAX,EAX
00406334  JMP DWORD PTR DS:[4D9278]

顯然,我們處在程式執行了一段程式碼的位置,但這並不妨礙修復IAT,看看堆疊:

0012FF6C  004063F9  RETURN to AlfaCloc.004063F9 from AlfaCloc.00406324
0012FF70  00000000
0012FF74  0000071D
0012FF78  004D2FD5  RETURN to AlfaCloc.004D2FD5 from AlfaCloc.004063E8
0012FF7C  005885C3  AlfaCloc.005885C3
0012FF80  0000071D
0012FF84  00000000
0012FF88  00000000
0012FF8C  00000000
0012FF90  0000071D
0012FF94  00B37CEE
0012FF98  00FE7E99
0012FF9C  00B37CEE
0012FFA0  00B37CEE
0012FFA4  00000000
0012FFA8  00000000
0012FFAC  0012FFF0
0012FFB0  0012FFC4
0012FFB4  7FFDF000
0012FFB8  FFFFFFFF
0012FFBC  00010101
0012FFC0  00000000
0012FFC4  77E67903  RETURN to kernel32.77E67903
容易找到被刪除了Stolen code的oep,就是4D2FD5上一條語句的位置,滑鼠選中
堆疊區0012FF78處的004D2FD5,回車後再向上滾動滑鼠,看到

004D2FCA  ADD BYTE PTR DS:[EAX],AL
004D2FCC  ADD BYTE PTR DS:[EAX],AL
004D2FCE  ADD BYTE PTR DS:[EAX],AL
004D2FD0  CALL AlfaCloc.004063E8 
004D2FD5  MOV EBX,DWORD PTR DS:[4D69C0]            
004D2FDB  XOR EAX,EAX
004D2FDD  PUSH EBP
004D2FDE  PUSH AlfaCloc.004D3248

好,就把 D2FD0作為oep吧。啟動ImportREC,選中目標,就緒後在OEP處填上D2FD0,
點選IAT AutoSearch得到RVA: 000D9274  Size: 0000000C,從Size值知道這裡有誤,
把Hex Dump區轉到4D9000往下翻頁,看到

004D9190  C7 E6 60 A5 5E 88 19 A0 D5 48 A7 3D BD A9 03 F3  擎`^?_H?僵 
004D91A0  78 92 22 D4 70 05 FE 00 A0 05 FE 00 AC 05 FE 00  x?p ?????
004D91B0  5C 92 FE 00 B8 05 FE 00 D0 05 FE 00 EC 05 FE 00  \.??????
004D91C0  1C 06 FE 00 4C 06 FE 00 58 06 FE 00 28 15 FD 00    ?L ?X ?( ?
004D91D0  68 06 FE 00 78 06 FE 00 84 06 FE 00 90 06 FE 00  h ?x ?????
004D91E0  A8 06 FE 00 B8 06 FE 00 C8 06 FE 00 F4 06 FE 00  ????????
004D91F0  24 07 FE 00 34 07 FE 00 44 07 FE 00 AC 10 FD 00  $?4?D???
004D9200  00 15 FD 00 7C 07 FE 00 94 07 FE 00 74 15 FD 00  . ?|???t ?
004D9210  A4 07 FE 00 B0 07 FE 00 C0 07 FE 00 F0 07 FE 00  ????????
004D9220  1C 08 FE 00 4C 08 FE 00 70 08 FE 00 A0 08 FE 00    ?L ?p ???
004D9230  CC 08 FE 00 DC 08 FE 00 EC 08 FE 00 C6 8B D1 6F  ??????o
004D9240  7E FB DF 77 AF E3 DF 77 68 3D E2 77 04 CF DF 77  ~wwh=w 線w
004D9250  38 5B C5 63 8E 85 D9 77 AC 82 D9 77 4D 7D D9 77  8[cwwM}w
004D9260  02 5F 8A FD 33 15 99 77 A6 3F 99 77 59 14 99 77   _3 w?wY w
004D9270  36 D7 A2 D9 00 09 FE 00 18 09 FE 00 2C 09 FE 00  6注?.? .?,.?
004D9280  00 15 FD 00 26 A3 03 CD 54 94 D9 77 8E 85 D9 77  . ?&?Tww

可以看出D91A4是RVA值,Size值?再往下翻頁直到

004D9830  BA 22 99 77 94 23 99 77 39 99 00 34 B0 30 A3 77  ?w?w9?4?w
004D9840  E0 4F A3 77 84 69 A3 77 1A 69 A3 77 D5 BF FC 06  Owiw iw湛?
004D9850  54 10 FE 00 64 10 FE 00 70 10 FE 00 88 10 FE 00  T ?d ?p ???
004D9860  A0 10 FE 00 AC 10 FE 00 BC 10 FE 00 CC 10 FE 00  ????????
004D9870  E4 10 FE 00 F0 10 FE 00 00 11 FE 00 0C 11 FE 00  ????. ?. ?
004D9880  1C 11 FE 00 28 11 FE 00 38 11 FE 00 48 11 FE 00    ?( ?8 ?H ?
004D9890  58 11 FE 00 64 11 FE 00 70 11 FE 00 80 11 FE 00  X ?d ?p ? ?
004D98A0  90 11 FE 00 9C 11 FE 00 A8 11 FE 00 C8 11 FE 00  ????????
004D98B0  9C AE 54 F4 6C 5A 7C 77 5C 63 7C 77 81 59 7C 77  TlZ|w\c|wY|w
004D98C0  CC 45 7C 77 02 61 67 9F 72 C3 5F 77 4B 71 19 5F  E|w agr_wKq _
004D98D0  45 6D B0 76 60 EF AF 76 CD A5 AF 76 27 BC D1 4E  Emv`鋯v庭v'佳N
004D98E0  A6 AF 4A 77 E8 12 4A 77 78 7D 79 13 E9 34 53 77  ΟJw?Jwx}y ?Sw
004D98F0  B6 C6 36 8E 69 27 FB 74 6A 4A FB 74 24 58 FB 74  鍍6i'tjJt$Xt
004D9900  71 66 11 68 09 EB FB 3C 09 75 91 84 E5 61 CF D6  qf h.臌<.ua現

顯然D9900是中止值,於是Size:900-1A4=75C
把D91A4和75C分別填好後,就可以Get Imports了。對於unresolved pointers,
   1.Show Invalid 後 Trace Level1(Disasm)
   2.Show Invalid 後 Plugin Tracers -> Asprotect 1.22
以上兩步之後就只有 rva: 000D93AC  ptr: 000FD158C 是真的unresolved pointer了。
選中本行後選擇Disassemble/HexView,看到
00FD158C   PUSH EBP
00FD158D   MOV EBP,ESP
00FD158F   MOV EAX,DWORD PTR DS:[FD7CF0]   // DWORD value : 00133938
00FD1595   POP EBP
00FD1596   RETN 4
這是Aspr製造的一個的unresolved的"API",
(如果RETN 4 換成RETN,就是GetCommandLineA,嘿嘿)
因此這個函式應該resolved成LockResource,為什麼?嘿嘿!
好了,對於剩下的unresolved pointers就全是Invalid了,Show Invalid,Cut Thunks。


三、修復
這是最麻煩的一步。
(一)修改Aspr修改過的 D6420開始的幾個指標,主要思想是:
      1.還原原來的三個函式指標
      2.讓兩個字串指標指向程式內部某處,我選定的是589800和5797F0,在這兩個
        位置放入字串Pediy001和7Rk1OABg9ag=。呵呵
下面是我修改過的情況
004D6420  00 98 58 00 00 00 00 00 F0 97 58 00 00 8D 40 00  .X.....X..@.
004D6430  70 1B 4D 00 9C 1B 4D 00 9C 1B 4D 00 FE FF FF FF  pM.?M.?M.?
004D6440  1E 00 00 00 10 00 00 00 FE FF FF FF 00 00 00 00  ......?....
004D6450  00 00 00 00                                      ....
(二)模擬stolen code
      主要是根據EIP的位置(00406324  JMP DWORD PTR DS:[4D9280]),參照此時程式
到要執行的“明碼”、堆疊結構和暫存器的情況來模擬
明碼是:
004063E8  PUSH EBX
004063E9  MOV EBX,EAX
004063EB  XOR EAX,EAX
004063ED  MOV DWORD PTR DS:[4D40A0],EAX
004063F2  PUSH 0
004063F4  CALL AlfaCloc.00406324         <- 正常情況下程式應從這裡到達00406324
004063F9  MOV DWORD PTR DS:[4D7664],EAX

堆疊結構前面已列出,暫存器的情況這時是:
EAX=0 ECX=FE787F EDX=FE7F98 EBX=4D2B48 
ESP=12FF6C EBP=12FFA0 ESI=5885C3 EDI=1

因此,程式在呼叫函式時,這幾個量是重要的:
EAX=4D2B48、ESI=58853、EBP=12FFA0,來到這裡,應有相似的堆疊結構,怎樣模擬我想這
是一件仁者見仁的事吧。我在程式中構造了一個函式來完成,函式後面給出。

(三)去除暗樁:暗樁的查詢太麻煩就免了,只說修改吧。使用 Hex編輯器作下列修改:
      1.004D1E05 處的 FF 33和 004D1E0A 的 8F 03 全改成 90 90
      2.004D1DD4 的 74 改為 EB
      3.004D63E3 的 FC 2D 8C FD 改為 8D 8D 8D 8D
      4.004D63F7 的 88 B9 18 89 改為 19 19 19 19
      5.004D6413 的 63 94 F3 64 改為 F4 F4 F4 F4
(四)申請區域性堆,模擬Aspr的驗證資料
  以前對付Aspr加殼程式都沒有這一步,包括AlfaClock的1.60版,現在Aspr玩的花樣是越
來越多了!
  在修復的前兩步完成後程式仍然不能正常執行,發現它要到139XXX去取資料,再次跟蹤加
殼的程式,發現了這些“無聊”的資料,它們唯一的作用就是讓你脫殼後的程式不能執行。
於是你也得在區域性堆有相似的資料結構,哈,就在堆中申請一點記憶體來模擬吧!這些工作一
並交給我構造的函式來完成。不過說清這個函式的事就算了,函式如下
004D3330  PUSH EBP
004D3331  MOV EBP,ESP
004D3333  PUSHAD
004D3334  PUSH 0FF8                                 /Size = FF8 (4088.)
004D3339  PUSH 40                                   |Flags = LPTR
004D333B  CALL            \LocalAlloc
004D3340  PUSH EAX
004D3341  PUSH 664                                  /Size = 664 (1636.)
004D3346  PUSH 0                                    |Flags = LMEM_FIXED
004D3348  CALL            \LocalAlloc
004D334D  POP EDX
004D334E  MOV DWORD PTR DS:[4D7620],EDX
004D3354  MOV DWORD PTR DS:[4D75E0],EAX
004D3359  MOV DWORD PTR DS:[EAX],0
004D335F  MOV ECX,60
004D3364  MOV EDI,DWORD PTR DS:[4D75E0]
004D336A  ADD EDI,14
004D336D  MOV EBX,EDI
004D336F  SUB EBX,10
004D3372  MOV DWORD PTR DS:[EDI],EBX
004D3374  ADD EDI,10
004D3377  ADD EBX,10
004D337A  LOOPD SHORT dumped_.004D3372
004D337C  ADD EBX,20
004D337F  MOV DWORD PTR DS:[EDI],EBX
004D3381  ADD EDI,10
004D3384  ADD EBX,10
004D3387  MOV DWORD PTR DS:[EDI],EBX
004D3389  ADD EDI,10
004D338C  SUB EBX,30
004D338F  MOV DWORD PTR DS:[EDI],EBX
004D3391  MOV EDI,DWORD PTR DS:[4D75E0]
004D3397  ADD EDI,614
004D339D  MOV DWORD PTR DS:[4D75E4],EDI
004D33A3  XOR EAX,EAX
004D33A5  MOV DWORD PTR DS:[4D75C8],EAX
004D33AA  MOV DWORD PTR SS:[EBP+10],EAX
004D33AD  MOV DWORD PTR SS:[EBP+14],EAX
004D33B0  MOV DWORD PTR SS:[EBP+18],EAX
004D33B3  POPAD
004D33B4  MOV EBX,71D
004D33B9  MOV DWORD PTR SS:[EBP+C],EBX
004D33BC  MOV DWORD PTR SS:[EBP+1C],EBX
004D33BF  POP EBP
004D33C0  ADD EBP,30
004D33C3  MOV DWORD PTR SS:[EBP-44],EBP
004D33C6  SUB EBP,50
004D33C9  RETN

注:CALL  是 CALL 401388

最後在4D2FBA鍵入下面程式碼,再用LordPE把EntryPoint的值改成000D2FBA,Over!
004D2FBA  PUSH EBP
004D2FBB  MOV EBP,ESP
004D2FBD  ADD ESP,-40
004D2FC0  MOV EAX,dumped_.004D2B48
004D2FC5  MOV ESI,dumped_.005885C3
004D2FCA  PUSH ESI
004D2FCB  CALL dumped_.004D3330

這是我在001的第一篇,難免錯誤,請各位高手指點

相關文章