数学建模社区-数学中国

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

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

编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友) o% K( u8 h0 T3 T1 ?) @ 会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助

$ z8 r3 ` J) H" F

作者 : Detten Detten@tiscali.be 3 R& k5 T1 @3 _: b" S$ o+ q 来源 : _blank>http://biw.rult.at/' c' o1 R0 p F* X% B1 I 1 ]) o. |7 g# I, g* r 翻译 : nbw _blank>http://www.vxer.com/ ( ?( J0 u2 |! E2 f. ~+ ~' }" ~% Y# n |2 u K: q9 a 1、前言 0 G. R" X9 x$ @ 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。" B3 q% B) m5 Z 那如何来写呢? / B8 X! F" W6 [===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。 - O; b) ?5 ]" T( c9 U9 U8 c9 Z+ Y2 q# ?6 |2 L( s+ E ===〉如果找到,打开该文件。& Z1 n- u5 O, a1 t& q- L9 q / X2 [/ o) [2 X' ~! a; T, r===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。( v1 _/ Z' r' R$ L; n7 R 6 F, ?) I {" q9 E, t ===〉如果以上都无误,我们可以做需要调整 z& z+ J$ M3 [4 n& i& y( J 把文件指针移动到指定位置,然后写入新的操作码。# \$ \" i8 s5 h2 ] F; M" K0 @& @! j8 d===〉关闭文件,给出提示结果。" n/ q* g( q' D4 ]6 b- d# b5 j( ~. z $ D e* l: i% Z5 X下面找一个你破解的文件,然后开始.... , r* a6 ^7 O% q* G ( g7 y' o6 f3 h$ v2、必要的API & _1 p+ ]6 z# s1 A& A; e 做这个程序需要用到什么API呢? & R& P$ X T6 Y2 ]4 e2 X* k' u2 v 8 }! z" f) f# l" ~1 L* [HANDLE CreateFile( $ }9 s; m% t5 E% Z g+ J # l; @8 I( X3 E! @, `LPCTSTR lpFileName, // pointer to name of the file ( N, v9 j0 ^3 r, W# k DWORD dwDesiredAccess, // access (read-write) mode + o: `3 f6 m y/ E DWORD dwShareMode, // share mode - z* W- a4 W5 A* H7 ~LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes 6 l. C3 w4 T& g+ R# H" }) LDWORD dwCreationDistribution, // how to create ; h0 w% k7 s3 R5 ADWORD dwFlagsAndAttributes, // file attributes - Z6 u/ F9 w- v6 NHANDLE hTemplateFile // handle to file with attributes to copy ( l* ^" \: X' D) x3 X! ?- y0 n& S$ I$ D8 ?);- R" \8 m$ T5 t* u% Q " E+ b* k1 ?; Y: t& u& K6 g 这个API函数用来打开或者创建文件。 0 w) w, W; e1 G5 o7 KdwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件; 4 A8 h4 ]8 e$ ^5 ^' ?dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'% P$ u8 ?' A( P' E4 l" ~ dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。 4 X4 o: `2 l5 f5 k8 H 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。 ) x0 m& ]$ g. c: j% `2 A* \ 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。 + g: v/ }+ x) p* \3 O9 { . ~ V# A0 X% JBOOL WriteFile( 6 Q0 h# J4 E9 ~( ~6 ]HANDLE hFile, // handle to file to write to ! H+ _2 [: k6 ?9 L# uLPCVOID lpBuffer, // pointer to data to write to file * L& H, b b* _ m9 Z6 R4 h) I& W% aDWORD nNumberOfBytesToWrite, // number of bytes to write ; [ S% o `. Z$ q8 E( E LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written 5 }. L6 n* e- R LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O 6 z/ n5 X1 u+ D& P# A); 2 b6 ]2 c9 I* ?1 ]# h# [2 } * k3 b5 R, a; J) o% W! v; J+ ] 我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]" x& }% Y* `" C1 O, {" W 涉及到的hFile句柄就是CreateFile函数的返回值。0 d; @) j5 ]. e. K2 H & d; Z4 C) T/ t. g& v lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。; O5 N9 q4 d( Y. [ ! T5 w, A0 j$ \( \' Vtypedef struct _OVERLAPPED { // o + E4 x3 F, S. b' W: SDWORD Internal; , k$ L9 V6 [- k! ]' p4 I$ _; A DWORD InternalHigh; , W1 b4 Z0 D/ X0 k; R: M, b DWORD Offset; , L: A1 S" C3 U$ z DWORD OffsetHigh; 6 Q' R* X8 V8 X; X5 G4 M/ V# P) g# k HANDLE hEvent; - t2 h1 k* `6 o0 @3 G} OVERLAPPED; ) V( d! T' t) xOffset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)$ K5 n5 z0 E b, ]# W/ I8 O7 U K8 X5 G2 k/ I j! T6 D$ C# e 3、目标" ?- M) k% |3 F. K$ Q8 c& k 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) ) C3 E. P0 |5 k s 当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方: 0 q4 l/ Y& [5 ~; \3 m3 d& u3 m7 B7 ]: q0 L/ @( w Offset 53Fh : 74h, 15h -> 90h, 90h, G& J0 l( u! L4 p" u & U! v# {! D% v8 ^: q5 V7 O 以上就是我们所需要的所有信息。1 R& t- L8 S0 I% u1 G& L) B 2 J$ b) Z& \* C0 i6 L 4、代码9 a; a0 j: o4 x% h+ Y: ^. Z 2 E; E% I& J1 p5 b; X$ t6 e 386# ?. r d, ^' h: h# ~/ @+ _; m' ~ .model flat,stdcall ' v) F# Y& T0 ~: Aoption casemap:none . L+ v/ s: K4 b8 i9 n- G" \8 h include \masm32\include\windows.inc ! k S. ?3 I) rinclude \masm32\include\user32.inc, u9 w" D8 J. d include \masm32\include\kernel32.inc # |6 L- \# Y) Y4 r' e f" n. E" r" iincludelib \masm32\lib\user32.lib/ u9 c) c; M, d5 b; }2 l includelib \masm32\lib\kernel32.lib8 e% [3 o; h5 a( ^1 i+ J * a# c% n) H' t2 C' X( y6 V: `" |7 e+ H .data 6 K0 v9 O j% `8 j" l7 v FileName db "Crackme5.exe",0; ^7 _+ m4 U0 ~; A AppName db "Crackme 5 Patch",00 ?- {+ @& Y' N& ^) N7 U# l; U* g Done db "File patched succesfully !",0 & {. S% b! ]7 w$ y# }; q n7 bNoFile db "Can't find crackme5.exe !",0 8 @8 r2 S8 |+ T- h% cReFile db "Wrong version of crackme5.exe !",0 # q' B. ^( Q1 A0 z# C/ I4 E' Q2 {/ w5 lWrFile db "Error writing to crackme5.exe !",0% _/ I3 l# V; [1 ~ RBuffer db 75h, 15h; V6 ]6 C4 S4 ^; Q WBuffer db 90h,90h " B V1 V, d) q) y. YOffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> 4 p: V ^8 x' e8 y/ h1 G: Z* u ; k5 \) u" D5 d1 @. T.data? * V# V1 v1 K2 K* C! }& e/ g & f D4 t& W V% n. C/ }# chInstance HINSTANCE ? / y$ }6 h; v, \& Y3 eCommandLine LPSTR ?( g& g6 O. ~, Q: i hwndname HWND ? . b& n `/ e3 Y: G- ~8 E$ I2 n0 \6 jhFile HANDLE ? 7 L' n+ F% F% w2 s: {Numb dd ?, l p6 ^! ]7 X! A3 a$ q Buffer db 2 dup(?) ' k' E% U3 E: E5 J $ H$ i, M' U( ~5 O- n+ ? 2 u+ U4 w; K9 `: F3 T4 N.const0 D$ T( h4 Q5 W* B4 U& Y( s + k# O1 g" |) h! u5 Q- r.code 4 ~% _& o# w0 {start:+ ?' |8 z6 V. B, P/ A 7 \$ Z9 A! Z, y1 A0 dinvoke GetModuleHandleA, NULL 2 V. c) Q1 j/ r% {9 N; emov hInstance,eax * h6 F- M# O- j. S# [ 0 x$ t% H# D" p/ p; ^invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL - C+ U; G3 T* I7 n T& O 7 n& k' D5 n+ q: ] .IF eax!=INVALID_HANDLE_VALUE 9 M7 H" [0 F3 r8 T5 C 8 X1 k+ A6 ], {1 K7 j, ymov hFile, eax ; 存储文件句柄3 Y0 m% i! u$ | Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节 0 O6 {% M" u/ z6 fmov ax, word ptr [Buffer] $ [! D4 I4 {8 H .IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-): M0 z' A) @' E9 W. e" y4 }; p Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)( b, K h2 Q% u: _& f1 U+ l .IF Numb == 2 ; 如果返回值为 2, 弹出成功信息8 J* c" K% ^3 C! V& b push MB_OK ! c. }5 ]! S/ Q1 J) n9 _7 p) m push OFFSET AppName 0 D- y3 A) [! f, ]push OFFSET Done ; 弹出信息地址入栈$ H7 s# Q D+ M8 M .ELSE ;如果返回值不是2,那么弹出错误信息$ |9 O. j2 R- [ N8 b push MB_OK OR MB_ICONINFORMATION1 Q9 x5 n6 a9 q0 V* P8 l push OFFSET AppName9 ?1 k1 R; k4 G. B: c push OFFSET WrFile) {. _+ C4 g/ M: | .ENDIF : d! Q v5 A/ z7 Z" U0 D5 _.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息2 E! H" c& O0 `7 ~, l push MB_OK OR MB_ICONINFORMATION % |- I& c( J' g i: ?9 s0 g6 Lpush OFFSET AppName 4 w& N9 X. C- f# c6 rpush OFFSET ReFile . w/ Q w' E/ U* t" d6 z( k( |.ENDIF 8 }. ~. ^+ Y0 \. U ; V: `+ c$ |5 ^.ELSE ; 如果未获得文件句柄,弹出文件不存在信息 6 m8 Q7 H5 O* U$ ppush MB_OK OR MB_ICONINFORMATION! ~* h+ p/ Z, s8 B9 f P push OFFSET AppName ( u8 Y* P& ?' p0 T5 u' x& g4 Fpush OFFSET NoFile 4 @2 ^% X( r$ @8 A4 ^1 Y.ENDIF8 U2 c2 g: E8 x) p) z/ z. v) h ! y8 D2 e+ P0 t* P+ `; a9 W push NULL' d, R; ^( ]9 o7 A Call MessageBox 2 Q; j7 w# c) P% ]- F) b( qinvoke CloseHandle, hFile ; 关闭文件 8 U% y. H9 ~, u* _& f% W& F3 ]invoke ExitProcess,eax ; 退出 ( u' n* r, c8 c N4 o + H# _, Z7 V) z' Rend start , P# B1 h" P4 ]% K & [, y6 T2 O$ v6 K, b; K0 e1 ] 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 # w, _9 N' }. l# X' ^ $ ~# [1 a, H' H V ~+ Qvar currentpos,timer;0 |% U: s" S" y. j+ C i+ ^ $ ^0 L E( C% s function initialize()0 j; H1 U1 A- k7 x {9 t5 l. `' ]! U7 k, R9 l timer=setInterval("scrollwindow()",10);& y \4 n. M$ H7 G) t }& n1 d- s! ]; O, B/ E0 _" g function sc(){6 I& Q! W' `+ L! G' y clearInterval(timer); + D- N/ X% r7 j% f1 v0 ?$ G6 Y} ! n$ u( r8 l8 z0 v$ efunction scrollwindow() 5 q# H% D. m c: k{ 6 S* J, j* _9 k) \+ V Wcurrentpos=document.body.scrollTop;# `) |- n5 H" T( `- z+ E: K! X5 o window.scroll(0,++currentpos); 7 o! }0 V* T6 p$ p. s; P4 E6 j# kif (currentpos != document.body.scrollTop) }+ _) X/ _* csc(); 3 E2 @8 l5 @8 t5 g6 m/ T* b8 U} . e4 A8 ]6 P2 a2 Q1 J) edocument.onmousedown=sc+ r' U" L/ k0 {, G& ` document.ondblclick=initialize % |' ~& E5 f- m$ N& P }; |5 i3 {/ q' t& @

( @: e# t. h. ^& Q






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