数学建模社区-数学中国

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

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






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