数学建模社区-数学中国
标题:
用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) G
OK,贴上来!!这是我第三次写这篇破解文章,第一次正在写的时候机死机了,第二次停电了。
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- d
1. 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 {" P
4. 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* U
1. 找到 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+ i
4. 修正OEP
7 F( t' V3 y: y6 ~) w
5. 结束
. 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 s
1. 运行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) k
6. 现在按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; F
7. 为什么??总是用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 P
9 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 b
7 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 K
1. 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- o
2. 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; w
4. 把大小从"BC"修改为1000(BC太小了!!)
4 R J7 T# I$ V: ?* q
5. 按"Get Imports"
2 O! s. M ?" V$ A- H8 Q+ ^* @7 G
6. 按"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$ J
9. 按"Fix Dump",选择我们抓取的文件…
: e7 n" a' K4 T/ W1 u, k
imprec将会以在文件名前加"_"的方式保存抓取的文件。
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 _' I
3 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 s
3. 如果你现在试图运行程序,它会死掉的!!
' \' 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 ` h
11=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