QQ登录

只需要一步,快速开始

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

编写一个文件补丁

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

编者:昨天一个叫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

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-4-19 06:55 , Processed in 0.326443 second(s), 52 queries .

回顶部