• 标 题: ASPR1.2x新版本的脱壳初步探讨 (5千字)
  • 作 者:bailei3
  • 时 间:2003-06-11 16:07:30
  • 链 接:http://bbs.pediy.com

这里就以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,这些就不在这里详述了

这篇东西是在下午上班时抽空半小时写的...若有错误,请多多包涵...