QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3094|回复: 0
打印 上一主题 下一主题

编写一个文件补丁

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2004-11-21 00:19 |只看该作者 |倒序浏览
|招呼Ta 关注Ta

编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友( i! @3 q( e$ e' W H1 q# f 会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助

7 \8 N; ?( v7 y! m0 q9 p

作者 : Detten Detten@tiscali.be x E/ f9 I/ d: D 来源 : _blank>http://biw.rult.at/ , G) G5 s }3 e; h1 t ' U: k% W" J. L+ x翻译 : nbw _blank>http://www.vxer.com/) z$ _5 t) t- M ) l `! P' {0 b' D/ g- C1、前言 " n# K- o7 g. |5 ]3 W# i- ]4 Y 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。3 Z/ r2 q* e u! l' E/ m) [% y% | 那如何来写呢? ( h. g5 y/ _& V) @===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。 9 z9 P6 S! w2 I* u* R: s5 |( [* R' |3 y/ j8 g ===〉如果找到,打开该文件。 2 Q. |1 d& A! x; I! r+ q- Y5 v: v- z5 P0 b' q0 X9 F. m ===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。, P4 k1 x+ x- N5 J0 m3 j & t1 n/ G/ M3 j4 m===〉如果以上都无误,我们可以做需要调整 $ |% W, b, C3 W& S+ a 把文件指针移动到指定位置,然后写入新的操作码。 8 N" j/ z" c! ^! F/ N% y& r6 `1 d/ }7 A; U ===〉关闭文件,给出提示结果。/ T# L. r! s* |! S; n/ F6 r , |* L+ _* O/ R: | k8 O5 R 下面找一个你破解的文件,然后开始.... - @) w; e9 h" \5 U- a+ \+ o) e& i, t( Y5 t5 S3 M$ X 2、必要的API E6 c$ ~9 n3 c1 ?$ W* x1 c0 \ 做这个程序需要用到什么API呢? - U6 @' e' p/ H! @ ! N& K* U0 Q& [# G6 r0 _HANDLE CreateFile( ( O# l* }$ E: P) A - P4 o0 P0 f+ N' CLPCTSTR lpFileName, // pointer to name of the file 3 e. ]. A$ _5 u4 h2 vDWORD dwDesiredAccess, // access (read-write) mode ( `1 d1 `5 a N- [" aDWORD dwShareMode, // share mode # G2 D) |6 m! z2 Z' g LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes % a' [/ Q7 @4 I: u* j+ O% [ DWORD dwCreationDistribution, // how to create + j, ]$ R* ~4 b8 i' i' QDWORD dwFlagsAndAttributes, // file attributes ( g3 a3 K6 _# }! UHANDLE hTemplateFile // handle to file with attributes to copy & T- F& w# M( [* q5 y. O/ a V);' x1 N5 c& n2 d, n" H - e: Z3 c2 k# D+ S& L1 h# p 这个API函数用来打开或者创建文件。3 u$ v9 W, C5 u9 \) \ dwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;! j6 P* Y" N- l/ Q! J dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ') y. J$ F: G! z' [) x) Y dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。 9 V5 x+ O& ^% c* x( e 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。 $ m3 I- E |2 i# U 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。 ' E; U9 H, G# ~8 u+ b2 B $ t/ g( Z9 P* K! r0 q. o, gBOOL WriteFile( E! h# h7 R. ~+ G1 R8 x' V2 N HANDLE hFile, // handle to file to write to M: `1 h& f! w4 g3 VLPCVOID lpBuffer, // pointer to data to write to file : n3 I' S2 {6 y% }' V# u( oDWORD nNumberOfBytesToWrite, // number of bytes to write : x2 q T& [. QLPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written & m& V( [) H y3 fLPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O - J0 \6 p: J X);3 @, w. S7 t; {6 S5 F. e " d6 f+ k1 t! W3 C6 o 我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]' l4 ~* c! r% G/ Y( k 涉及到的hFile句柄就是CreateFile函数的返回值。$ A( n9 `; W: H 1 m4 L: k# l3 F1 J. w3 E7 Q! O lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。 . u: {% j; q0 p6 x! _6 I) Z' R/ b8 i1 _6 G% ^8 g2 G2 ~! {' l typedef struct _OVERLAPPED { // o 9 ~% y9 r2 k* k# o7 \5 nDWORD Internal; ( B; p. y" `9 l; n; z DWORD InternalHigh; & a y1 T6 H2 }. ^. X! q$ ^$ h DWORD Offset; 8 u" @9 o, k6 ?/ q6 X' ?9 } DWORD OffsetHigh; 4 z; X% Z4 J% |* q HANDLE hEvent; ; L* m$ A. n+ [. \' p } OVERLAPPED; % c, E" p- B4 k! ?; i0 C0 VOffset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)- v! @, o/ S, z1 b 6 `# R% x) p) D1 j 3、目标 , u; ^, l0 v* y" i( Q3 F8 m4 P 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) # i% v' H# u6 B- Q6 s2 D y+ ^ 当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方:0 q6 Z* B7 \0 S( h3 g2 @/ _ * G" r% ~1 y* x$ v5 t+ U& e Offset 53Fh : 74h, 15h -> 90h, 90h! }4 k* R {5 W) F* S0 |% A ! s' f# w7 l$ g( N7 B q+ \5 N 以上就是我们所需要的所有信息。: ?- ^0 c, H2 ~7 P! P, \1 ^ " t; h5 C6 P; @# o, r5 a% _6 N1 g 4、代码 & v0 c+ @ w/ [* z2 D9 }. Q1 E, J # _( `' ?- I) N386 ) _3 w) d! j: V6 D) f.model flat,stdcall : V0 O6 w3 j1 x& toption casemap:none ) ?8 k* d5 S; R% K3 a0 linclude \masm32\include\windows.inc % Z# A! I& o& s5 S0 `$ t/ C8 xinclude \masm32\include\user32.inc) v$ t* @* L n8 F* S9 } include \masm32\include\kernel32.inc 4 ]% r% e% b( _includelib \masm32\lib\user32.lib; a& e: q/ C) t: k3 [$ \$ a2 { includelib \masm32\lib\kernel32.lib+ x* i9 W6 P* v9 O; {& B " o; G \# |/ K& U( F. y# j# g $ u$ x* V! z: N .data : u7 Z# d5 R! `/ _9 j' K( k FileName db "Crackme5.exe",0 " g d6 L9 D7 W2 \% H4 A! ?AppName db "Crackme 5 Patch",0 $ I3 F/ J: v3 A. S j" x) RDone db "File patched succesfully !",0 ' ]# a. `, N( z0 B/ N7 bNoFile db "Can't find crackme5.exe !",00 K& S7 b3 Q: x) ^' ? F3 f% h ReFile db "Wrong version of crackme5.exe !",09 X0 {1 _$ O) Y+ F. z( h5 E WrFile db "Error writing to crackme5.exe !",0 S" N1 s& G7 U3 X RBuffer db 75h, 15h( U8 u* [6 F. k6 d% u WBuffer db 90h,90h2 C& M. e) a$ Z2 N+ ]; r OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> % W! q" p, o1 o1 q * x, _) }8 C U. h: w2 \! L/ [.data? 7 g8 `6 @3 c# f) p3 A( ` J, d% B7 d% d. a ahInstance HINSTANCE ? - F& j) ~5 \) T# }& K( TCommandLine LPSTR ? - l$ H/ c- D, y5 u- y8 Ghwndname HWND ? ) k3 ^; ?6 i8 M, JhFile HANDLE ? / a& w: d G5 y- \ k. x1 cNumb dd ?& n) z2 z: G) B9 B Buffer db 2 dup(?) * D4 B, z5 L8 F+ @7 {; C " v! p' o6 _1 ~( U: I4 F# c 4 R$ j0 s8 w3 n" ], {.const8 {# y+ i5 n3 e. U5 N! y g 3 b# b x7 F& |( U .code, F/ K. O S, l' L/ i start:' F# k0 l% e- S, I V ! `5 F9 |2 k8 {& j% L. G6 b invoke GetModuleHandleA, NULL 8 H4 r( b# P6 ^: Y$ Smov hInstance,eax 1 P: Z ?2 v( k6 [* D6 B1 o7 }( R" } m. y) k" P9 J invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL , @- L6 ^# R8 m; p* o) m ) O% ]$ B. Y) a0 o) A2 Z0 a .IF eax!=INVALID_HANDLE_VALUE) d* \; y" }3 C: e& ]* H6 B. R 4 h# q2 \+ d8 P) N: D4 K; v1 ~- M% X mov hFile, eax ; 存储文件句柄 0 }! H+ \. E8 k4 @& p( JInvoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节9 @# k( o6 B7 Y6 m9 z# W4 ~( j: B mov ax, word ptr [Buffer] 4 c2 K/ B7 g `. ?$ ^.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-) ( e- D4 Z) C- B, F, K8 eInvoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h) ! N, d( D1 }. e8 I.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息& [ l2 X# N2 M, o$ k, w2 Q push MB_OK 6 _* R$ z/ a* f( K, ]% r4 s push OFFSET AppName & j5 x% I% _# d0 T! V3 Rpush OFFSET Done ; 弹出信息地址入栈 1 ]) F E7 ?) J6 N F.ELSE ;如果返回值不是2,那么弹出错误信息( |& h6 v) x$ L4 y push MB_OK OR MB_ICONINFORMATION3 z8 f/ Q- T* u% V0 ]" @ push OFFSET AppName: @; u7 W: [2 b& j6 ?* Q push OFFSET WrFile 7 `: H( E) e0 `$ [1 r5 J.ENDIF 0 b$ n$ y' ]2 j: ~" ^.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息7 v4 L: g) R. s6 t3 h$ l) F! X7 [ push MB_OK OR MB_ICONINFORMATION * p; s4 n1 j1 u+ Z8 g tpush OFFSET AppName- Q, }# Q8 s. o push OFFSET ReFile ( [& Q$ ~/ ~! E3 b .ENDIF % X# N3 ~4 e, r5 g+ ? " u3 c7 ^$ ^. A.ELSE ; 如果未获得文件句柄,弹出文件不存在信息- Q; y5 D' E% ^0 v7 P9 C: E; v% z6 k push MB_OK OR MB_ICONINFORMATION 7 E" Y- m; f) C i I& o& @push OFFSET AppName9 {% o i" J5 p C) J) u$ X push OFFSET NoFile 5 R+ Q# L; A: {# i4 d# Q4 t.ENDIF . C( b) [/ A* n1 V+ |# [4 y; K' Q- O) } push NULL . e8 r+ m8 q' O) ^+ h( b& @Call MessageBox 1 S* h6 A, [% z/ H+ {$ O. _. L* _invoke CloseHandle, hFile ; 关闭文件- {* a' i( d! F$ v9 g4 a invoke ExitProcess,eax ; 退出' J( a; y/ \0 m7 m# O; W, _' \ 8 v/ l0 f y: e+ ` end start# u' B1 R B" q2 E7 L# H' G; \ 9 |4 P* O% x: _+ N4 S- H v$ x7 w 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 0 F4 b. t5 N2 I: }3 Z# m; X5 j- M1 W / @; T' J/ L' Y. Avar currentpos,timer;3 R8 f) M V Q; K5 X( ^ ' t/ L( y# G% q( _ function initialize()" @& L; C a. ?3 \; `4 b {6 ~# `8 g; P3 e timer=setInterval("scrollwindow()",10); x3 n/ [, _. J, P }9 G0 `" U8 F. i; }) ^ function sc(){; J( q! }* B& d& k clearInterval(timer);. v$ i" _0 l+ N' g } " l, O* O, ^# `& M8 yfunction scrollwindow() U; f% y8 q V1 @ E# J{8 E" w0 y3 l5 y4 @0 a currentpos=document.body.scrollTop;( S5 a9 l, W f4 }# J3 j: ^. o. I window.scroll(0,++currentpos);; E/ O& q: E6 A- u3 p' e. v% h5 m3 ~2 c if (currentpos != document.body.scrollTop) 5 j8 t8 @+ V4 x, g: nsc(); 3 n; G2 B c7 \) R+ V# E( Z; V} 4 J$ ~! T! V: qdocument.onmousedown=sc - M9 v+ O1 K+ d2 e! L3 K/ tdocument.ondblclick=initialize . @) j8 k6 }, v0 \' R ~9 U" C% ]3 P- B

, x7 o# m, z1 K4 M$ G/ g0 d' ^

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-8-18 00:21 , Processed in 1.654687 second(s), 51 queries .

回顶部