|
编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友# l) `0 u. o, i; G& @4 [7 b9 d0 V3 x
会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助 ) y+ {4 V) v; h+ e( K. n. ?$ x b
作者 : Detten Detten@tiscali.be
F+ ?1 U3 y1 @& s来源 : _blank>http://biw.rult.at/
! o7 m2 q8 M+ n: L" ~9 T+ }9 M+ t$ m- J6 w/ M$ y3 S
翻译 : nbw _blank>http://www.vxer.com/7 H7 z4 }4 {6 N8 K6 i/ J6 e
d' b( b! {4 z0 m8 S: ^1、前言( X4 d8 O' ^2 d7 A7 T( v
一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。$ K2 L( J; u. g8 ^5 K- O# g
那如何来写呢?, r9 S, ]. r$ J& o) l5 }# g0 Z2 o
===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。
6 S" y$ m5 N* ^7 _. `. m2 `9 v
5 a3 a; Q0 [, w. U===〉如果找到,打开该文件。4 V: H0 Y0 y3 B0 P9 Y1 Q1 F# m( N2 y
; \; f( C% }( b( Y, U% f- m===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。6 ?6 _4 t3 A! s) X# U, }8 s; M
' k3 k) r$ b6 G
===〉如果以上都无误,我们可以做需要调整
6 ?9 h6 d1 a3 b$ r0 [, A! G 把文件指针移动到指定位置,然后写入新的操作码。( ^+ k9 u0 K3 J% T7 x: ]) o% }
* c! W' a6 _( C===〉关闭文件,给出提示结果。
3 s, M/ _1 P+ w' y8 C
6 |& D- V- w d v2 }下面找一个你破解的文件,然后开始....% }/ S9 W' {3 X0 h# D
- j1 ]. [; p) o. ?2、必要的API; X3 H$ K% V E) ] ?$ V
做这个程序需要用到什么API呢?+ K& n8 r8 p; C0 [2 W- Y Z
' R8 Z+ |0 j. U! z& \7 R
HANDLE CreateFile( 3 h, V& \* U5 |; {3 X) W
; h3 @7 Y% b! v HLPCTSTR lpFileName, // pointer to name of the file 4 u2 l& Q& y9 j+ p
DWORD dwDesiredAccess, // access (read-write) mode
/ s1 ]$ q, b, ]# F, DDWORD dwShareMode, // share mode
6 u4 P O4 A! c ?3 TLPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
4 M( n# W: z2 i* r' G tDWORD dwCreationDistribution, // how to create
; w& c; P6 ~5 E5 z ]DWORD dwFlagsAndAttributes, // file attributes $ R1 h: M) Q8 P) }
HANDLE hTemplateFile // handle to file with attributes to copy
% ^# Q5 N9 m. g+ I# Z);8 d" B. [$ I4 U
6 W8 W3 x* @! p( s0 K1 ?# | k4 q 这个API函数用来打开或者创建文件。1 _! X. t3 i0 W9 V
dwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;& X$ B: @/ w o) q; D
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'
& E% A3 X+ o! VdwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。
+ X* \5 [2 M' a+ E% G0 b; F 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。
( Z* m8 t8 H5 E) ? 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。; h/ ]2 Y, F* D6 l: H
7 M& W) T/ [; }0 p0 bBOOL WriteFile(
7 r5 l |# W3 U9 U9 _+ z9 CHANDLE hFile, // handle to file to write to
( f' H+ y5 g4 p6 E" ]' pLPCVOID lpBuffer, // pointer to data to write to file
8 o: P0 S% @! _1 g6 u$ X2 b: KDWORD nNumberOfBytesToWrite, // number of bytes to write , Z9 z% @1 x4 \" M: e+ w
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
; @7 w) U; }; s& I7 sLPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O! `" {/ o2 P( U& A! E( N! _
);
% M B1 y! j5 ^1 U
7 G7 X; X( x W# F: P" O( _# S1 ` 我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]# F8 L2 C- ^2 h4 j; }) _
涉及到的hFile句柄就是CreateFile函数的返回值。+ s( b4 ]& }5 M. {
& }; O1 \6 M9 t flpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。' U( C# M0 t+ T8 @& A# v" g
- O9 }7 h, Y2 e# j& Ttypedef struct _OVERLAPPED { // o
S# @8 S- `2 G! V' ]. o: m4 `DWORD Internal; / W" N% g# p' N4 k4 _
DWORD InternalHigh; 7 i* d6 j9 C5 h- v) j! _
DWORD Offset;
, W, H8 p. i( K2 N7 @- [' KDWORD OffsetHigh;
- U# E6 B3 _8 c" `HANDLE hEvent;
7 a3 u2 i2 F d% b, U} OVERLAPPED;
/ f' @- |7 i; n1 sOffset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)
6 K6 `$ E) h/ a& ~' z
3 u4 Q+ j! Y2 `2 h' c$ k3、目标
' ^3 Z u F+ t: x9 O! x w 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行)
' `+ X& S4 ^+ p J9 ?2 z 当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方:# b6 |& D9 A+ U* L) S6 V: j
# ?; p3 t2 G3 n- |: {" Y% Q( gOffset 53Fh : 74h, 15h -> 90h, 90h3 ]' d- u& p& U7 i. t
! A+ q/ c, k- r1 {+ r 以上就是我们所需要的所有信息。
* I% l# u1 I8 `9 }: A+ f4 M* p7 l. b4 R. h+ v6 C$ e) d7 o. ~
4、代码
* K- ~. h* K; B. `$ z6 V, e) ^6 b1 R# U3 ~; D4 v
386
7 E& M; d! a- g1 B, a.model flat,stdcall A+ H% o! z9 ?- w' o5 y) y
option casemap:none ) A+ ~; V8 F# c1 x' H' j
include \masm32\include\windows.inc# {, j- d2 y' M+ }
include \masm32\include\user32.inc
I" y5 C% u8 `4 \" p: i# vinclude \masm32\include\kernel32.inc
$ K8 M& r0 x1 ?; a8 @. N$ Sincludelib \masm32\lib\user32.lib
3 T! u; y3 p. z k& B; {includelib \masm32\lib\kernel32.lib# r+ p7 M6 I U2 w) y3 U
5 D( H& `! {) E* j
- o5 O2 \' P _ f7 P( M9 e# r.data
4 Y; `2 ?# l2 g; kFileName db "Crackme5.exe",0* g" ]" \7 M) N7 [2 L6 n# w
AppName db "Crackme 5 Patch",0
' ?0 C8 ^" p% M" D2 _0 dDone db "File patched succesfully !",0
- ?, \" f G3 n k2 z& x- @NoFile db "Can't find crackme5.exe !",0- o* E! o* x# k; u! B% `( m
ReFile db "Wrong version of crackme5.exe !",0
+ R. J0 t% a4 ~4 D) I- BWrFile db "Error writing to crackme5.exe !",0$ l3 g: e0 g3 P. L
RBuffer db 75h, 15h7 `" ?5 t" a! Y) }
WBuffer db 90h,90h! a% p& R. t* U- u) [
OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> 7 |3 n" ~, ]% f( u/ H- d$ F5 E( I
; w \5 D5 l2 V* b& |.data?
, a) S9 s1 Y$ n! T; d9 w7 M; U9 w d( k9 r0 X
hInstance HINSTANCE ?
" k5 e* F7 u7 Q9 j1 ]0 s8 X2 P7 @4 i& QCommandLine LPSTR ?
/ Y7 f) A& p" Q* G7 whwndname HWND ?
! I5 N$ d" p/ i" O$ uhFile HANDLE ?
( K' J8 R$ b. X( Q5 Z6 y9 Z7 INumb dd ?
: P# o1 P: @5 n9 Y/ @/ t2 g7 c6 gBuffer db 2 dup(?)
- |2 b: Q% T1 H$ c
$ W/ s$ K' ^3 n5 M7 e6 z8 C: }# O. E' J1 X, u6 F( r R
.const
! r" |2 G1 S. o8 W8 m6 Y
' w# E+ ]! O, ]# D, G5 @8 D& `.code
/ o% x( A2 Q9 k$ X$ U8 n; [, N6 {# wstart:8 X# m! |) V$ t9 l9 \& ?( _
# S/ n1 R5 I, x+ j6 M9 x" d3 Z
invoke GetModuleHandleA, NULL. B8 V; p, M, V7 n
mov hInstance,eax 8 R4 o7 p( I6 o+ }9 Y/ V3 b ~
& b9 E! f) S) K6 c; Y' [4 k* ?5 v2 s
invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
1 }6 W. Y* X; I1 T+ k2 f
4 D% m1 `% I! V( A# I, c, U9 A$ ].IF eax!=INVALID_HANDLE_VALUE
9 I& Y2 o6 w" F) k3 h, m
- H8 \7 \6 g( Q# Zmov hFile, eax ; 存储文件句柄' `4 R( h# ^# P# ~' a. X
Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节3 |) x9 m. d3 L, V" @/ \
mov ax, word ptr [Buffer]
8 |5 C1 q" P0 C- W0 h: x.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)
1 j- V% @9 W* c0 yInvoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)
9 c- Q4 l+ A* n4 V; e.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息5 X7 Y" W1 \2 d6 ]
push MB_OK
& R- T# z; Q6 d) A+ n7 epush OFFSET AppName
# r1 \7 I* e; j2 xpush OFFSET Done ; 弹出信息地址入栈0 J2 g0 d' X0 H" u3 L
.ELSE ;如果返回值不是2,那么弹出错误信息8 \/ _* Q$ T7 v/ x9 {
push MB_OK OR MB_ICONINFORMATION
+ R4 E' [9 V6 S% d1 y# Mpush OFFSET AppName
1 a9 k9 b# X7 y6 h; ]: f: U: }push OFFSET WrFile1 x# X0 Y% z7 X ?8 `
.ENDIF
" o& v' Q3 m, h$ T.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息. c+ F. \: q& A9 _8 R( K- \
push MB_OK OR MB_ICONINFORMATION
+ ~) N$ E& u S2 {push OFFSET AppName
9 V, A" U* O2 ypush OFFSET ReFile
: z1 S" o( ?1 I$ V.ENDIF
- y- v5 Q0 N3 V/ q$ ]0 b
. W: D, l. A& B4 j6 W2 f$ ^.ELSE ; 如果未获得文件句柄,弹出文件不存在信息# Q5 e8 f w' m2 ]. S) R/ ]
push MB_OK OR MB_ICONINFORMATION
6 s& Z: O, C# C1 m! R9 b8 Vpush OFFSET AppName, @& ?5 S6 G+ c$ z
push OFFSET NoFile
( I$ H; g& Y5 c" {0 p.ENDIF7 ~: ^4 z; G0 s
5 K) ^! ]) x" v: `0 o. j
push NULL# O! i. i3 B" Q5 L
Call MessageBox9 |* O! Q9 l1 u
invoke CloseHandle, hFile ; 关闭文件
, t* r, k3 m6 ~% r& E5 }invoke ExitProcess,eax ; 退出
( Q/ j* L3 Z$ J8 Z# ]
- f7 A0 x0 i$ H1 L: s- f+ N6 ]end start
5 m' W! [* o: f. M( u* b3 h" Z( _
& {5 V2 L. e4 C- m/ i: C& R 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 - N+ J0 A' F) u, |. @1 w
8 W. N1 @7 w: k: evar currentpos,timer;; k F/ `" ~* K* u' A" d6 f
7 Q7 |+ _' z+ L2 ofunction initialize()
3 A3 O! {. P: v! X{% f% X& p( C" F( l- |7 U
timer=setInterval("scrollwindow()",10);. m+ v I" l% g. \$ v& o, }+ @
}
4 S. O$ C7 m6 ~" Z$ M1 Efunction sc(){
5 u+ w- w+ U! M$ h7 E5 I8 Y5 EclearInterval(timer);+ c( R1 w: }! T1 E
}
7 p* P* C/ r; q6 U, X% e+ h5 ^* t! Gfunction scrollwindow()$ B0 s0 e6 S1 v4 M! c# w
{
4 a4 ~6 y2 T3 q5 B X) X! kcurrentpos=document.body.scrollTop;1 Y' p/ \ N% `- I' ?1 Y
window.scroll(0,++currentpos);
4 {0 ~* {8 b, \2 z @' Jif (currentpos != document.body.scrollTop)
. E3 [! j, [$ e9 l6 _sc();( E \! M' x# v! D, D( F! Q
}
% S. X6 U; E6 }4 Y, S5 Rdocument.onmousedown=sc
. `9 w1 T& G3 z5 ~; Y" ^document.ondblclick=initialize& |; h. Z$ F8 K2 J' _( }3 Y
2 k3 l7 _9 Y- ~ s* K - a0 z, e! B* x; g2 z
|