|
编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友
7 O. Z1 B4 e$ m9 O1 I% i会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助 # F1 S3 Q) @- }% W5 a1 G0 y6 K
作者 : Detten Detten@tiscali.be : k! m5 m, V! Z) Z% f
来源 : _blank>http://biw.rult.at/; ~5 c( g$ M* m3 W1 |
+ Y7 z, x0 e* |3 S$ K6 l
翻译 : nbw _blank>http://www.vxer.com/9 l( `# K; r% ~
5 g3 k- C; z$ v6 i9 Z# T" V$ c9 c- m" C
1、前言
/ N7 y% r1 u* v( z# p9 r 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。% q, z6 z+ F7 x: P7 T
那如何来写呢?
- N2 Z& X0 _# w1 I3 ?5 U===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。
?4 x/ S% F) l5 A) e1 S' R/ ?( q1 s6 S# b" P4 }, N
===〉如果找到,打开该文件。1 r( s2 f& a& k+ m9 ~" x7 e+ j
) ^, m# |; L. \( K( D& U. i
===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。
' S' x2 X4 v" U: t+ ]% [$ z" m5 R. O! H% ~
===〉如果以上都无误,我们可以做需要调整
/ J% e" [5 p6 W7 U5 { 把文件指针移动到指定位置,然后写入新的操作码。
" V+ d3 _7 W2 m/ Y8 r( Q( H9 z& M/ t# w
===〉关闭文件,给出提示结果。
7 @4 k$ s' ]0 a" T$ z! F' _. E4 U2 _/ H c) {- f
下面找一个你破解的文件,然后开始....( I5 W# c. ?. ~) x! y* ^
6 y; `$ B7 j2 q8 v% y$ ~2、必要的API/ C, z& z6 |8 F
做这个程序需要用到什么API呢?
+ O9 C4 X+ k8 F ^5 t3 ^( s& R8 H( ^6 j- w! ?' ]2 O: H2 q
HANDLE CreateFile( # k5 @7 R9 F/ F! D0 V7 u
( S, J9 B/ W+ ~" D! H
LPCTSTR lpFileName, // pointer to name of the file 3 C, m9 l0 I& }
DWORD dwDesiredAccess, // access (read-write) mode & q G5 ~2 G/ u2 I: Q0 `
DWORD dwShareMode, // share mode
* R" G+ L$ O8 a: f) G9 E$ _LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
0 P. \+ {$ f8 t+ M. Y/ A2 Y' D) `& MDWORD dwCreationDistribution, // how to create 4 {* I/ F3 ^) M8 H# \
DWORD dwFlagsAndAttributes, // file attributes
( y* M! H) k& p+ e MHANDLE hTemplateFile // handle to file with attributes to copy 4 o$ |% _# ~8 X2 \1 Y" q
);
8 j; r) A* S# i }, _3 P/ i, r, h- C$ I/ q: v
这个API函数用来打开或者创建文件。
# U F1 d7 N, e S7 OdwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;- J. V& b, l9 s _) x
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'
/ V1 V" b8 h' j4 J3 O, z7 l- bdwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。
& o2 o( ]4 t5 g 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。
- C: s% {' c' _ 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。7 S: h: N3 u- L$ }
9 O* y M" d: W% I) [/ t6 R8 RBOOL WriteFile( 7 P M& q9 w0 I" z/ V
HANDLE hFile, // handle to file to write to " d! {" {0 A9 `9 h
LPCVOID lpBuffer, // pointer to data to write to file % o7 l# i1 a) J- z7 c6 B
DWORD nNumberOfBytesToWrite, // number of bytes to write
5 d' @0 X' y; |6 j3 G1 T" T, gLPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written 5 V7 V& b4 M! g2 d5 S0 u
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O N _' q& [9 O. n0 z% x; W
);9 \' x0 N- Y1 k0 u& N( |! W8 L
) M7 r0 \8 @! S' O% v& m" c
我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]! a8 ]9 D2 o0 g+ O. I
涉及到的hFile句柄就是CreateFile函数的返回值。 }' H+ R$ }4 J! y% u2 C; z
8 E5 E7 Y4 V F2 z' Y* elpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。& _2 W9 p3 x' Y5 Q0 ^* m: z/ F- e
1 ]( v2 i' ^5 P+ Y5 g, { Y9 ltypedef struct _OVERLAPPED { // o
9 G. n9 v% B& f% p1 qDWORD Internal; & `& ]) M- m" @8 S3 X5 g- Y
DWORD InternalHigh;
2 ?) W2 }$ R- {7 Q6 S3 }DWORD Offset;
& L) d' m3 T* r3 I3 x; w+ KDWORD OffsetHigh; ( x7 Z% C/ _2 S. G4 c; [6 O% F
HANDLE hEvent; 9 m% y/ r* M z: u2 D: P3 m8 m
} OVERLAPPED;
& M# D2 j- P6 ^' ^8 rOffset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)( J, v4 Q! S3 G- z( O; p
' H: w( n, ?3 K4 I' |( f5 ?
3、目标- F/ ~; k# e" K% @
目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) r3 e& p' S9 J9 _' y! k' U/ u P, L* C1 L
当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方:/ U; y, ^2 V# q" z- V7 T
) Q0 f; r: p( E2 H- Z: ~Offset 53Fh : 74h, 15h -> 90h, 90h7 l% q7 _/ C! L3 A" |4 u- D
2 ]" B7 V) X$ [ P9 _ n3 d 以上就是我们所需要的所有信息。
1 S/ c/ [. R( l! I+ z' x# j8 F$ T
4、代码
, e1 I( _/ `7 k% M% t2 v* w9 w' \5 ]' \: e M# G
386
' Q- }0 ~- q" Z' y0 U% m.model flat,stdcall
- S5 _# {/ b' {& koption casemap:none
' ]5 Z6 O9 s& |& uinclude \masm32\include\windows.inc
) i) F+ N- W! p8 P" r' w( Ainclude \masm32\include\user32.inc
7 y, w D% g& |4 ?include \masm32\include\kernel32.inc
* {, i4 y8 z2 ]" y% ~includelib \masm32\lib\user32.lib
. x) B6 z) _/ b# _; qincludelib \masm32\lib\kernel32.lib% U& ~5 e2 ^3 S9 F
. a$ K: L9 J# }* G W% S# z4 h" H% f2 n4 _/ K+ o& S
.data
4 Z7 T6 b' H. b& S8 W! {. EFileName db "Crackme5.exe",07 s3 `4 f% p7 D7 z6 C1 I2 U# T" o
AppName db "Crackme 5 Patch",06 ?% J" w4 K8 C
Done db "File patched succesfully !",0
! }& l& K( U& K+ cNoFile db "Can't find crackme5.exe !",0
+ o% r$ `7 }/ w8 s6 R4 Z _3 L9 T- ?ReFile db "Wrong version of crackme5.exe !",0/ _/ _7 A" m5 J: |3 S
WrFile db "Error writing to crackme5.exe !",0
% _! E% H4 Y# k: V8 jRBuffer db 75h, 15h
0 ]) V' [, j4 B/ W0 d5 `& cWBuffer db 90h,90h
+ b9 m! y( b) [2 COffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> - D# q3 v1 P) {7 _9 U6 O; ^
2 A7 m, L- S' p
.data?' Y. k4 w) O2 w7 A4 C8 E& |
# a# K0 H8 E6 h$ KhInstance HINSTANCE ?
% T/ {6 k# M- J6 pCommandLine LPSTR ?
0 c/ {9 Q" ?3 @* H% {) ^hwndname HWND ?
7 U. y8 f# f6 f' _: }hFile HANDLE ?4 t0 r: r4 J/ Z% D, o
Numb dd ?4 Y( p* f0 O( Y! G7 \
Buffer db 2 dup(?) ! J" q3 o7 O- v. ~- ]% |0 t. G
5 H* ~) w( h2 W: s# o/ v R0 K5 s) J7 ~
.const
: |; E! [8 \0 |" e: G
0 f0 l3 C- ~: f9 v5 x0 `' v2 u+ n0 H ^.code
8 o) P8 D4 m" s3 Y6 B! Wstart:
# }/ |) n t6 h' i; {! e1 l
% e! h8 @0 [$ k0 e/ ainvoke GetModuleHandleA, NULL
8 u( e( y# v9 _# _9 l+ V* Emov hInstance,eax
* E2 x7 e6 S! s* U6 q8 f! ]# T a. }
invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
' ^0 H$ u H7 `( s( B% a- o1 R
( x- j+ u/ ^: J7 s, k8 e.IF eax!=INVALID_HANDLE_VALUE
# t: y/ I) \# u. K/ h) w
+ D7 M( t2 ^# Q! {* l6 n0 m7 Kmov hFile, eax ; 存储文件句柄
7 j- v- G; Z p4 R' M. t3 ^4 k1 n1 KInvoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节
# S0 ?+ G* K, J7 n8 s# c) r3 }mov ax, word ptr [Buffer]
& | C8 a Q! [9 X- |.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)5 }5 p, [1 b, p
Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)% n+ O' f% t2 t* D ]" ~& u+ I
.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息
" a9 `. c# t0 {8 M9 P) h0 W% jpush MB_OK : s" z( h; C. ^* o7 t4 N. z
push OFFSET AppName
+ Q; O$ Q3 l) Q {4 e' g; Bpush OFFSET Done ; 弹出信息地址入栈+ d) {' u* {9 t) E% Z) m- a" ~
.ELSE ;如果返回值不是2,那么弹出错误信息( K, c* o$ J( O, M8 l& F2 K+ t& D
push MB_OK OR MB_ICONINFORMATION+ w8 u# ^5 O" g+ c5 M* Y, W( I6 E
push OFFSET AppName/ x4 Z4 V& y W6 ~* T! S v3 i% }# w
push OFFSET WrFile' f% p. w) T* M" w3 Z
.ENDIF 7 y0 p! V. {/ u" @- D
.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息# \. p# n( P& Y$ C
push MB_OK OR MB_ICONINFORMATION
9 t. P! V$ H( W+ [, |/ Qpush OFFSET AppName
; C0 h2 \; P; D1 z9 lpush OFFSET ReFile ( R, A4 {, W$ e9 ~
.ENDIF
% v' q, L$ Q* |+ F% _6 M3 d$ b7 U# O
2 C8 J# D y6 m; A9 O4 t% E5 d.ELSE ; 如果未获得文件句柄,弹出文件不存在信息
- ^6 T7 E; x) {9 }" R9 `- bpush MB_OK OR MB_ICONINFORMATION. U o* ?1 h: B$ Y5 w: {
push OFFSET AppName
1 @! K4 H- m. S+ @push OFFSET NoFile + h- j* P" ], T& R) g
.ENDIF
- H+ g6 ]! V ?4 i k3 \: V% S' z1 ^$ q3 l+ T0 Z2 E
push NULL
! j; k9 S, X+ | a4 qCall MessageBox& }! y Y9 {. O+ U) l+ U5 v- X7 {
invoke CloseHandle, hFile ; 关闭文件- N5 h$ R- i9 d. g: i4 [
invoke ExitProcess,eax ; 退出
`+ C, c4 V$ @3 T$ ]! _3 X/ B. g$ P$ D7 ?5 B
end start9 X5 Q$ [# B7 E1 \& q3 I1 k
" v6 a3 {& ^: w5 s8 k' q v- @9 ] 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。
8 D( i6 C- H* h1 [$ Z* M" e, U* A/ Q$ D( e6 p7 Q6 b
var currentpos,timer;/ S4 h4 W' Q" g( c: [
$ }9 S9 |4 ^, ]" O' b' n
function initialize()" @9 V2 [6 x% X# g# P7 \; d% K' k) \ O
{
7 X- R( K9 H9 t; etimer=setInterval("scrollwindow()",10);1 J; B2 d7 @) p
}
4 {# I* O' P; ifunction sc(){7 ^% e# W; C2 b$ }* x
clearInterval(timer);$ ]. p+ f4 O# S9 q& o
}
& P) ^, v8 s8 P2 M) G, M$ ?function scrollwindow()
: j* `3 d4 s( z/ O{
9 C0 L* I# J$ x! Lcurrentpos=document.body.scrollTop;2 D& f1 ?/ U1 L" s) F7 Y
window.scroll(0,++currentpos);
) V3 s( p4 X0 P; o# \4 fif (currentpos != document.body.scrollTop)
3 {. n7 _8 l8 M' C! Fsc();# \! x+ X( Z# u5 c: H5 S1 r7 P
}
9 H4 j& s2 s* M* _+ y7 Mdocument.onmousedown=sc
9 a0 O/ s* S1 ^) ?. G/ m' e fdocument.ondblclick=initialize
! R: P$ h0 p- e* y/ `# J7 T9 |
l7 A/ F! R- I
! x4 n# j- w; e+ t# t |