ASPR1.2x新版本的脫殼初步探討 (5千字)

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

這裡就以Win2K,Ollydbg尋找System cleaner(4.90 build 122) OEP為例:

新版的ASPR最早讓我發現異樣的就是用IsDebuggerPresent來檢查是否在被除錯,Ollydbg裡下斷點IsDebuggerPresent..經過一系列Shift+F9後斷點來到IsDebuggerPresent的函式里:

77E6F4E9 > 64:A1 18000000   MOV EAX,DWORD PTR FS:[18]
77E6F4EF   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
77E6F4F2   0FB640 02        MOVZX EAX,BYTE PTR DS:[EAX+2]
77E6F4F6   C3               RETN

此函式利用eax返回值,1被除錯,0否..執行到MOVZX EAX,BYTE PTR DS:[EAX+2],看一下DS:[EAX+2]所指記憶體區域,把記憶體中的數值改為0(必須),同時eax也返回了0.

繼續Shift+F9,經過十數個後就來到這裡(當中會發現ASPR比以前的access memory錯誤還多了一些Int3):

01363D5F   3100             XOR DWORD PTR DS:[EAX],EAX                 <-----Ollydbg停在這裡
01363D61   64:8F05 00000000 POP DWORD PTR FS:[0]                       <-----我們在這裡下斷點
01363D68   58               POP EAX
01363D69   833D BC7E3601 00 CMP DWORD PTR DS:[1367EBC],0
01363D70   74 14            JE SHORT 01363D86
01363D72   6A 0C            PUSH 0C
01363D74   B9 BC7E3601      MOV ECX,1367EBC
01363D79   8D45 F8          LEA EAX,DWORD PTR SS:[EBP-8]
01363D7C   BA 04000000      MOV EDX,4
01363D81   E8 8ED2FFFF      CALL 01361014
01363D86   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
01363D89   FF75 F8          PUSH DWORD PTR SS:[EBP-8]
01363D8C   8B45 F4          MOV EAX,DWORD PTR SS:[EBP-C]
01363D8F   8338 00          CMP DWORD PTR DS:[EAX],0
01363D92   74 02            JE SHORT 01363D96
01363D94   FF30             PUSH DWORD PTR DS:[EAX]
01363D96   FF75 F0          PUSH DWORD PTR SS:[EBP-10]
01363D99   FF75 EC          PUSH DWORD PTR SS:[EBP-14]
01363D9C   C3               RETN
01363D9D   5F               POP EDI
01363D9E   5E               POP ESI
01363D9F   5B               POP EBX
01363DA0   8BE5             MOV ESP,EBP
01363DA2   5D               POP EBP
01363DA3   C3               RETN

Shift+F9,ollydbg就停在我們的斷點上..接下去已經沒多少路了,手動吧.F8一直到Retn,然後就在這裡:

01379330   68 D3F8FD02      PUSH 2FDF8D3
01379335   B4 4F            MOV AH,4F
01379337   5B               POP EBX
01379338   66:81D3 27F5     ADC BX,0F527
0137933D   E8 09000000      CALL 0137934B         <------F7進去

接著一直到:
013793EA   5B               POP EBX
013793EB   81C7 5075A77E    ADD EDI,7EA77550
013793F1   E8 0B000000      CALL 01379401         <------F7進去

接下去小心一點,用ollydbg的trace eip很快就能返回程式的領空,首先就是停在這裡:

00407278   $-FF25 2CF35600  JMP DWORD PTR DS:[56F32C]   <-----我們停在這裡
0040727E     8BC0           MOV EAX,EAX
00407280   $-FF25 28F35600  JMP DWORD PTR DS:[56F328]
00407286     8BC0           MOV EAX,EAX
00407288   $-FF25 24F35600  JMP DWORD PTR DS:[56F324]
0040728E     8BC0           MOV EAX,EAX
00407290   $-FF25 20F35600  JMP DWORD PTR DS:[56F320]

對於1.2x和大多數的1.3+來說,trace eip停下來就是OEP裡,但新版本可以看到明顯不一樣,F7跟進去,這裡有一個技巧,如果發現停下來的程式碼都是DB FF之類的,大多數情況下選擇右鍵選單中的analysis/analyze code就可以看到正常的code.有時也不行,下面會看到

01361504   55               PUSH EBP
01361505   8BEC             MOV EBP,ESP
01361507   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
0136150A   85C0             TEST EAX,EAX
0136150C   75 13            JNZ SHORT 01361521
0136150E   813D 70793601 00>CMP DWORD PTR DS:[1367970],400000         ASCII "MZP"
01361518   75 07            JNZ SHORT 01361521
0136151A   A1 70793601      MOV EAX,DWORD PTR DS:[1367970]
0136151F   EB 06            JMP SHORT 01361527
01361521   50               PUSH EAX
01361522   E8 853FFFFF      CALL 013554AC                             JMP to kernel32.GetModuleHandleA
01361527   5D               POP EBP
01361528   C2 0400          RETN 4

看到上面兩個指令是不是很心動...繼續走

0040734D   . A3 68B65600    MOV DWORD PTR DS:[56B668],EAX            <-----看到40734d這個EIP麼,很重要
00407352   . A1 68B65600    MOV EAX,DWORD PTR DS:[56B668]
00407357   . A3 D8205600    MOV DWORD PTR DS:[5620D8],EAX
0040735C   . 33C0           XOR EAX,EAX
0040735E   . A3 DC205600    MOV DWORD PTR DS:[5620DC],EAX
00407363   . 33C0           XOR EAX,EAX
00407365   . A3 E0205600    MOV DWORD PTR DS:[5620E0],EAX
0040736A   . E8 C1FFFFFF    CALL SystemCl.00407330
0040736F   . BA D4205600    MOV EDX,SystemCl.005620D4
00407374   . 8BC3           MOV EAX,EBX
00407376   . E8 75D8FFFF    CALL SystemCl.00404BF0
0040737B   . 5B             POP EBX
0040737C   . C3             RETN

繼續走,會停在

005613EB     E8             DB E8
005613EC     4C             DB 4C                                      CHAR 'L'
005613ED     5F             DB 5F                                      CHAR '_'
005613EE     EA             DB EA
005613EF     FF             DB FF
005613F0     FF             DB FF                <----我們停在這裡
005613F1     15             DB 15
005613F2     84A15600       DD SystemCl.0056A184
005613F6     E8             DB E8
005613F7     BD             DB BD
005613F8     39             DB 39                                      CHAR '9'
005613F9     EA             DB EA
005613FA     FF             DB FF

這裡就不用analyse了,檢查了也沒用...但分析一下上面的binary ,什麼意思呢?反彙編一下就知道了

005613EB     E8 4C5FEAFF    CALL SystemCl.0040734D
005613F0     FF15 84A15600  CALL DWORD PTR DS:[56A184]                 SystemCl.005608F0
005613F6     E8 BD39EAFF    CALL SystemCl.00404DB8

看到了麼,最上面那個cALL我們已經執行過了,很顯然,aSPR更狡猾了,直接在殼裡執行了第一個cALL,所以oep就在第一個CALL位置:5613EB

剩下要做的工作就是恢復11個STOLEN BYTES,分析一下剛才走過的程式就可以得到,還有IAT,這些就不在這裡詳述了

這篇東西是在下午上班時抽空半小時寫的...若有錯誤,請多多包涵...

相關文章