数学建模社区-数学中国
标题:
用OllyDbg脱ASPR 1.3x的壳
[打印本页]
作者:
韩冰
时间:
2004-10-6 10:49
标题:
用OllyDbg脱ASPR 1.3x的壳
作者:LaBBa
- l4 L& ~* i& _) R4 y: P- ~
翻译:gmh001
9 [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" _; A
OK,贴上来!!这是我第三次写这篇破解文章,第一次正在写的时候机死机了,第二次停电了。
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& e
2. 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 r
1. 找到 OEP+从内存中抓取程序
# ^5 q: A& U0 \9 b; m9 @0 z& J
2. 找到抽掉的字节
. O# }& U9 p3 ?
3. 重建IAT
) ^6 w0 D& C/ y% g/ d
4. 修正OEP
8 k% v! L# Z+ M2 Q: E6 H1 y
5. 结束
. 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/ v
1. 运行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 d
3. 按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/ M
7. 为什么??总是用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: W
9 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/ E
7 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 q
9. 重点!! 在OEP处看盾EAX值(CPU窗口的右上面)
7 Q2 }' g2 d+ r. C$ B7 Z; K" [9 F
EAX=57E318
8 ]' G! l' v4 Y$ M( l
记住它,以后会用到它的。
6 W" d5 }/ J9 d `
0 i- ~3 G/ T. o* ^, y
10. 打开 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 b
7 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 E
8 `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 S
9 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 @+ Q
5 y) B! O7 V( k
1. 首先运行软件,等候它被载入。
. \, r3 f6 l% Y/ |1 i
2. 运行Imprec,从列表中选择进程。
' u. V) _2 @) h) d7 }7 x" x
3. 按"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" U
8 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/ F
1.打开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& q
2. 打开ProcDump/Pe-Edit ,点击“Pe-Edit”按纽载入重建的新文件,修改入口点为:57ea55 (因为抽掉的字节)
, H8 d% V' a3 O9 i/ N
1 E& o1 f; q: }3 U# N* u) m* j
3. 如果你现在试图运行程序,它会死掉的!!
1 K2 ]+ M6 B, K# i" N
% h: M3 @) B1 t) q: W* p8 ?+ u
4. 打开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 ^$ e
11=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/ g
1 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