|
作者:jwh51 来自:看雪论坛
( l1 ~3 h% f; r& ?) b3 d1 A
+ w' X2 l; H6 C) d. ?新版ASPR的加壳方法有了一些变化,用工具是脱不了了,所以写了这个,给大家一个简单的解决方案. 7 K4 t: e( \; l2 P2 F# O$ E( s
用OD载入,BP IsDebuggerPresent,F9,停了下来:
4 F% i' }3 ~3 m% @" i77E52740 > 64:A1 18000000 MOV EAX, DWORD PTR FS:[18]
( s8 ^- D- ?5 Q/ N. R77E52746 8B40 30 MOV EAX, DWORD PTR DS:[EAX+30]
) D/ t3 Z% v3 e' Y5 C" D: U77E52749 0FB640 02 MOVZX EAX, BYTE PTR DS:[EAX+2]
1 I6 R) ~) h3 R- f2 D77E5274D C3 RETN
3 p% v- l' C. l+ J
+ n: m* V% n( C' F8 [) A' fF8,到RETN之前这一行,看看[EAX+2],我是7FFDF002=01,
7 j" n5 E7 a" b0 x5 p) W重新载入,把7FFDF002值改为0(这样可跳过ASPR对程序级调试的检查),F9,这时有异常会停下来,这时就用SHIFT+F9过,大约30次左右,你可看到这样的代码
$ d7 ~3 A1 L# J00C23D5F 3100 XOR DWORD PTR DS:[EAX], EAX
3 S0 R8 G; @+ I+ t) q/ W00C23D61 64:8F05 0000000> OP DWORD PTR FS:[0]
5 ^2 g5 I/ F/ O# r2 p6 p1 T$ e00C23D68 58 POP EAX
) j$ v* R4 E ?/ l00C23D69 833D BC7EC200 0>CMP DWORD PTR DS:[C27EBC], 0
9 V# @6 V/ @, Q! Y9 o00C23D70 74 14 JE SHORT 00C23D86 & e! H0 L, \6 M( S+ G& d6 ]- P* a7 K
00C23D72 6A 0C PUSH 0C 6 f" k4 m, d- S9 ~1 a
00C23D74 B9 BC7EC200 MOV ECX, 0C27EBC ! e1 T& U5 b9 ~: ]- N) q) c
00C23D79 8D45 F8 LEA EAX, DWORD PTR SS:[EBP-8] " o4 X+ S& \, V0 ]" ?) N
00C23D7C BA 04000000 MOV EDX, 4
' _5 e$ U3 _- S, I00C23D81 E8 8ED2FFFF CALL 00C21014
5 ]7 l: U! @, j, v" J00C23D86 FF75 FC PUSH DWORD PTR SS:[EBP-4]
) n8 N+ i0 ^3 a* E4 T00C23D89 FF75 F8 PUSH DWORD PTR SS:[EBP-8]
- p( s3 O, \* G9 F, F' @5 p00C23D8C 8B45 F4 MOV EAX, DWORD PTR SS:[EBP-C] 6 d- w9 f4 q9 q" B
00C23D8F 8338 00 CMP DWORD PTR DS:[EAX], 0
# x) j3 _7 e4 E00C23D92 74 02 JE SHORT 00C23D96 . Z5 K8 ^/ m5 l2 ?) _
00C23D94 FF30 PUSH DWORD PTR DS:[EAX] 6 {- z6 u% D4 z |6 E# I
00C23D96 FF75 F0 PUSH DWORD PTR SS:[EBP-10] : q! `! i1 ~8 v- f
00C23D99 FF75 EC PUSH DWORD PTR SS:[EBP-14]
' N9 x+ m5 W: `* `2 m n8 v00C23D9C C3 RETN
9 l1 L( s |" H/ J `5 `3 y这是典型的ASPR的最后一个异常。(两个JE加个RETN),这时不要SHIFT+F9了,不然程序会运行的。要用SHIFT+F7进入。这时会停在系统空间。用ALT+M打开MEMORY MAP,找到SYSTEM CLEAN所在的位置,第一个SECTION如下.
9 O. }2 M( @% h; d9 @$ zAddress size section contains
1 @4 _" V$ {& o! b/ R00401000 00161000 code
% k% [: T. B; [0 q5 O* k l. f- Q在上面这个地方“右键—>set memory breakpoint on access"下个内存断点.然后F9运行,呵,你可发现,我们已经从壳的迷宫走出来了,(这个方法,再也不用象以前那样小心翼翼的F8F7了.)程序停在这:
1 b- l1 w8 f$ J- R00407278 - FF25 2CF35600 JMP DWORD PTR DS:[56F32C] ) B, s/ [4 @' x6 }$ q
0040727E 8BC0 MOV EAX, EAX
+ Z& P- t1 ^7 q% y* A00407280 - FF25 28F35600 JMP DWORD PTR DS:[56F328]
' w: n7 H2 N1 f! Q+ O00407286 8BC0 MOV EAX, EAX
5 B9 l. U+ Z! J/ ]00407288 - FF25 24F35600 JMP DWORD PTR DS:[56F324]
( f" Y, L- S7 u6 z+ o6 Z4 Z0040728E 8BC0 MOV EAX, EAX
* `! P- X- O$ }9 A00407290 - FF25 20F35600 JMP DWORD PTR DS:[56F320] 2 }* [ q' C& i
00407296 8BC0 MOV EAX, EAX
L; A) |2 D. _' X" r00407298 50 PUSH EAX
4 c& b& X/ x# T00407299 6A 40 PUSH 40 # l, p' b( i" U% K
0040729B E8 E0FFFFFF CALL SystemCl.00407280
6 ~0 j* C# M0 [* A004072A0 C3 RETN
* H# G; n9 Q& V' l4 V这并不是程序的真正入口(入口位还远呢,这是ASPR的新特点),但是它给我们提供了一个很有用的信息,那就是IAT的位置(新版SAPR无法用importREC自动搜索IAT了),所以我们可以先 D 56F32C,让内存区定位在这里,去掉内存断点,F8,又回到壳中,不过没关系再按几下F8就又可从壳中回来的,回来后我们来到这:
& L x, B0 \" |' Y% M0040734D A3 68B65600 MOV DWORD PTR DS:[56B668], EAX ; SystemCl.00400000 , m. j' A) \" M) S; ? W7 y e
00407352 A1 68B65600 MOV EAX, DWORD PTR DS:[56B668] ) J. k! o [* K( ], |
00407357 A3 D8205600 MOV DWORD PTR DS:[5620D8], EAX + i) c( r6 `' P# _) Q
0040735C 33C0 XOR EAX, EAX
3 f1 h) t! M5 P, m0040735E A3 DC205600 MOV DWORD PTR DS:[5620DC], EAX
' j5 y) q$ d, [# D' q" `! Y7 D: a00407363 33C0 XOR EAX, EAX 5 K( R% T+ B7 O
00407365 A3 E0205600 MOV DWORD PTR DS:[5620E0], EAX 5 @. _5 d- y h8 n
0040736A E8 C1FFFFFF CALL SystemCl.00407330 ( k# |* X) L5 C% b' R2 Q
0040736F BA D4205600 MOV EDX, SystemCl.005620D4 ( f' l6 y# z" S! C
00407374 8BC3 MOV EAX, EBX
) F' ?) x2 E- H5 q! I00407376 E8 75D8FFFF CALL SystemCl.00404BF0
; V* ? s- Q% c o( V6 L* W! L0040737B 5B POP EBX * E% R5 R2 A, T9 H
0040737C C3 RETN ; ]2 r( |9 Z+ Q+ d9 r# z
到这里我们要做3件事: ) P" D8 A" C: Q+ d
1.拿出LOADPE,把这个东东从内存DUMP出来DUMPED.EXE. : F% \ O$ }, h2 ^4 q+ v
2,记下EBX的值560d08.
8 z1 F/ _9 v2 L6 w9 J9 l0 f& {3,先修复好引入表,修复方法如下:
) P# j% p j! G4 z+ K看看内存区在56f32c一块(别不记得为什么在这里了,上下找找,很快就可发现IAT的位置:56F21C--->56FBA4,大小为56FBA4-56F21C=988, 0 ^' H) a" G- t6 J
打开importREC,选中程序IAT的RVA填入16F21C,size:988,按下"获得输入信息",这时可找到一些指针,但还用很多无效,按"显示无效--->追踪层次1(分解),可修复大部分指针,还有一些得手动了,不过我发现用新版的ASPR插件竞可以全部修复(试了几个都可以,所以也就偷懒了,用ASPR插件修复,还有几个无效的指针其实是垃圾把它们CUT了(看看它们的值就知道是不是垃圾了).然后FIX DUMPED.EXE为DUMPED_.EXE.
& Y# R5 W+ w/ a) N/ c+ n下面就是修复入口处了. 5 D; @ T* u& q5 A* [# P
3 K7 h8 B: u' M2 z回到原程序.按几下F8,过了RETN我们就来到程序入口了. ( k$ h. | g7 p8 n# d. W
005613DF 0000 ADD BYTE PTR DS:[EAX], AL
6 X$ _$ s8 E$ t/ o( i5 p. W8 m005613E1 0000 ADD BYTE PTR DS:[EAX], AL
2 V2 }$ S i4 A- F; |005613E3 0000 ADD BYTE PTR DS:[EAX], AL
0 w- }3 c- g! b: k005613E5 0000 ADD BYTE PTR DS:[EAX], AL " ?7 s5 C# z6 J% @7 d( F, {# ?
005613E7 0000 ADD BYTE PTR DS:[EAX], AL ' W' Q B- u k
005613E9 0000 ADD BYTE PTR DS:[EAX], AL
1 {7 I3 D6 O+ a8 }5 Q" i005613EB E8 4C5FEAFF CALL SystemCl.0040733C / O& Y- i6 I% G$ c. m3 b/ A- ?5 I0 z
005613F0 FF15 84A15600 CALL DWORD PTR DS:[56A184] ; SystemCl.005608F0 # Z) Y2 b" i7 e0 B
005613F6 E8 BD39EAFF CALL SystemCl.00404DB8
# J' D4 O( R* z% L8 n5 X005613FB 90 NOP ! Z* h, O8 P1 `! S# W# q& \, t
程序是停在5613F0,可以断定前面的CALL已运行过了.而且入口处和以前一样被 5 O$ a. m8 w; n! {( }0 _
改成了0,我们要把它补回,但是新版入口的代码似乎不好找(如果谁发现更好的方法告诉我一声:-),不过看这个特点
, G7 X X& L! A- n5 r( x是用D7写的,D7的代码特征是
% d! w% y" @) z; \PUSH EBP
1 s6 R6 e! { L' dMOV EBP,ESP
! s$ J% I% A; qADD ESP -10(也可能是ADD ESP -0C) 9 a! e6 I5 O5 U: U3 y
MOV EAX,****** 4 l0 Q, e' A3 `8 `7 S
所以只要找出最后这一句MOV,EAX,******,中的*****值就可以补回去了,还记得开始要大家记做的EBX的值560D08吗,它就是这里的值.这样我们就可以打开DUMP出并已经修复引入表的程序DUMPED_.EXE,把这一段代码补回去了,补完后是这样
9 y: ]2 g4 V0 s) D8 k' S( K005613E0 > $Content$nbsp; 55 PUSH EBP % D% _6 k6 |+ G, ~0 }9 W
005613E1 . 8BEC MOV EBP, ESP
F# y2 v5 O$ d% R005613E3 . 83C4 F0 ADD ESP, -10 ' A2 d' s. \/ ?
005613E6 . B8 080D5600 MOV EAX, jjjj_.00560D08
3 Q- P3 Q o e8 ]) ?- w005613EB . E8 4C5FEAFF CALL jjjj_.0040733C
; H/ f" x) T5 P4 f005613F0 . FF15 84A15600 CALL DWORD PTR DS:[56A184] ; jjjj_.005608F0
' B l; |4 m* J* X/ q# i2 r! R005613F6 . E8 BD39EAFF CALL jjjj_.00404DB8
; k' W& p0 P% z: t; x2 n; J6 _/ @保存后用LOADPE把入口点改成1613e0,OK,程序可以运行了.脱壳完成. ! M5 m, l/ l# L
|