数学建模社区-数学中国
标题:
用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 g
Url : 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 _* R
OK,贴上来!!这是我第三次写这篇破解文章,第一次正在写的时候机死机了,第二次停电了。
# `$ 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, ~/ S
7 ^! 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) V
2. ProcDump(G-rom)/Pe-edit(y0da)
n$ Z# d# q7 m+ o& L! d
3. 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 S
3. 重建IAT
1 K0 a" s" ?7 X3 O2 F9 D; w
4. 修正OEP
1 y }: f' }5 k
5. 结束
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' |, D
2. 现在按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 l
5. 现在我们向下移光标,到这里:
% 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% v
6 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 u
6 ^7 E2 {' v* B& R& K/ _
7. 为什么??总是用F8 / F7追踪??!!
, A) w' c8 X: i" {- @& y& K
好吧…不!!
, K# O- q2 F4 u5 `3 _) P/ Z
Olly里有一个很好的功能:调用命令行。
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' W
YES ! 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" G
8. 追踪完成后中断在这里:
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* B
9. 重点!! 在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/ T
3. 没有抽掉的字节时,只执行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 R
6. 按"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 Z
imprec将会以在文件名前加"_"的方式保存抓取的文件。
+ @( 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 b
1.打开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 h
7 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