数学建模社区-数学中国

标题: 用OllyDbg脱ASPR 1.3x的壳 [打印本页]

作者: 韩冰    时间: 2004-10-6 10:49
标题: 用OllyDbg脱ASPR 1.3x的壳
作者:LaBBa - l4 L& ~* i& _) R4 y: P- ~ 翻译:gmh0019 [2 R* U$ x3 y$ w( X& S 软件: System Cleaner 4.89 Build 110 - e F5 r" ^& d1 l9 L Url : http://www.allerasoft.com/products/systemcleaner/ % S) C0 l7 F$ c" m 4 j0 ~" P5 H; f# k前言, f& f$ r& V& v8 _/ F1 G% T ================== 8 l$ F# \0 h* {% H" _; AOK,贴上来!!这是我第三次写这篇破解文章,第一次正在写的时候机死机了,第二次停电了。 4 y O1 j0 P+ Z) v# b (呵呵,运气有点背啊…)$ E; J% C, ]7 i' }2 m 现在… 3 b2 v9 g; _% i4 I* t. }" A2 \, O! F+ k+ I0 Z" _: t 这篇文章讲述如何真正快速简单的脱掉ASPR 1.3x的壳,并且找出被抽掉的字节… $ T; u+ P( P! C4 Q. |0 V0 J 并且不使用SoftIce、IceDump和 /tracex!用什么?使用OllyDbg ! & G( @& f7 |6 y* e5 j6 c 7 [: ]; B' m. W7 S+ ^所需工具 7 D+ I6 m/ o3 C, |% F* v5 f _================ 0 e4 F2 R6 P# Y( b* r6 H 1. OllyDbg 1.09b2 or newer . k2 m2 i1 c- ~: H: w$ _: x& e2. ProcDump(G-rom)/Pe-edit(y0da) & L1 m7 j- a6 w1 ^ 3. imprec 1.3 (MackT/UCF)(protools.cjb.net) , G0 ~. L8 U" V3 `4 N2 Y 4. HVIEW / Hex Editor ) s. b" a% E3 E# _ % ^0 x2 l( Y( S* W; Z. I脱壳步骤 & m1 N* ~ ], R ======================= 2 s2 y- u. \7 y$ y2 r1. 找到 OEP+从内存中抓取程序 # ^5 q: A& U0 \9 b; m9 @0 z& J2. 找到抽掉的字节 . O# }& U9 p3 ? 3. 重建IAT ) ^6 w0 D& C/ y% g/ d4. 修正OEP 8 k% v! L# Z+ M2 Q: E6 H1 y5. 结束 . Z7 Y2 y* Q2 s; C 3 s( S7 m) m0 w( O* h+ ^: E6 Q * z/ J7 p; l) I==================================== 5 k- c* D+ H* \6 H+ |第一步—找到 OEP+从内存中抓取程序 7 s; L, D) g9 u+ R, I: c ==================================== 8 M2 E/ G1 l$ l0 [6 l1 s d K" ?0 I 0 y1 K' m1 i! Z/ v1. 运行Olly并载入应用程序(如果有提示就按 YES!) ( \( P7 U: }* R/ @9 U 2. 现在按F9就会在这儿中断: 8 V$ @* Q2 m u; p8 D7 W {7 z2 b. n, d$ U 017E3414 3100 XOR DWORD PTR DS:[EAX],EAX 〈-我们在这儿中断! $ d& K0 x& M, ?. `# |: g 017E3416 EB 01 JMP SHORT 017E3419 , o, z7 ]4 J7 p, @6 q' r 017E3418 68 648F0500 PUSH 58F64 ; N q" @3 T4 k: T k1 D6 d( {4 z 7 p! S9 I7 ]9 u( r+ E( i' F( Z0 v) M 为什么Olly会中断?我们不用设断点吗?! + \4 G* [9 R& p. v* F' X; [呵呵,Olly在每次进入一个新模块时都会中断…我们将继续使用它!! + q! |# e' ?* B- o Q7 h ! @# I: @% G: J& F7 E9 d3. 按Shift+F9,这样Olly会继续运行直到遇到一个新模块。 & t' v* T5 {( ? 4. 按Shift+F926次后我们将到达这里: $ e7 f- n1 @2 Y: c5 @2 f ( G, o8 z/ \' [9 v 017E2D7A 3100 XOR DWORD PTR DS:[EAX],EAX〈-我们停在这里 / a& A5 d3 R% E4 F. N) f! m 017E2D7C 64:8F05 00000000 POP DWORD PTR FS:[0] 〈在这里设断点 y) R1 W3 r- P% r) ^. }3 ~! O- t 017E2D83 58 POP EAX $ r1 n4 H! ]! I# J& V2 |2 P 017E2D84 833D 806D7E01 00 CMP DWORD PTR DS:[17E6D80],0 , E! _! ^4 d+ |$ U 017E2D8B 74 14 JE SHORT 017E2DA1 / z9 C1 K4 J3 w 017E2D8D 6A 0C PUSH 0C . c1 @% I! B' c3 D0 { 017E2D8F B9 806D7E01 MOV ECX,17E6D80 ' F6 {6 e6 Y) S7 d8 {8 c2 v 017E2D94 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] 8 d6 e& `5 O, S 017E2D97 BA 04000000 MOV EDX,4 : f7 \ [; r% J4 A3 J5 \ 017E2D9C E8 EFE0FFFF CALL 017E0E90 ! t, B1 Z% \5 f0 h9 a 017E2DA1 FF75 FC PUSH DWORD PTR SS:[EBP-4] - P( L4 A3 \, c$ r3 [ 017E2DA4 FF75 F8 PUSH DWORD PTR SS:[EBP-8] 1 c7 ^ ?& x* C 017E2DA7 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] & w# S9 g$ ~# ]1 o) T 017E2DAA 8338 00 CMP DWORD PTR DS:[EAX],0 . |% X, A2 n' H& W$ D9 Y/ |% O 017E2DAD 74 02 JE SHORT 017E2DB1 / j! N+ z9 s9 ^8 B 017E2DAF FF30 PUSH DWORD PTR DS:[EAX] 7 h1 s- J3 R2 o- O% A0 f+ m. q 017E2DB1 FF75 F0 PUSH DWORD PTR SS:[EBP-10] " p2 J- A. r! j9 K8 n% J1 I- D 017E2DB4 FF75 EC PUSH DWORD PTR SS:[EBP-14] 1 X5 P" O1 {6 B+ J+ y9 r1 q 017E2DB7 C3 RETN ) E1 q2 K1 l. ~1 i5 t( e : l) i9 t) ~) e+ t4 \如果我们再按一次Shift+F9,软件就运行了…千万别这么做!! 9 o) Y# |$ t0 ]+ l( d% g1 _8 f# D% L- U- C, j% L7 g5 }- J 5. 现在我们向下移光标,到这里: , z. t# I0 Q' O/ ]+ T# `1 y 1 o6 O3 R+ q* X4 _( ] 017E2D7C 64:8F05 00000000 POP DWORD PTR FS:[0] ; Q J7 A& ?* Z+ k1 ?1 g( p* K( _5 ]7 ~ Z! v9 K: T6 w 按 F2(设断点)。 / j3 F, c2 m' A' q# g: T; y 再按Shift+F9,Olly就会在断点中断。 % n5 _, x- O. o% w$ Y $ O4 ]$ Q7 ]' }; Z- ^6. 现在按F8单步追踪,执行RETN将会到达这里:! `( j8 I0 Y( B" q9 Z ( ~; o3 }& ^! J n& t 017F4EC8 E9 080A0000 JMP 017F58D5 〈-在这里 . |2 A+ h% [2 a- y- m7 K ! a8 U9 \ q8 p- h! i 按F8执行这个跳转… 0 T; M! `$ t* _. N- y! O5 F现在我们来到这里:4 i9 ?- ^6 Z; B* q- x 017F58D5 D3DE RCR ESI,CL 〈-停在这里 ! ~; f6 U% `/ k9 d: ~# N& q* v, S 017F58D7 B9 7D966271 MOV ECX,7162967D - M2 I, r( k: `5 N6 x& n 017F58DC 81C1 38F10A23 ADD ECX,230AF138 5 `: k3 U% w& x3 w) q( A% I 017F58E2 D3EE SHR ESI,CL K; b. ^3 u8 U* F3 z6 Y4 Y1 _ 017F58E4 BA 9ECC7376 MOV EDX,7673CC9E * a+ v0 Y5 ]; r3 F% W. z 017F58E9 81EA C56EFFD4 SUB EDX,D4FF6EC5 ' q4 h% u- E5 {, n 017F58EF 81F2 B7104902 XOR EDX,24910B7 + x/ ?8 Z3 {. A( g3 k6 F L 017F58F5 C1CA 94 ROR EDX,94 * p6 m \/ u; u7 W+ O- ?: g4 q 017F58F8 8BF2 MOV ESI,EDX ! h2 b& L8 P4 D E 017F58FA 81EE 87D851D2 SUB ESI,D251D887 % w3 P' i( z' T, L 017F5900 C1CE B0 ROR ESI,0B0 ) N; B( q& w7 a% O+ B% ? 017F5903 8BC6 MOV EAX,ESI . w$ u- R" G9 P6 A7 M% h% T6 A 017F5905 C1C8 28 ROR EAX,28 9 Z% b; @' P' i2 l 017F5908 53 PUSH EBX 8 }+ l0 t$ m# i- Y2 ~$ y 017F5909 5E POP ESI O" _! x$ M( ]; C! U9 E+ C0 u( _ 017F590A 81C5 974FAF73 ADD EBP,73AF4F97 ( C. v( y' F6 @2 S3 Y# [ 017F5910 BA 048A9178 MOV EDX,78918A04 # M# U( w' R# l5 q5 Y3 _- f1 g; @ 017F5915 F7D2 NOT EDX O& b1 x5 s/ M& v- i, Y 017F5917 F7D2 NOT EDX ! ]9 Q9 m( Y- h( g F2 s 017F5919 81C2 FC756E87 ADD EDX,876E75FC & a# t* d2 U1 O; J 017F591F 8BDA MOV EBX,EDX 1 Z( y; y) o" D0 n3 n 017F5921 41 INC ECX------------------------- $ ?1 f6 d# p- S 017F5922 8BD9 MOV EBX,ECX | 9 {/ r; Q- C# m9 k4 B 017F5924 D1C3 ROL EBX,1 | a Realy Long 4 |9 q: `+ w: x 017F5926 81F3 A38FD7AC XOR EBX,ACD78FA3 | Loop ) t, _# J# B& Z& r7 N- P4 A! g 017F592C 3BD8 CMP EBX,EAX | 1 A6 ?% G, v2 H9 C+ M. z' S 017F592E ^0F85 EDFFFFFF JNZ 017F5921-------------------- ( X$ N7 x# u" y( `' ?3 H. x* A7 o 017F5934 8BC1 MOV EAX,ECX 〈〈-在这里设断点!! ' }0 o- z V* E2 ^; _5 { 9 g2 g( D& z+ F. d& } 好了,我们可以不用通过按 F8 来追踪整个循环!!我们在下面的指令上设一个断点: + _: h8 W$ d( @! } 8 x8 ?& c; h2 p% f0 x" A 017F5934 8BC1 MOV EAX,ECX . ]) ?: _2 h5 o & P6 M4 i/ V' Y& ` 设置断点后(F2),按F9(运行),将会在断点上停下来。 3 Q1 E& E# g. _ " q5 ?* w: r2 |) N- N- b/ M7. 为什么??总是用F8 / F7追踪??!! ( \' N2 d$ `' C+ o. h' }9 N 好吧…不!!% J* e: ^( B. ^ k Olly里有一个很好的功能:调用命令行。 8 \% Q. o! q5 V; s* ~) k 从菜单里选择:Plugins->Command line->Command line ! y$ |1 W( ?4 b4 ~8 `; V: W9 S! ]" ~( S& c& P9 @$ o0 y 现在我们将写一个条件追踪命令! : K. \4 U A& y4 v: }# u+ T YES ! Olly有一个追踪命令!它调用-TC-条件追踪- C4 T4 C4 X5 j0 @! j/ \" k' v 它将会在条件表达式为真时中断! 2 ~) b) M+ Y% Z( X; a: ] ) B6 e) k6 k( N, E& k8 R( `这样…在文本框里写入:TC EIP<900000 9 y1 Y. ~! I/ e1 o- O 按Enter键。 " n5 p, [' F0 F5 F6 z在窗口的右下会出现:“正在追踪” : v, W4 n# R9 R: g/ E7 Z7 u, [. l/ B2 o; |5 b0 H 我的机子慢,花了大约8分钟(350MHz) - [1 V+ z' v( |. o3 X: ?* f; j7 ?- K在另一台较快的机子上花了2分钟多一点(900MHz Celeron) ' j' o1 i1 G/ C* B" M7 P 7 j: o+ L3 [9 r 8. 追踪完成后中断在这里: 9 A( q9 u& N" L1 L- L 3 n3 A2 V+ X. @6 S2 a 0057EA5B E8 DB E8 # ^( g7 C2 T& ?1 N) s. i 0057EA5C 00 DB 00 7 ]/ b) W C6 C/ E- b) |* p" c0 d 0057EA5D 8A DB 8A 3 ]& U7 v$ u6 L% X. { 0057EA5E E8 DB E8 ; H) L, l5 d( u% I* I0 `; A3 {+ m 0057EA5F FF DB FF ! Y! P |; h. {( Q- u! e5 `, p: O" U: g- w9 D 嘿!! i Dont See Shit !!这是为什么?! ; {% x& f! O% ~噢,Olly没有分析这段代码,实际上我们并没有真提停在OEP上! ' I; J" q. g( a3 ~ m! \ OEP=57EA5B ( I3 }% D2 g3 w & ^7 g; }: I4 v! E5 q9. 重点!! 在OEP处看盾EAX值(CPU窗口的右上面) 7 Q2 }' g2 d+ r. C$ B7 Z; K" [9 FEAX=57E318 8 ]' G! l' v4 Y$ M( l 记住它,以后会用到它的。 6 W" d5 }/ J9 d ` 0 i- ~3 G/ T. o* ^, y10. 打开 ProcDump/Pe-Edit,完全抓取进程。3 N1 W! k& \; h/ Z/ d 4 d& G3 M \2 R6 r0 @* j5 U' E9 ^ =================================== k; m& N1 m3 p/ c! T/ s% { 第三步-找出抽掉的字节= ( S# p2 v8 V% `=================================== * ~) A/ f/ O6 i % r* M/ z; J* I* ]5 ^. |找出抽掉的字节有三种方法: 5 Y f/ u( V+ M5 E$ w, \" C) _4 N/ @# Y- d- n/ D. d: G 1. ASPR会执行抽掉的字节,象下面这样跳转到OEP: ; b' ]* U" H& Q6 d' b' c5 r9 R % h! d3 ]5 m3 G& Y* A" L Stolen_Bytes_1 ' `" c; }+ Y' D$ R Stolen_Bytes_2 % m5 B3 q! `+ u5 v; o Q Stolen_Bytes_3 7 v$ M/ p3 i4 u% l& a3 J3 g ..... 9 c3 `# n: c6 z ..... 0 E# R: X( D- R5 D- n2 C PUSH_THE_ADDRESS_OF_OEP 8 i E+ p0 Q x% u, L2 j4 ~) V RET_TO_OEP 0 s. t) P: R5 _+ K: O & M" }- f! r5 [3 d( k" t0 d( ?2. ASPR首先保存抽掉的字节,然后从OEP处还原,再象下面这样跳转到OEP: j; d5 L ^+ T ) ^7 l5 e/ F0 l- | Stolen_Bytes_1 % ~: A0 T. M. E1 e- B Stolen_Bytes_2 . t6 a0 M" I8 O' ~ Stolen_Bytes_3 ! l9 z. z% X3 F6 S6 Z; T u n* n& S6 A) ^ PUSH EBX - @5 Y% W; h. Q- ^( g8 n PUSH ESI ; y* }$ u# V( @7 } PUSH EDI 0 ~# H& _ _2 L ...... 2 ^& |. H4 H# S4 L8 z ...... / q' H+ F' z& w+ ^# y2 s ...... , m- W( {) x0 `! l REPZ STOSB 〈-还原字节 # A' ~$ y+ d' ?* k% Z$ E POPFD 3 F4 B$ v# [( H' K POPAD + o* \6 G E) f3 ?$ y# N' D- v JMP_TO_OEP & L; b* g% M+ d/ I3 b7 p; J/ h7 j/ W ? 3. 没有抽掉的字节时,只执行PopAD指令和跳转到OEP。 8 g: g# I& w. T ) U$ O6 g- c' p% G那么我们怎么处理它呢? 7 a( }. h2 N" ?% `! W* R+ S看看ASPR在跳转到OEP前的最后几步是什么。这需要查看跟踪日记。 9 X) w; x. m& ?# m5 ], |5 { 太好了!Olly可以使用"Run Trace"功能来得到一个 跟踪日记。# t9 Q# Y: w) s# ^( w6 Q 这样…选择菜单: View->Run trace 4 f _8 S, B( y# o. c+ Z+ E 现在我们看见一个新窗口…跳转到最后一行的前一行,你会看到CPU窗口也变为同样的地址,象下面这样: : ~; E( Z: Q6 I* _; |" {" z2 r 1 J& c5 P5 l* p4 |8 z5 r: t 017F5779 F3:AA REP STOS BYTE PTR ES:[EDI] % L3 g# W) K( F( o+ ] 017F577B 9D POPFD ; f# _6 J3 B$ U8 l2 o 017F577C 61 POPAD 4 H* O/ T, @( Q 017F577D -E9 D992D8FE JMP SYSTEMCL.0057EA5B 〈-OEP的地址 9 b3 G. V) @1 X8 A+ M' `6 X8 C7 f& g8 I T: U+ _5 R8 P我们用第二种方法对付它!!+ P6 L0 y8 q2 v6 \ : z* Y; {- B9 G2 ]) w) s v上面的内容我是在 winXP下发现的,不是 win98:: " l9 G% M2 F6 {% [8 B在CPU窗口里按 Ctrl+S(搜索命令的次序) / P- U' t' x! _ ?0 q ~+ ? 写入下面的: 6 }' K6 G8 p( s: o# q/ S& n( t& J2 E2 @1 m PUSH EBX % J5 O% c" h4 S; P PUSH ESI % B" F, |$ a2 u$ `& @- o1 p' ^ PUSH EDI 7 U) `# s" b3 E8 `4 c/ T1 l+ q1 n) S 你会发现:6 C6 p+ j9 x% w % y8 A! M2 R4 F( L5 ?# l 01029227 0055 8B ADD BYTE PTR SS:[EBP-75],DL 1 _6 R0 Y5 V* A5 z& _ 0102922A EC IN AL,DX ; I/O命令 + s% Y! |, i- } 0102922B 83EC 54 SUB ESP,54 ; ]3 }" x4 x: h% o. }. J; `2 F 0102922E 53 PUSH EBX , Y- l: n( }0 N' h) O- S1 x6 ~ 0102922F 56 PUSH ESI - _! t5 _- a* ]- {9 x i5 X; t 01029230 57 PUSH EDI % ^, U6 \* H& k9 i" t8 _0 I. _ |, Z 01029231 6A 11 PUSH 11 + v- Q. c# k' X5 z" I7 R; a) A1 R+ \8 L" [% F 忽略 "00",你会找到抽掉的字节:55,8b,ec,83,ec,54 ! V: e7 o: d( t3 X$ {& p 记下它们,以后会有用的… ; X; d- n$ [7 S9 X) k) X6 z$ V4 g 关闭OLLY… % v! i+ ^8 g. ^( ?: z# Z目前是不需要它啦… $ k$ w2 z! Q- ^2 S 0 i( N# O1 A3 I: e' i" b2 | z w+ h) S/ A: ~' |, U- f ============================= 1 n. V' o0 |1 G- W! ]9 i" @. r第三步-重建IAT=" q+ t/ ^) V! H& x9 }- q$ [ ============================= L1 j7 S0 T5 T1 S' _" A @+ Q5 y) B! O7 V( k 1. 首先运行软件,等候它被载入。 . \, r3 f6 l% Y/ |1 i2. 运行Imprec,从列表中选择进程。 ' u. V) _2 @) h) d7 }7 x" x3. 按"IAT AutoSearch" ' U. x" o. f$ [# { 4. 把大小从"BC"修改为1000(BC太小了!!) , A$ T9 I( G' B* N* s 5. 按"Get Imports" / D. b: h' T. O9 g+ Z7 [% y 6. 按"Show Invalid" $ C( T1 u$ D& c; _( `8 v 7. 在显示无效的项目上右击鼠标,选择"Trace level 1" 9 `; [9 U: Y! t& [, }% X* f+ H, D 8. 再次按"Show Invalid"…现在我们应该得到下面的东西: 4 [$ F9 r. S) \+ i" U8 G4 q3 j" ~! g) x( \ (从保存的树中剪切) 6 I- D& u/ J8 t b2 ]/ Y' L FThunk: 0019E258 NbFunc: 00000400 A9 ]( |$ t9 [1 u3 z$ W 1 0019E258 kernel32.dll 00D6 DeleteCriticalSection 7 ?' d1 i$ M' \0 d) c 1 0019E25C kernel32.dll 0228 LeaveCriticalSection 6 T+ {+ C1 n2 R3 D; U6 a& ^ ................ % b4 e( [& L! L7 n/ N 省略-省略 8 R! D, u) ]2 G& ^ ................ * E: X1 s' D. K& c+ |+ z 1 0019E2A4 kernel32.dll 01D1 GetThreadLocale 0 Y v, _' w: o( y/ D' C$ e 1 0019E2A8 kernel32.dll 01B9 GetStartupInfoA * S0 m$ P( ?4 a$ X- p 0 0019E2AC ? 0000 017E0F2C <-- good 6 k& ^6 t& L9 l. K8 v 0 0019E2B0 ? 0000 017E139C <-- good , P# q2 [6 T7 e x+ A0 U 1 0019E2B4 kernel32.dll 018B GetModuleFileNameA 8 E8 q* F' y0 l |2 L! X* m 1 0019E2B8 kernel32.dll 0183 GetLocaleInfoA 8 L" f# K0 _" F 1 0019E2BC kernel32.dll 0181 GetLastError 2 J( { `9 H: J6 a) h- b* e 1 0019E2C0 kernel32.dll 0158 GetCurrentDirectoryA : N2 c" I0 w; [& Q' p 0 0019E2C4 ? 0000 017E1408 <-- good ( P( Z" f3 n* y+ T4 k1 @ 1 0019E2C8 kernel32.dll 0133 FreeLibrary : @1 q1 b* a* K: P9 x; h 1 0019E2CC kernel32.dll 011C FindFirstFileA ' r# Z* e) v, H4 k/ h# p' s .................. - e) c, w; `2 a Z1 D& _ 省略-省略+ w/ T6 f$ t; Y J/ A .................. ; v( j+ D1 a3 q 1 0019E314 kernel32.dll 00A0 CloseHandle ' W; }' R) F7 |$ S' J 0 0019E318 ? 0000 0255A00E <-- BAD 3 }& Z4 h6 |, \! g( v$ n 1 0019E31C user32.dll 0112 GetKeyboardType 4 F& M; j h7 T7 h7 o! {0 }+ N: j 1 0019E320 user32.dll 019F LoadStringA : ]1 n/ ?" k$ P" u 1 0019E324 user32.dll 01AD MessageBoxA 6 p6 D& M/ z/ t, T 1 0019E328 user32.dll 0026 CharNextA ; }" C6 l- d; o& F: P* \ 0 0019E32C ? 0000 70F7D832 <-- BAD + ]% L& f9 u+ ^$ {0 x; a 1 0019E330 advapi32.dll 00F7 RegQueryvalueExA / G4 r1 r7 b: P 1 0019E334 advapi32.dll 00EF RegOpenKeyExA 7 ^1 }" @; J: Q; j2 i5 I 1 0019E338 advapi32.dll 00D8 RegCloseKey $ Z2 ?, U% X. ` 0 0019E33C ? 0000 F37514C2 <-- BAD 0 U- c. h1 A. t, p 1 0019E340 oleaut32.dll 0006 SysFreeString $ j! C, v8 ~% e) F0 b 1 0019E344 oleaut32.dll 0005 SysReAllocStringLen ( A0 G4 ^8 k8 E 1 0019E348 oleaut32.dll 0004 SysAllocStringLen $ h2 t' ?; ]; u% i 0 0019E34C ? 0000 4007F56E <-- BAD ' [+ c8 \- D8 A) J5 s! J8 i- n 1 0019E350 kernel32.dll 0307 TlsSetvalue 6 m4 \, D7 Z2 V: u1 p% X0 v 1 0019E354 kernel32.dll 0306 TlsGetvalue : W/ Y) G: `; E' K) c: G 1 0019E358 kernel32.dll 01E6 GlobalAlloc . k# n9 W+ v. M' h7 D, y# r 0 0019E35C ? 0000 017E139C <-- good 3 H8 c% [9 C" A& q9 |( _ 0 0019E360 ? 0000 BF57C0D8 <-- BAD 9 Q, i$ W+ _* G# B# e3 e ....................... ) W9 o; H( T9 K. c 省略-省略 D8 P! E/ @: G5 q4 b( W ....................... & A$ l, V% S. g # D8 T& R) f0 \& j好了,我们继续重复这样做… # r( l( L h2 c% z9 g5 d我们需要手工选择所有坏地址(不在压缩代码内),然后在它们上面右击鼠标,从菜单里选择 "Cut Thunk(s)"。 9 D6 t# y$ z7 h" I) U( ?* ^观察窗口在最下…那儿有好的Thunk(s)… ' \9 ?& w9 S2 H" E" w $ }" w' K8 h+ i6 v现在我们需要修正这些好字节…你可能从fraviamb.cjb.net下载过一些插件# h {: z$ T- z* o& k2 } 或者看我其他关于如何重建的文章(New2Cracking.cjb.net或者Fraviamb.cjb.net) 9 ~# u- w! k* n+ h9 E" u这是我修正的:1 [ }. N( S% \! B ! G4 y; f9 ]( D i' n. Y$ a' t 0019E2AC-> 017E0F2C ->GetProcAddress : H! M8 J# _( P4 a8 j 0019E2B0-> 017E139C ->GetModuleHandleA " N9 o! X$ }+ [; Z a y( [ 0019E2C4-> 017E1408 ->GetCommandLineA $ s. j4 X e* ]8 }8 ^ 0019E35C-> 017E139C ->GetModuleHandleA 8 t; t& B; G, ^1 G 0019E428-> 017E1420 ->LockResource 6 o$ d3 V- F+ X: E3 [' J4 S7 R' i& N& E3 [ 0019E47C-> 017E13C4 ->GetVersion 9 P" E% ^5 X9 t/ o: a/ u 0019E4AC-> 017E0F2C ->GetProcAddress & ~) k# i8 W; r; A( D 0019E4B8-> 017E139C ->GetModuleHandleA ! e; Z1 e- y! h 0019E4FC-> 017E13F8 ->GetCurrentProcessId 7 a+ l6 v3 A$ F2 m* Q0 {* z4 N7 o 0019E500-> 017E13F0 ->GetCurrentProcess $ A% u3 |6 U* D2 n" ]7 P9 _" d 0019E50C-> 017E1430 ->FreeResource 7 Q) g1 E# f7 Y3 Z9 z ^$ N% c3 ` # V# G) H6 H. r" z 9. 按"Fix Dump",选择我们抓取的文件… V& [1 W1 l' W imprec将会以在文件名前加"_"的方式保存抓取的文件。 ( \9 _: b, j& V" ] 2 w; T4 {4 x4 |" y========================= . X2 v( U8 h+ ? 第四步-修正OEP= 2 {4 w8 z, m$ j! }5 l========================= 7 [) K5 f9 ?/ {, |2 b+ Q+ R, s & V$ ]( j7 j' x/ F1.打开HVIEW /Hex编辑器,跳转到OEP的偏移地址:57ea5b处, 9 i( R9 g7 T9 e i9 L' `向后移6字节到57ea55处,用"00"替换写入 stolen bytes. 保存为新文件。 K8 t: g- `# i( d: `' S% t; ?# I % k* r! X6 o. V1 F8 n* X& q2. 打开ProcDump/Pe-Edit ,点击“Pe-Edit”按纽载入重建的新文件,修改入口点为:57ea55 (因为抽掉的字节) , H8 d% V' a3 O9 i/ N 1 E& o1 f; q: }3 U# N* u) m* j3. 如果你现在试图运行程序,它会死掉的!! 1 K2 ]+ M6 B, K# i" N % h: M3 @) B1 t) q: W* p8 ?+ u4. 打开Olly并载入我们的修正文件。 # a& H8 m2 g, V7 ^' Z' B) {* }' } Y# J6 C- D9 D- c1 V3 u 5. 停在OEP: 57ea55处,EAX寄存器的值是什么?还记得我告诉过你在抓取之前保存的EAX的值吗?它是EAX=57E318,两个值的差别意味着有两. I& r9 f/ Q O 3 g9 Q% d' t2 l3 G4 X: h 个以上的命令: that is stolen: ( ]* |" X5 o6 ?$ b" P& w. t1 W$ l# f6 H2 @ MOV EAX, 0157E318 6 C9 W! k* ]3 z- U5 `6 X! o( n 4 k2 W8 C' \$ v/ g; X. M% G x这条指令占用5个字节(你可自己在 HVIEW里试一下) 9 |! u7 u2 n# g# G. u1 @( ? B818E35700 MOV EAX, 0157E318 ; t/ }% {# f% r这意味着有6+5=11(十进制)个抽掉的字节 * A" [7 l( `1 D. g& n$ `那么,真正的OEP是: ( d9 Y D9 j. _) b9 U& D0 ^$ e11=B(hex) 3 D; [2 R: T/ D) T9 u, x7 y: |OLD_OEP-STOLEN_BYTES=57EA5B-B=57EA50 % L0 N: @# S9 u( v7 h2 u1 | OEP = 57EA50 * z' m2 N- h( j# v* _' g: z- N用HVIEW/Hex打开,跳转到新的OEP,写入: 5 L& L- v. j, f; } ~ # p( B* `" c6 R6 B- s$ H 55,8B,EC,83,EC,54,B8,18,E3,57,00 + c* t% z4 x, `' ?4 U% Y. J6 u/ g1 Y# ]. I$ B" u7 m 用ProcDump\Pe-Edit修改入口点为:57EA50 : n. M6 c- L/ O* Y/ X1 b, t 哈哈,这下程序能运行了!!! 2 _* {2 f& l4 B. L( T! N6 V收工!!!# L8 M2 ~& b0 g1 [2 }- u ; D0 B) g* Y7 G% K0 I' Z翻译后记:俺一直用Softice,没用过OllyDbg,所以有些内容不知道是否准确,再者水平有限,如有错误,请各位大虾指点!! $ x# n6 @) P. Q. s% i6 u* I , Y2 w- _* E, m& O( w3 f- Y $ h' F9 e9 h& {7 |3 O






欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5