|
编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友6 V" [9 A+ k9 K- g, T; q
会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助
. D2 w- b/ E5 F9 A! V8 ?+ R" Z作者 : Detten Detten@tiscali.be
z- ^( d; M8 H. _* b3 [来源 : _blank>http://biw.rult.at/
, `4 V9 G' O5 D+ S$ \2 \) y* N1 s1 z$ o9 a9 a' Y. U8 O
翻译 : nbw _blank>http://www.vxer.com/
- ?% }5 ?2 S1 k) ^9 N, D, \# T+ p7 H2 @ N3 i! T
1、前言
( ` J, S9 _' C7 M 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。
! N# _& s9 o3 P2 G 那如何来写呢?
9 }4 s- C& ]3 ?/ R3 p9 S& w===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。( u. z: \3 v4 n- y- a O9 K( g
A: t2 H% U+ i7 B! w
===〉如果找到,打开该文件。 F' a& E# x& L' J7 b1 u/ k
9 O Q( }7 `& A M- w3 w- A
===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。, U" r4 h" I% i8 E' G0 Z
j2 F6 u _8 \6 ~, l: `, E===〉如果以上都无误,我们可以做需要调整
7 t0 P, B3 n# X6 }8 Y& J3 d+ }; Y 把文件指针移动到指定位置,然后写入新的操作码。. ?/ _+ K9 k1 o# h: P" V
7 \$ ^1 I% R9 Z0 K2 z& j0 \
===〉关闭文件,给出提示结果。
' p& c/ h4 ~% f* |1 T9 A$ T! ?9 A) s. K) W: C6 U. d9 I8 n
下面找一个你破解的文件,然后开始....4 p2 ] t6 j9 V2 y' i; ?0 O
2 y0 M4 }: q1 ^! E2、必要的API
# j! H, y, g2 H3 {* F 做这个程序需要用到什么API呢?
( M, Z" n) S% W6 O
2 E- J& @& r) W: ^1 gHANDLE CreateFile(
' m I( r" Z' i+ a0 |6 p0 Z8 i
2 k0 W: t$ j7 r, q" K' e8 ZLPCTSTR lpFileName, // pointer to name of the file
- @5 H8 p0 d( `+ |6 ^/ X2 B7 X* LDWORD dwDesiredAccess, // access (read-write) mode 8 e: I; Q' Z8 P7 \& j4 Z' p
DWORD dwShareMode, // share mode
/ L2 b# Q- ^! Y2 ^ D" Y8 x0 W# ]; K( rLPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes # H5 ?/ w0 ?) J# x% S
DWORD dwCreationDistribution, // how to create
2 k% x+ q" g8 u5 R, h g8 ]7 QDWORD dwFlagsAndAttributes, // file attributes 2 G" b: N/ }( b7 ?+ ]7 [* V
HANDLE hTemplateFile // handle to file with attributes to copy 5 j' K J" c" A" P; p
);$ v% W- L7 F7 @' ?
, N$ P# z+ }0 D: J 这个API函数用来打开或者创建文件。
0 P% q* L- E4 C6 s1 X& l6 IdwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;
; I3 s5 F( w5 Z' y- {3 |- s$ l# T/ }dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'
1 ?5 U& x* H+ M' o& d! ~+ pdwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。
: l; H3 z! B& [; O! f- i. S2 I/ j4 { 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。
( { s, O% K! I8 O 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。
- j1 l1 P" a" S; f* s8 {4 H" {' ]9 P/ m+ p: ~ k
BOOL WriteFile(
/ m7 @( D& Z( ]7 V, y) ~HANDLE hFile, // handle to file to write to
4 o* {! u; L, o8 tLPCVOID lpBuffer, // pointer to data to write to file
/ `0 j3 o2 r+ o, w# mDWORD nNumberOfBytesToWrite, // number of bytes to write 1 n, C4 @- h2 e6 [5 s1 k8 T, e' g
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
' y3 D) q4 @- u( |3 H6 T$ f Q/ _LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O# _5 |3 W4 P/ Q) F: H, u2 H3 ^
);8 e6 ^& _7 r7 ]# q$ S/ X8 u% I# Z0 ]5 P
& s: g8 v8 _. ]) `+ g
我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]3 n- ?' d/ |" y: R
涉及到的hFile句柄就是CreateFile函数的返回值。
7 p8 G, h/ s8 h. ~! Z I2 V/ f! v/ n8 c& [* K. d4 E3 z
lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。" v1 r1 M6 ]( U# f2 `: H0 d- ^# A
- }: ?% l; T4 O+ F L$ Ntypedef struct _OVERLAPPED { // o $ X! u8 S2 z @1 P+ B
DWORD Internal; 9 d( }6 e% w/ j9 n
DWORD InternalHigh; ! h( O& e3 M+ ` A; j
DWORD Offset;
$ h" _) b" X5 p- B& ~3 ]; TDWORD OffsetHigh; & @$ |) `! Q# { E4 Q2 O
HANDLE hEvent; ' Q7 t/ [7 C D/ V
} OVERLAPPED; 5 Q! C, i4 r* ^ a& y7 h; v& S7 w
Offset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址), u. H% p0 F# l0 {" a
6 Y+ G5 }* N4 N
3、目标
% U* ] f2 r$ |) s' g3 Y 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) - \& `" N3 e. N% m" b
当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方:2 t0 i B/ M$ t7 C2 S/ h+ A; c
% R8 t8 D* A3 G- R, ^1 Z2 fOffset 53Fh : 74h, 15h -> 90h, 90h
) v' K R2 _% a/ b! U7 f# U6 e3 Y' Z3 k/ J2 H, Z
以上就是我们所需要的所有信息。* h" g$ B& p5 Z W) I
4 K1 u4 a) w# k# R1 b5 j! O
4、代码 }' g: S0 ~& Z& m
' M5 F- r8 F5 G' W1 M
386
! t8 ?1 ?" U; x( |2 `" @" D, z.model flat,stdcall. P2 k9 F6 J% I5 A/ J$ H3 }$ A
option casemap:none c5 h% S; F! f
include \masm32\include\windows.inc
0 o2 h- J$ Q, S2 R5 ~' j+ |# Kinclude \masm32\include\user32.inc. I! N& k9 T0 y j9 F6 y
include \masm32\include\kernel32.inc
% {4 l& ~% K$ F1 j# I8 O/ M. Iincludelib \masm32\lib\user32.lib$ e/ \7 U7 W5 G" c
includelib \masm32\lib\kernel32.lib4 B( L! ]/ J/ M: r1 J
7 j- i5 C5 `1 I5 b4 H1 t) o
: D1 g' z' O; Y9 M( T/ r1 R$ [
.data 8 |4 M4 Q: |, p4 d
FileName db "Crackme5.exe",0
; @5 F; _$ h+ w) D( m( C/ a, ~8 CAppName db "Crackme 5 Patch",07 o3 r( x3 J! k0 D8 @3 [
Done db "File patched succesfully !",0
" X* m$ G8 T- ~NoFile db "Can't find crackme5.exe !",0
i# ?) ?- p& D( {0 }& G7 y; KReFile db "Wrong version of crackme5.exe !",00 T1 |( B9 G) A- n6 y" n
WrFile db "Error writing to crackme5.exe !",0
2 x4 X' w' r0 H8 QRBuffer db 75h, 15h, G3 x5 c8 c* K% b" m. `: l# U
WBuffer db 90h,90h
. N' a" N4 e0 Z% c3 k" tOffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL>
) ^0 k) v) Z! O1 M' q! b
6 F) ^6 Q. _* [2 x0 d.data?# }. T% K/ k/ \
1 w5 k0 H3 _0 F. d$ w4 W- d( XhInstance HINSTANCE ?
% t3 J% A& ~. ~$ R$ ]# X8 KCommandLine LPSTR ?
+ _$ n0 s# P, ] khwndname HWND ?
0 a Z+ E" A3 UhFile HANDLE ?
) v% x9 z- O' ~4 ^. INumb dd ?& W5 t3 x6 E) Y: W; ?. s
Buffer db 2 dup(?) 8 e# Z1 F! W" T" `* j: `4 \" R
6 P8 W/ w: e" ^/ o( E5 h# `
9 `' ?7 G' U3 n) F% f
.const
S: y/ J4 S' o: F, @5 Y5 f 3 ]; P9 M# A& V8 B! z" U" S
.code5 ^2 q+ _6 Y5 G
start:
2 Y! ?; o8 ]9 p% }) k# S
+ y) C/ h1 y" a7 c" y% winvoke GetModuleHandleA, NULL
# i$ }/ y5 X4 k2 f0 ^2 y' o% L6 _( ^mov hInstance,eax
9 R. ~" }6 T' E! H9 Y% X
! K% z5 b' l3 [! Pinvoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ' R' `9 e: `- b3 K# i }
0 Z/ m3 } g4 t4 O' |
.IF eax!=INVALID_HANDLE_VALUE4 y* Y) b% W7 C5 y; o
# n1 h% R- m1 K. x& gmov hFile, eax ; 存储文件句柄" a0 ?1 s8 \1 S: d: c7 D1 _( v
Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节3 x7 S! D4 ]4 J& }
mov ax, word ptr [Buffer]
% f0 N+ z: H5 |; T% v0 d( _0 _1 b) h.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)9 |. y$ ?; X; a# _7 d
Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)2 h( G6 P1 c t6 a
.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息# l; ?8 i) s; l5 r; Z0 z7 o
push MB_OK
; t; {0 S$ i" `5 h2 S4 y% _6 dpush OFFSET AppName
% X1 j1 F( O% p( @7 k+ H0 C) r) lpush OFFSET Done ; 弹出信息地址入栈
* ^ e$ c `' |, h: E5 N; U.ELSE ;如果返回值不是2,那么弹出错误信息
# G& ~8 @. o1 ]$ x# ]2 bpush MB_OK OR MB_ICONINFORMATION v. G8 K8 {% E$ i* ?
push OFFSET AppName; c9 Y0 @" ]& D/ y$ J
push OFFSET WrFile0 S. C) m/ X( b+ I* @7 X
.ENDIF
% Y6 Q6 q* g# ~# o9 s' r; b8 V9 ?) ^.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息
) O3 Z; ^, v% C* Rpush MB_OK OR MB_ICONINFORMATION
) k. W6 V+ Q6 c4 i) z( e' xpush OFFSET AppName
1 R: ^, i' `' I4 c7 n: {push OFFSET ReFile
5 K W( s& r/ N9 _6 E.ENDIF - Y1 T, G$ k5 G' {
8 S$ B$ u8 Q4 [* T
.ELSE ; 如果未获得文件句柄,弹出文件不存在信息# I4 |0 T4 C3 s, p1 v
push MB_OK OR MB_ICONINFORMATION
. Y& L& N# h, E7 n" v- o p- Bpush OFFSET AppName( M4 I0 b: _, a( X9 K2 l& w
push OFFSET NoFile
; d( h2 r' g# J+ T& I.ENDIF/ O( r+ Q% o2 Q6 T! Y) i3 d! v
2 A& M3 l! M8 w6 ~; u. J5 Y9 F
push NULL
; H4 j: ?$ \, PCall MessageBox7 T: C' z7 e" @2 |: f
invoke CloseHandle, hFile ; 关闭文件. ^6 w/ M L- Y9 H- l( E- j5 B
invoke ExitProcess,eax ; 退出
9 }- R' z- @0 U' F; R5 P/ s, }6 h! b. i+ J) c; G
end start
& ?7 B) t' I! H% k+ O! a 0 {# z7 c6 I. w$ ^3 B
如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 3 _; L: I3 f0 l
% U& a: G4 M8 Pvar currentpos,timer;
' O. {6 {! Q* G+ x+ }8 B& x; {) L3 z7 `8 \ W; E7 n% C
function initialize()
5 x3 \/ F) u/ d+ ~{( W5 |/ I6 Z' H/ _
timer=setInterval("scrollwindow()",10);
2 Y6 L! M# B S! F}8 z' P; K I- M
function sc(){" ]4 u7 ]0 y' I+ f" _8 h
clearInterval(timer);" S+ b" A6 R+ T9 w' o1 k
}
% `% j. W4 L" i& T' f- \: e% Wfunction scrollwindow()
8 E( s, H* v' a/ V3 `2 |8 [' v3 Q: k{* U1 o. Z& n) G# m! G6 @
currentpos=document.body.scrollTop;7 X8 ]0 ?+ F" J$ ~
window.scroll(0,++currentpos);# E# ? D' X c% A; ^; l
if (currentpos != document.body.scrollTop)# v. p6 e" {- A
sc();2 W- n0 P3 S9 [3 Y- u# V8 J
}. ~0 [* P3 U1 f U
document.onmousedown=sc
( p0 ]" }" j, B" d+ k1 g( l$ w3 Udocument.ondblclick=initialize
) x. l# b) u ?
+ d7 w& Y+ l6 x! z; }
" D! ^. |2 g u! h' J% q0 O0 i |