数学建模社区-数学中国

标题: 编写一个文件补丁 [打印本页]

作者: 韩冰    时间: 2004-11-21 00:19
标题: 编写一个文件补丁

编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友* j( F- Q0 j+ W* g( D 会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助

/ u. u; y2 B+ H6 }

作者 : Detten Detten@tiscali.be ' g0 ]- W' c' |来源 : _blank>http://biw.rult.at/4 f# @7 I( o U; K s ; }# ~: D1 _$ C; B翻译 : nbw _blank>http://www.vxer.com/. W& S5 x' Z. R ( K" |7 M, D& }8 w( U 1、前言 A: G$ p; ], z9 H4 }9 D. c' k" [' X 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。 4 p6 b+ E% }" p/ {0 O 那如何来写呢? / _# P9 S1 @' N===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。 ) O% v1 ^4 O4 d, ]# d" Y4 ?7 w" W" i ===〉如果找到,打开该文件。 , Z/ l) K* [/ T0 K6 i- Z# J: P z" | ===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。 " t/ c: f1 u0 }& x- y. I& ~( }& B3 z9 m+ Q$ |# `" y$ r6 ` ===〉如果以上都无误,我们可以做需要调整- V* ?5 E: j. K% X3 M I 把文件指针移动到指定位置,然后写入新的操作码。% a+ y. p# J3 H+ l/ d8 ^8 d% @* V : t# l/ x) Y. b* M5 l' I, U. S2 n- ]' Y===〉关闭文件,给出提示结果。 3 K/ \6 G/ T: G" C8 ?' Q* z: ]& G9 E `. j 下面找一个你破解的文件,然后开始.... ! g; O% B& `$ A& {' G8 s$ q. _+ H ; e G1 ~; ]+ F2、必要的API & P, @2 R( T( i# p+ g6 b 做这个程序需要用到什么API呢?% i B& R. e+ |2 l9 R# L / D8 _/ _ V4 i" h# P: IHANDLE CreateFile( ! E/ O/ L( r7 G; w, F$ l' P* S - s: V- e8 @& Y. t LPCTSTR lpFileName, // pointer to name of the file 4 f$ u2 |7 B7 e7 p+ F$ y DWORD dwDesiredAccess, // access (read-write) mode {2 c2 p. n; Z( V, gDWORD dwShareMode, // share mode 6 I# g$ \7 ^. e m LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes 8 L' G3 r3 o% F1 Q {/ Y DWORD dwCreationDistribution, // how to create + b2 U! R. _$ x, {- T* @7 s. o7 SDWORD dwFlagsAndAttributes, // file attributes $ Y m5 C* G8 \HANDLE hTemplateFile // handle to file with attributes to copy 7 ?7 R$ v; Z" X# l! ~, x# Q ); f- N9 V; i0 ? # `1 u5 `4 O) K 这个API函数用来打开或者创建文件。 4 R0 O7 Q/ a5 k+ K3 D2 zdwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件; * z5 m, e7 D% Z) b9 U0 IdwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'6 [/ c* p4 o& p+ A) b9 f dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。 9 W3 ] P. F2 Q+ E 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。- K7 { ?3 W7 D* B% E* {& e 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。 # ?7 h! u+ z* k' g$ Q+ H" M# g: a" i% X! |" v8 x BOOL WriteFile( 6 D6 d/ g* \) HHANDLE hFile, // handle to file to write to 3 H, c/ y1 E7 \: p LPCVOID lpBuffer, // pointer to data to write to file ! o* k4 J$ r1 ~; Z5 S8 q DWORD nNumberOfBytesToWrite, // number of bytes to write % O: z, m8 @" d/ O) k7 MLPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written ) N# ^9 h0 x+ }7 b& B" y LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O & R7 d3 y! F) t3 A9 y);# u' G0 y1 S, K/ b 0 T* J% w+ T t5 j& x3 g 我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要] ' \6 n8 {' ^, n n 涉及到的hFile句柄就是CreateFile函数的返回值。 ' p; f4 ?/ s3 P0 F( x7 y$ {! Y 2 I0 V' p% Z0 U/ zlpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。 5 I* d7 p5 l; D6 Q( C" j* h9 i3 E3 Q: v9 M0 Z; { n7 n typedef struct _OVERLAPPED { // o & K0 v* p9 n2 R# |5 K DWORD Internal; 4 ~ Q; n+ t9 Z) K8 I DWORD InternalHigh; . d& u" R3 h4 |8 y( R7 B; W: ~DWORD Offset; . j" ~% I& t' O$ R& ^7 K' VDWORD OffsetHigh; % E: c& P2 G5 W+ c% @4 SHANDLE hEvent; . O7 s* l0 E; F } OVERLAPPED; 6 Y. |+ d' g9 b$ a3 c* y3 |Offset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址) . L* W- T9 f5 r # w7 H1 j( B3 u5 _6 B+ S3、目标 # U" M9 p3 S' r) C( J; a 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) ! e; B# `4 |4 Z; S6 B; |2 I 当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方:( r6 C- g) E' { 2 R, E9 I- N! T Offset 53Fh : 74h, 15h -> 90h, 90h- q. w8 d9 N- X/ s" g. j \ 5 A3 a0 t. a) f0 r& U, V8 {5 E( N 以上就是我们所需要的所有信息。6 w" C1 p9 k2 f ~ e 4 A* w/ t8 e, D6 @7 `6 ?8 W4、代码 / t0 `( ]4 P' J) v( V* x" _' ]8 O7 w9 {3 ^ 386; Q0 a, Y) I0 @+ R .model flat,stdcall0 d D# T+ j' Y option casemap:none ! \$ V$ n9 c4 s, Cinclude \masm32\include\windows.inc" ?0 C6 M* a7 v% F% G. q' U( l include \masm32\include\user32.inc4 o5 K5 h) ~1 M o& n& T- x, S include \masm32\include\kernel32.inc ( P' Y" m+ P+ w: I/ R' ]+ Kincludelib \masm32\lib\user32.lib4 Y$ @/ u; x. X1 I7 F( U; r includelib \masm32\lib\kernel32.lib# P* t2 u E" s- t& w1 F/ E 3 U1 r. l3 O) s% m+ G ) u; R3 g/ u2 s: A8 E: G.data , I8 E* x2 [9 c/ k0 dFileName db "Crackme5.exe",0# ~! T# h( q! H5 c! S5 T AppName db "Crackme 5 Patch",0 2 Z E6 C# P7 ?) N2 N2 W- SDone db "File patched succesfully !",0/ u- w3 W* C* @' J. G1 c. h1 v( w7 B NoFile db "Can't find crackme5.exe !",0 " Z) |% ?2 E. { j: D7 s9 ?ReFile db "Wrong version of crackme5.exe !",0 7 L$ @6 L6 h9 d, O% JWrFile db "Error writing to crackme5.exe !",0 " @# S. a5 o: VRBuffer db 75h, 15h ! U+ |, u/ W6 SWBuffer db 90h,90h , T0 J- m% F) h, A! n2 J$ i: QOffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> . d1 @ {; d$ Z! D 2 M n6 _7 Y9 ].data? 0 H$ Q' W6 w1 q( M8 R+ c5 x; e. @: ` hInstance HINSTANCE ? ' x. `, l- N7 l+ [# l. ]CommandLine LPSTR ?% j; Q3 `' J' O: r hwndname HWND ? . p+ x* t# h: ~: D. j' u7 ohFile HANDLE ? , F+ L1 _; v# T6 K6 t9 H- }Numb dd ?: g' L/ t. ]" D. j: R Buffer db 2 dup(?) & o6 H$ _: V7 D" @1 ~ / |% a2 V6 } s1 j% K1 a K+ M2 s .const |5 G* c9 L; K9 v, S* P $ e: s0 N' V0 i' B) u& Q2 A$ l.code 3 b' _' w7 P1 l8 q: mstart: , g; V5 Q W9 t( K* R' @$ h1 a 7 d, I/ Z# x9 j% H2 m7 L0 s+ ?invoke GetModuleHandleA, NULL ) k$ X, _! ^2 K6 C. Q3 w) @& {+ Rmov hInstance,eax 7 b1 x7 x' K: U+ A( X0 j5 R$ G6 c+ [ 1 \- X7 S o: X' p, @6 dinvoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL - [7 K4 B* z6 _8 | ' R' i, [ a" V# N) h .IF eax!=INVALID_HANDLE_VALUE; `, m% Z. V( Y# n 9 W6 j3 d/ }) Z+ [1 Q0 B- e mov hFile, eax ; 存储文件句柄 % k1 `- E$ E F8 u2 P$ jInvoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节( d! R8 L: e6 b7 P( [ mov ax, word ptr [Buffer] & l6 s6 b( j8 j( l.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-) * f# w; G! S8 m7 U1 j4 ?3 sInvoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)! H+ e- Z/ }, y0 [7 i. ?+ O .IF Numb == 2 ; 如果返回值为 2, 弹出成功信息 0 G. [& M$ l5 p J* f3 Lpush MB_OK 0 n9 C- e1 t. U' R" d6 A0 O9 Xpush OFFSET AppName ' B- z$ s; n* ]1 l5 [9 a; v. i9 W3 [ k1 upush OFFSET Done ; 弹出信息地址入栈2 W# Y6 s/ `: Q5 e: g3 }0 l .ELSE ;如果返回值不是2,那么弹出错误信息 ! m8 s: T5 E0 S- ?' q; n( {push MB_OK OR MB_ICONINFORMATION1 r2 [/ u3 o E7 [4 f push OFFSET AppName9 i! ` ?+ A9 s2 ^5 F( A push OFFSET WrFile 9 y2 a, f4 i) P3 d.ENDIF 9 h L& m; B- E4 S$ z& |9 a+ z& B! N .ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息 [& q! J' R+ d& h push MB_OK OR MB_ICONINFORMATION2 r2 m7 ^. q. V, c push OFFSET AppName5 ~: u! ~ q$ y- q push OFFSET ReFile 5 Z7 D: d& I7 {0 r8 D .ENDIF * b4 c" _7 A3 l, K- d; j( v1 i . e! d' Y! M' r8 ` .ELSE ; 如果未获得文件句柄,弹出文件不存在信息 $ a# b: c2 T* {% Rpush MB_OK OR MB_ICONINFORMATION8 S' S' r9 f% B [ push OFFSET AppName , O0 ~+ a3 `, ^' u- Apush OFFSET NoFile " c- i/ s& I# j* m' [% {.ENDIF( V, F# {; u& z0 z 4 e f% b; k! [7 i* f$ A. s push NULL / I# O$ |9 T. S/ JCall MessageBox 2 k4 l1 r5 {% g* j% linvoke CloseHandle, hFile ; 关闭文件) P- n9 d5 g7 `: ~8 w0 I% D4 @ invoke ExitProcess,eax ; 退出' ]0 f, ^) }; O6 u6 ?; ~0 Y! d 1 N' D3 ]4 j7 M/ `0 v* L, U' [ end start : J! }6 M9 C2 k5 o; W& \5 f r 0 J- l) Y! H! { 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 / c) t1 A$ n9 y& p( s1 N% P , t: O' i; |+ o5 \# b var currentpos,timer;, ~# }: ?+ L2 Z3 y+ r) V % [9 j2 j2 S. h/ B: e, ]8 V1 S, Gfunction initialize() $ T1 Y8 v1 H6 |& o/ p; ~$ q, {$ z{ ) P2 s, i& J. e" Q* _- {# {timer=setInterval("scrollwindow()",10);2 o' B9 H% w8 [! n4 n2 D }& y6 i) s% [, k3 A8 w+ M1 x function sc(){0 N* B. c; U( J& Y clearInterval(timer); 5 N \1 v& E6 h8 h; E& k9 g}: t9 H7 b) _; R) r' E function scrollwindow(); ^9 f. C( O; m! R. {2 [& M2 R3 } {# P/ \ U. ~5 u$ G) g: f. J' A7 V currentpos=document.body.scrollTop;- p- A, c. H# r1 A R window.scroll(0,++currentpos); 3 s" y/ j! f+ J# r8 p9 ]4 P9 Jif (currentpos != document.body.scrollTop) ; L) G/ K& W* c6 z4 zsc();" W9 B$ K* b$ h! ` }9 s. i) X. Q4 Y: }, _ document.onmousedown=sc* o7 @8 ]% r: \1 ^ m document.ondblclick=initialize0 @1 H# O9 S9 e0 t' s 1 A8 g' e x |6 N" ]

; l0 ^2 t9 [( m" R& v






欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5