QQ登录

只需要一步,快速开始

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

编写一个文件补丁

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

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

8 ~- x, T! G' `

作者 : Detten Detten@tiscali.be 6 s* q4 Q! l+ ^& o: m ^来源 : _blank>http://biw.rult.at/8 E4 q8 E4 V* w5 f9 ] $ x+ H& a. N0 C% H 翻译 : nbw _blank>http://www.vxer.com/* H; K4 L J8 A. O0 { , l3 r( m6 l, O! ~. f4 H" A 1、前言 1 D$ C3 J7 O* g9 u5 Z 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。- v( Y( {: l3 i3 x& z. A7 i% ?; y* [ 那如何来写呢? 6 v6 D0 W1 q8 t- I3 c* @% n/ v===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。$ F: `0 j* W2 H( y 9 c7 B. N# B( X' M! U1 X! {9 W===〉如果找到,打开该文件。6 k U* Q* I* E8 a0 y. ? " t, x2 A f- N; U$ P1 J===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。 1 J- @; L% E2 Z* z- p: o( c& i/ V) q4 n$ F& E8 W ===〉如果以上都无误,我们可以做需要调整2 S3 ]: j G# p! K* ?% O5 Z4 j 把文件指针移动到指定位置,然后写入新的操作码。 5 G% S" v; Y/ c/ F6 I! L6 ~5 m7 f; ]& _! s$ A ===〉关闭文件,给出提示结果。6 O' F( _( ]/ W 8 K8 X3 F9 L$ m z/ \# t/ l/ U下面找一个你破解的文件,然后开始....* N/ G7 l7 o/ S- k+ K, ^! { / T2 b0 ^4 Q4 @; }5 u" B* v2、必要的API8 u; X( s ~2 }2 ?+ `/ F# p 做这个程序需要用到什么API呢?: s5 |, u5 ~5 L- `5 \ I : k$ X4 m! e/ ~0 \, C1 A5 O: wHANDLE CreateFile( 2 L. n$ c) S( z* B& a # W5 ?; @1 V! }* H6 @LPCTSTR lpFileName, // pointer to name of the file 5 L; o) F B% D0 M DWORD dwDesiredAccess, // access (read-write) mode " b8 c6 L" D; \5 LDWORD dwShareMode, // share mode 5 Z7 |2 Z$ v: {& z! H' }; d LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes ( N* Z/ d8 F6 O" z7 C- I% B DWORD dwCreationDistribution, // how to create . z/ P i* [/ R2 P3 J DWORD dwFlagsAndAttributes, // file attributes 7 O+ x, K4 f0 K1 KHANDLE hTemplateFile // handle to file with attributes to copy - t2 q: t3 E' D8 ^ j, Z, U. e0 E); + q) X4 W6 K; f, e; \& R0 Q. p6 f; H 这个API函数用来打开或者创建文件。7 ?/ m5 |% w$ }4 I7 [4 W dwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件; 7 Y R* F& p/ _( Z& LdwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'7 z$ m- r2 U& M8 f; h' \, g dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。& F- Y- B0 m4 D0 | 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。 , D. j. I3 D3 J& h1 L 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。 , U( G! Z, _$ v: x( \/ |; w7 U( ~( j, @1 q) Z; [ BOOL WriteFile( . c; A" S1 H, L' P8 Q, W5 ~$ C& ^ HANDLE hFile, // handle to file to write to H1 F1 s e0 @4 P LPCVOID lpBuffer, // pointer to data to write to file * R' C' f/ L" j' i' y DWORD nNumberOfBytesToWrite, // number of bytes to write ! j+ L! Z7 }3 x9 J( D8 T LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written , R; O$ ^1 F, Q" GLPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O( S0 Q2 [8 o1 N2 D) n: S ); 9 x* _! C% n! c4 H) {9 } ! n, F; ?6 G) |. A% A( N6 u8 t 我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要] 0 X& F6 q2 J% `. ?9 c6 X 涉及到的hFile句柄就是CreateFile函数的返回值。: a4 ^8 T6 i0 n6 }' k4 u7 X4 P2 \9 W / c z$ f6 e2 \5 H5 YlpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。& \4 [3 d: ?! c, c+ I% n' f / }' u3 S0 l3 {% mtypedef struct _OVERLAPPED { // o / [3 o) W! o" C/ a7 x9 |DWORD Internal; & c# m* r/ ?$ o( ~ DWORD InternalHigh; 9 f: c5 P+ _: B0 k DWORD Offset; & ~) s" P6 @& D) S DWORD OffsetHigh; & c9 h& w" A( Q6 T, I0 Y' w HANDLE hEvent; 6 a7 w3 x( n& b$ g: a} OVERLAPPED; 0 H# P( X+ G) D0 oOffset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)9 r) u+ @7 V/ |1 i7 c/ e 6 l4 Z5 Z# ?8 I' u, F1 L) i( k% a3、目标 , E; C7 T' [6 H$ O- U( ~$ w J 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) . {$ a* M5 u) B$ y7 ~. D" ` 当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方: ' Q6 i( h) s, ^- C! |% D% H, c, a1 F* | Offset 53Fh : 74h, 15h -> 90h, 90h0 Q I' ?1 N) g( a ; a+ u' J+ M; i6 d' m 以上就是我们所需要的所有信息。 ; X7 X. r! S# j& {1 f* [' g. I" i& h3 u% p' Z5 b* ~ 4、代码& s) Z" G7 ^3 t* X, g+ C ; `( I" N) A8 r2 _* H+ [ 386 ( X$ k# {7 a% G4 S.model flat,stdcall ! a! V! O: I* W* [- M' woption casemap:none ' M& o+ ~4 e2 F! P8 b. a5 ~ include \masm32\include\windows.inc$ N+ a; t9 }7 x/ @/ T include \masm32\include\user32.inc% C$ R- M0 H2 f& t include \masm32\include\kernel32.inc: R6 L U# h7 @5 q1 x& L' N includelib \masm32\lib\user32.lib, D, R0 W! _$ q includelib \masm32\lib\kernel32.lib + v- R) W3 B. Z2 {9 T a3 P( G 5 Q! Q1 T( g3 S 7 ]3 d( i! f; `5 k# R" a. R.data , I2 p Z7 P8 O- Z FileName db "Crackme5.exe",0 ( u3 x% r8 A6 X: x: e. e0 xAppName db "Crackme 5 Patch",0 + I" Y; [1 N" {# Q3 \' o) aDone db "File patched succesfully !",0; o& @& l6 Z% S: r W2 [/ r; R NoFile db "Can't find crackme5.exe !",07 p+ H5 n# u5 P- r9 c6 Y ReFile db "Wrong version of crackme5.exe !",0 3 k4 ]8 P: Z8 `* F- k5 t- iWrFile db "Error writing to crackme5.exe !",0: ?; ~; \" O* O5 I$ \7 Z RBuffer db 75h, 15h# N/ f& ^ z4 A: j. T/ H+ j WBuffer db 90h,90h$ Y. m* Z! j1 i1 e1 Y. h OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> 0 N0 U4 k8 N7 }1 W5 b 2 v6 g: B; G W4 J" W .data?% @9 \, T3 q0 I6 ^: d( C % j% ^" `, ^3 G2 x, @" i hInstance HINSTANCE ? $ o' V6 t5 [1 p' o+ D" ]CommandLine LPSTR ? 7 g8 B# a2 r% Z1 D# E. k. S8 o1 x! bhwndname HWND ?4 I! ]. o. H* v: i: T8 ^1 M ^" j/ l hFile HANDLE ?/ y9 m, y! h3 k- g$ D4 s/ l- T Numb dd ? 9 j- x% a" ] q0 Z8 M! O8 NBuffer db 2 dup(?) 0 P: [, h1 H9 \( I 4 a; f+ R6 u t, F , Y j4 h( u+ v& y% G% T1 v1 g1 B.const# t H/ ]& f& Y3 b. s% Y 7 b" \1 K: J; B" z' V2 R .code+ _1 i# H9 t3 d. Q) r start:2 X8 h: p2 k0 C; v5 v" ` # v8 g% G$ I2 V invoke GetModuleHandleA, NULL0 y q& K, N" a6 T" Z1 z mov hInstance,eax ' {; k* i, j5 C( n2 e; Z , l( |# w! N8 i7 s" Linvoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ! D E0 t r! g+ j$ [9 z: \) `$ C) c+ O8 O* m" q$ H .IF eax!=INVALID_HANDLE_VALUE/ T" |3 e' |2 X0 @0 ~4 u$ a) k # B/ `0 {* t. [/ k3 W( g2 ^mov hFile, eax ; 存储文件句柄+ `# J6 K. `) Y0 b# c" d$ m Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节5 W( a# F* g. r9 l }# a+ t, o9 x mov ax, word ptr [Buffer] 1 J% @; k6 C; a. C- J i .IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)9 L: a5 R, Z2 ?3 I8 u Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)' p7 Q6 z$ Y7 x# u .IF Numb == 2 ; 如果返回值为 2, 弹出成功信息3 u! q- Z, C+ Z push MB_OK % m4 D. ~- A: q; V8 ^. r `7 U+ }2 \push OFFSET AppName; p9 Q: I7 ?% Z1 N( o: I0 }, z5 n push OFFSET Done ; 弹出信息地址入栈 ' M* n2 t. A J+ {, D. t.ELSE ;如果返回值不是2,那么弹出错误信息 ' F, ~) l3 d8 E7 S5 q% [push MB_OK OR MB_ICONINFORMATION . Z x7 c" l) `push OFFSET AppName * `' V( w7 d/ q& U+ v/ k" e- z. Ppush OFFSET WrFile. L) p ^7 ], J S! N; t .ENDIF ' p9 Q8 u! o0 u4 _8 {* Z .ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息 4 d' ?& x/ V9 h! Epush MB_OK OR MB_ICONINFORMATION : ~3 E5 \# [5 }8 }( p$ {+ Wpush OFFSET AppName @) P4 t g8 K# w push OFFSET ReFile / ^+ r* j! m& I! Z .ENDIF 1 Z( B4 A* Y* L! j . K, A$ v: O: `# o .ELSE ; 如果未获得文件句柄,弹出文件不存在信息0 @, I8 j0 o% C3 i& k, } push MB_OK OR MB_ICONINFORMATION P ~5 U1 z4 ~+ ^# y) gpush OFFSET AppName * O. U$ V7 m6 W9 {6 Dpush OFFSET NoFile : ~$ U7 M" K4 A s# [.ENDIF / j0 S3 v& p$ d1 ^. k7 ~ . O) h, f" n: }9 y npush NULL) x# D- Z2 a/ Z) P+ H1 a Call MessageBox 4 k& r U0 e+ {' ~+ minvoke CloseHandle, hFile ; 关闭文件 3 b0 Y* m: _: Y* `, H# Ainvoke ExitProcess,eax ; 退出 8 y' Y0 S. a; ^7 s2 ] 6 m$ c: G" S f' r) wend start% G$ H/ q# d8 i5 Y 1 k6 p) D6 ?, y! O 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 1 E+ F- [0 d) ~1 | 3 d* s5 F1 X. H* M, U( E( qvar currentpos,timer;. i" h, N3 x, g" j2 F 5 i, Y9 m9 w% a0 qfunction initialize()* \) Q2 W4 I* g' Q' X { 5 }. B! `+ ?: Y0 ftimer=setInterval("scrollwindow()",10);9 h5 t ?( d' l- R) ~. _ } 1 _1 ~; v0 g+ C; e: w4 D: ofunction sc(){ ; c" S+ b: Y: \ gclearInterval(timer); - d7 e9 v5 Q2 V* w9 U0 o$ @}" [ _& `9 @0 w6 ?4 r7 o" i% v$ @ function scrollwindow()( m y$ ^: B4 A& P' D- \ { / w7 t) k D/ gcurrentpos=document.body.scrollTop;/ Y" J4 n& H5 I4 j window.scroll(0,++currentpos); 2 I8 I- t9 I8 i8 jif (currentpos != document.body.scrollTop)- [8 g3 X# E0 t. y. E6 a6 A4 z sc(); 6 E3 M L' H; ]+ n}. `( g' w8 P4 A document.onmousedown=sc4 k0 h+ V; \) A: ?9 o document.ondblclick=initialize0 x ]/ X% \0 e8 F 7 a A9 B: Z; N4 E

% r* q6 j" Z8 A! z% W0 a! ?

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 09:21 , Processed in 0.389597 second(s), 52 queries .

回顶部