数学建模社区-数学中国

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

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






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