QQ登录

只需要一步,快速开始

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

编写一个文件补丁

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友8 ]/ \/ {* o* ~* [; N o& _3 _ 会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助

9 O& P, z( q B( N0 T

作者 : Detten Detten@tiscali.be ! x& m5 Q9 f4 B1 ]. w 来源 : _blank>http://biw.rult.at/ $ h6 z; O# i) M0 v6 N$ s; R + J8 Q2 I+ R% b: r: Y翻译 : nbw _blank>http://www.vxer.com/ + y; U9 m2 I1 t: k; P* I- ? : A# b1 Q0 \6 ]# H6 N' ^# C! B1、前言 7 z9 L+ g$ N) C9 o R 一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。9 Q' `$ J& l0 p# X! ? 那如何来写呢? 0 K+ m2 c4 i C6 I0 t, x===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。 7 M3 G6 d; S9 w# T$ i( `: x/ E1 H6 B# K# H- H/ u$ | ===〉如果找到,打开该文件。 . o8 L* J" ?. L: {: K) ~" T$ v2 f, }; p ===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。 4 t' h& \+ |/ k v; w! Y( R9 s. B6 E3 E7 V1 T" L5 g ===〉如果以上都无误,我们可以做需要调整 1 K; L/ Y4 i; A1 U7 P, ` 把文件指针移动到指定位置,然后写入新的操作码。 # A6 X) K8 U6 C9 e6 R6 _, s+ H3 `0 p ===〉关闭文件,给出提示结果。4 i- `* N7 U1 l9 C $ a6 d0 S0 |4 Z+ A 下面找一个你破解的文件,然后开始....7 K9 A; W, n0 V/ e0 k# d& t n' i ' L2 M+ i% e. W0 k1 T* r& r$ q 2、必要的API 9 O2 j% w% ]0 }4 v+ M 做这个程序需要用到什么API呢?( a7 ]4 V" }' ~# L' }7 W; }. T 8 Z) H; C; T3 J! d' C* THANDLE CreateFile( 5 x# |& x7 W9 e$ F 4 K0 W F% \4 i, l* iLPCTSTR lpFileName, // pointer to name of the file 6 G" P* e% E' D3 i3 E: g: q; SDWORD dwDesiredAccess, // access (read-write) mode ) ^' N3 V4 e, H9 _8 G! U DWORD dwShareMode, // share mode * R/ B8 y0 @# K4 xLPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes 3 C( x2 v9 k7 c$ a/ I6 W! E7 `3 A k DWORD dwCreationDistribution, // how to create 1 Y: w' p$ P9 c+ M& ] DWORD dwFlagsAndAttributes, // file attributes 5 N* N( |* r3 {- x) cHANDLE hTemplateFile // handle to file with attributes to copy 4 e* K- [* d; k) W: e- ]5 L: K" K4 U ); 0 Q- [/ c Z4 [6 [; K, K5 j) ~( h: h3 j( h% T7 H 这个API函数用来打开或者创建文件。 * C c3 [+ e v) `% g" f1 {- ndwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;6 K9 k5 s S" O1 T( j dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'6 J7 y- k' ]# E- A dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。( }' {( M L( W. ?$ K& c9 D 可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。 1 E+ z0 b- K5 B- b4 Q9 P+ r% h 如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。 8 L) \/ k$ Q B* [* i6 \ v) i1 A( K- e: r) j$ c2 X BOOL WriteFile( 2 W& T( @+ I0 I HANDLE hFile, // handle to file to write to 0 c1 G3 ^1 @: m" Y* [ LPCVOID lpBuffer, // pointer to data to write to file ; |- l" P1 s6 P9 T0 O DWORD nNumberOfBytesToWrite, // number of bytes to write 3 b. _' R m: @$ r( L7 b9 ~" OLPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written 2 {& M' i/ o0 v/ j) h LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O( [7 U+ S- K K( O% c );/ F5 T7 x# [6 L; X1 r 3 z' k, L) [; K9 N 我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要] ( @ m' g$ g; q( x 涉及到的hFile句柄就是CreateFile函数的返回值。 " U8 a! Q& K; s 4 u( Z( E$ {# I: j3 y) x! f# [lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。5 w" W1 T P. n0 O% n2 p , M$ x/ z% J. ~# P9 `% [3 b typedef struct _OVERLAPPED { // o 4 Y+ s& E1 q0 l, s! R& c DWORD Internal; ?6 J9 N% G+ IDWORD InternalHigh; 7 R% `3 z8 m! W; w& M- ^5 O DWORD Offset; 5 Y5 F2 t) g9 ~, E* p3 {! v DWORD OffsetHigh; & G9 O& m2 Q5 y* I% MHANDLE hEvent; 2 o/ |! v! F: t: n } OVERLAPPED; ! c7 E2 G( g' a6 R Offset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)+ |( l+ b; r" {; A; \, L( ] 4 G: R- N/ M! J" b9 K3、目标 6 s8 E$ o) s1 V% [: Z" L 目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) 5 K) c7 u# e( w# ]' Z9 d4 z( O 当然你肯定是不错的Cracker 并且很快找出来了需要修补的地方:. \- K: a6 p% Y% r$ h8 M / ?# f9 R! O9 p/ hOffset 53Fh : 74h, 15h -> 90h, 90h : H" ] S4 B2 s * ~# M9 }5 s+ ?: D3 U7 a; I 以上就是我们所需要的所有信息。 ; i6 C; Z* N& s# Z3 a+ Q5 z+ c! R3 S: h T 4、代码 ' a5 E/ K7 o2 C; n$ {0 h % i# ?- T9 n$ s- P8 K0 b l! U386 5 b& L8 C; E5 |3 T+ k7 e.model flat,stdcall : G) e# _ X5 R- z6 T7 zoption casemap:none , L$ h- I5 Y' ?1 Q4 k7 @/ h' g! { ] include \masm32\include\windows.inc * N! G1 P& L9 \& ~$ Dinclude \masm32\include\user32.inc + I. D1 U* E3 J' Iinclude \masm32\include\kernel32.inc 2 |4 ~5 \* E" ]9 C, t# y% Pincludelib \masm32\lib\user32.lib2 D/ b l4 ^. w C3 G! K2 c includelib \masm32\lib\kernel32.lib " r% w9 T' s5 B 7 t- X) H+ n- A; C( w4 Q/ d3 v3 w8 j .data - g' d" }" I' E5 S: D0 |6 L9 h FileName db "Crackme5.exe",0' V9 B! K3 y( b/ P AppName db "Crackme 5 Patch",0+ ^3 F( q8 X! e- z8 X P9 N0 h i Done db "File patched succesfully !",0 7 }% n6 w) D5 j7 g7 vNoFile db "Can't find crackme5.exe !",0# S4 i2 _4 {* q ReFile db "Wrong version of crackme5.exe !",0 ( ]; [8 k6 q p. j+ o, R' H' EWrFile db "Error writing to crackme5.exe !",0 2 ~3 L( b+ K6 ] R' S/ iRBuffer db 75h, 15h; M4 h" f6 z! w8 `0 A9 Z B1 `2 q" M WBuffer db 90h,90h2 m, B3 Z! n3 I8 e OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL> # L1 J/ Y% _/ { i" G5 B C$ @8 W0 p& Q' N.data?3 W6 \, `( O9 T' c - G L- A1 |/ S0 p hInstance HINSTANCE ?1 l; s; D5 v6 t7 W, p, _ CommandLine LPSTR ? # V- L, v/ x, m* R7 |$ l" ?% g& qhwndname HWND ?& R! y) e+ _+ I1 R( t hFile HANDLE ?1 p! \; l7 d7 u8 k. P8 \ Numb dd ?4 w# Y" T% _. T! V0 F/ ~' ? Buffer db 2 dup(?) # n" J2 d& o# V: b1 I - a9 j. D' q# Y* x6 D & H F( b8 y( X/ U: B! C3 ?.const: Q6 W1 u# r7 ^; {+ Z2 S7 t/ ] * a0 g [+ [! N9 g" t) H, v.code! X6 G9 J8 [; F start: 7 Q: j: p4 R6 P# |: N7 O0 ^# ]" z invoke GetModuleHandleA, NULL 4 }+ [! i/ L0 m) J/ H- \5 ]mov hInstance,eax / L7 [. M- ^$ H * g# z( l* R) L- n1 g: H invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ( [* s0 {' ^: o/ Y 9 [% m+ O: W. }.IF eax!=INVALID_HANDLE_VALUE2 z/ L5 v- |2 A) P; p2 a& j) a' S ( W% Q- _ g B( i- v# H. k mov hFile, eax ; 存储文件句柄0 R; G+ j8 v3 l9 y1 R; E6 j Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节* q1 t7 \. o, _) _1 Y mov ax, word ptr [Buffer] ) }# t3 Z; I/ \ .IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)' z0 T/ l1 z' t! o: I; k) ^ Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h) ; V% q0 \+ M7 H.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息 $ z8 k+ U0 U* U" tpush MB_OK $ [. v5 {3 j" d A7 ~2 ~* R push OFFSET AppName " E* w$ [* s. r8 r7 t6 s9 q7 qpush OFFSET Done ; 弹出信息地址入栈 9 \2 K t+ B6 G8 g# @) a! s.ELSE ;如果返回值不是2,那么弹出错误信息 c; ^3 Q* a5 f! X2 N* |& s/ U7 y push MB_OK OR MB_ICONINFORMATION1 V1 P5 F! h% k" S push OFFSET AppName 8 S1 @1 D; g) ^+ [9 _push OFFSET WrFile! v9 R% K! G0 U. m1 r' o8 d7 U .ENDIF $ {' l# e5 z( R0 P/ G8 [8 H- H7 r% S.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息 : P) w3 C; u6 C: r3 F, ^- spush MB_OK OR MB_ICONINFORMATION # M( m* K6 |. l2 b s+ Cpush OFFSET AppName + E4 ^" C4 R# P q4 ipush OFFSET ReFile * m) S% t$ j: u7 Z.ENDIF ( j' U$ ~2 u/ W" }) ~! B& }* s# \4 p. A .ELSE ; 如果未获得文件句柄,弹出文件不存在信息 , |3 C4 S/ W* qpush MB_OK OR MB_ICONINFORMATION4 G6 b! I) x7 N8 a+ o" W; F: X2 l push OFFSET AppName 8 J% l! C; X5 W' M* O) u: Kpush OFFSET NoFile ( X$ m0 t% q5 o/ ~0 S2 Q+ l .ENDIF: W* F; I: T1 G4 `& y; R3 S$ n4 V / l+ x. z' a2 w push NULL 1 ^3 w; L. Z$ O6 d+ C6 l+ E: uCall MessageBox% ~7 H7 {' [, N7 |% k4 W invoke CloseHandle, hFile ; 关闭文件 X) L8 ]+ \. v invoke ExitProcess,eax ; 退出 1 Q3 B( f4 O9 d3 f6 ~+ G. C% C+ P+ s. ~6 y! V, t& f end start' w1 t7 J; T8 u6 a 7 s5 X4 j% K- z& j& t a" H 如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 2 f% H; t) p7 K( D $ M+ I; n, k3 D) F( m# Rvar currentpos,timer; # v0 Z w1 B: X V5 W- I5 P9 `; X# R3 ^+ f' ^# F5 q function initialize()) B0 j. ^9 Z% q. C. L" T$ Y$ a { 3 s9 K+ k1 n6 ` Mtimer=setInterval("scrollwindow()",10);* y9 {5 Z$ v ]' u* `1 R! @5 @ } $ `- x. T+ w' G5 b0 x, Z- vfunction sc(){ 3 v J3 }3 Z. _3 f1 z) @2 S' V' HclearInterval(timer);+ [" R0 ^' y% t5 a/ _0 n } : D5 z/ ?8 ~' {function scrollwindow() ( S, p2 e- |" j9 b# R/ l& X! c{% Y4 I0 I2 I/ b) H6 Z currentpos=document.body.scrollTop; ! y. o2 }. o4 \- nwindow.scroll(0,++currentpos);% J6 N" v2 Q/ Y* ~( W8 T2 Y if (currentpos != document.body.scrollTop)3 ?4 s) o2 n$ @# Z% q" ]1 A2 m+ H: d sc(); # L$ N( H& Q. e M$ p% t# M" u2 X}2 I, `' E: d, f* u; k3 K document.onmousedown=sc2 D, Y: V2 d) G( t1 g& H document.ondblclick=initialize ( G6 x' @4 h* u0 Z4 c# } 4 J! b& i+ |8 X

: k3 D1 b) F5 ^# K6 x

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-18 21:43 , Processed in 0.458222 second(s), 51 queries .

回顶部