编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友* j( F- Q0 j+ W* g( D
会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助
作者 : Detten Detten@tiscali.be
来源 : _blank>http://biw.rult.at/4 f# @7 I( o U; K s
翻译 : nbw _blank>http://www.vxer.com/. W& S5 x' Z. R
( K" |7 M, D& }8 w( U
1、前言 A: G$ p; ], z9 H4 }9 D. c' k" [' X
一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。
那如何来写呢?
===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。
# d" Y4 ?7 w" W" i
===〉如果找到,打开该文件。
0 K6 i- Z# J: P z" |
===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。
& B3 z9 m+ Q$ |# `" y$ r6 `
===〉如果以上都无误,我们可以做需要调整
- V* ?5 E: j. K% X3 M I
把文件指针移动到指定位置,然后写入新的操作码。% a+ y. p# J3 H+ l/ d8 ^8 d% @* V
===〉关闭文件,给出提示结果。
' Q* z: ]& G9 E `. j
下面找一个你破解的文件,然后开始....
2、必要的API
做这个程序需要用到什么API呢?% i B& R. e+ |2 l9 R# L
HANDLE CreateFile( ! E/ O/ L( r7 G; w, F$ l' P* S
- s: V- e8 @& Y. t
LPCTSTR lpFileName, // pointer to name of the file 4 f$ u2 |7 B7 e7 p+ F$ y
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode 6 I# g$ \7 ^. e m
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes 8 L' G3 r3 o% F1 Q {/ Y
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy 7 ?7 R$ v; Z" X# l! ~, x# Q
); f- N9 V; i0 ?
这个API函数用来打开或者创建文件。
dwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'6 [/ c* p4 o& p+ A) b9 f
dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。
可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。- K7 { ?3 W7 D* B% E* {& e
如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。
' g$ Q+ H" M# g: a" i% X! |" v8 x
BOOL WriteFile(
HANDLE hFile, // handle to file to write to 3 H, c/ y1 E7 \: p
LPCVOID lpBuffer, // pointer to data to write to file ! o* k4 J$ r1 ~; Z5 S8 q
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written ) N# ^9 h0 x+ }7 b& B" y
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);# u' G0 y1 S, K/ b
我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]
涉及到的hFile句柄就是CreateFile函数的返回值。
lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。
" j* h9 i3 E3 Q: v9 M0 Z; { n7 n
typedef struct _OVERLAPPED { // o & K0 v* p9 n2 R# |5 K
DWORD Internal; 4 ~ Q; n+ t9 Z) K8 I
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent; . O7 s* l0 E; F
} OVERLAPPED;
Offset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)
3、目标
目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行)
当然你肯定是不错的Cracker
并且很快找出来了需要修补的地方:( r6 C- g) E' {
2 R, E9 I- N! T
Offset 53Fh : 74h, 15h -> 90h, 90h- q. w8 d9 N- X/ s" g. j \
5 A3 a0 t. a) f0 r& U, V8 {5 E( N
以上就是我们所需要的所有信息。6 w" C1 p9 k2 f ~ e
4、代码
) v( V* x" _' ]8 O7 w9 {3 ^
386; Q0 a, Y) I0 @+ R
.model flat,stdcall0 d D# T+ j' Y
option casemap:none
include \masm32\include\windows.inc" ?0 C6 M* a7 v% F% G. q' U( l
include \masm32\include\user32.inc4 o5 K5 h) ~1 M o& n& T- x, S
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib4 Y$ @/ u; x. X1 I7 F( U; r
includelib \masm32\lib\kernel32.lib# P* t2 u E" s- t& w1 F/ E
3 U1 r. l3 O) s% m+ G
.data
FileName db "Crackme5.exe",0# ~! T# h( q! H5 c! S5 T
AppName db "Crackme 5 Patch",0
Done db "File patched succesfully !",0/ u- w3 W* C* @' J. G1 c. h1 v( w7 B
NoFile db "Can't find crackme5.exe !",0
ReFile db "Wrong version of crackme5.exe !",0
WrFile db "Error writing to crackme5.exe !",0
RBuffer db 75h, 15h
WBuffer db 90h,90h
OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL>
.data?
8 R+ c5 x; e. @: `
hInstance HINSTANCE ?
CommandLine LPSTR ?% j; Q3 `' J' O: r
hwndname HWND ?
hFile HANDLE ?
Numb dd ?: g' L/ t. ]" D. j: R
Buffer db 2 dup(?) & o6 H$ _: V7 D" @1 ~
% K1 a K+ M2 s
.const
.code
start:
invoke GetModuleHandleA, NULL
mov hInstance,eax 7 b1 x7 x' K: U+ A( X0 j5 R$ G6 c+ [
invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL - [7 K4 B* z6 _8 |
' R' i, [ a" V# N) h
.IF eax!=INVALID_HANDLE_VALUE; `, m% Z. V( Y# n
9 W6 j3 d/ }) Z+ [1 Q0 B- e
mov hFile, eax ; 存储文件句柄
Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节( d! R8 L: e6 b7 P( [
mov ax, word ptr [Buffer]
.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)
Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)! H+ e- Z/ }, y0 [7 i. ?+ O
.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息
push MB_OK
push OFFSET AppName
push OFFSET Done ; 弹出信息地址入栈2 W# Y6 s/ `: Q5 e: g3 }0 l
.ELSE ;如果返回值不是2,那么弹出错误信息
push MB_OK OR MB_ICONINFORMATION1 r2 [/ u3 o E7 [4 f
push OFFSET AppName9 i! ` ?+ A9 s2 ^5 F( A
push OFFSET WrFile
.ENDIF 9 h L& m; B- E4 S$ z& |9 a+ z& B! N
.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息 [& q! J' R+ d& h
push MB_OK OR MB_ICONINFORMATION2 r2 m7 ^. q. V, c
push OFFSET AppName5 ~: u! ~ q$ y- q
push OFFSET ReFile 5 Z7 D: d& I7 {0 r8 D
.ENDIF * b4 c" _7 A3 l, K- d; j( v1 i
. e! d' Y! M' r8 `
.ELSE ; 如果未获得文件句柄,弹出文件不存在信息
push MB_OK OR MB_ICONINFORMATION8 S' S' r9 f% B [
push OFFSET AppName
push OFFSET NoFile
.ENDIF( V, F# {; u& z0 z
4 e f% b; k! [7 i* f$ A. s
push NULL
Call MessageBox
invoke CloseHandle, hFile ; 关闭文件) P- n9 d5 g7 `: ~8 w0 I% D4 @
invoke ExitProcess,eax ; 退出' ]0 f, ^) }; O6 u6 ?; ~0 Y! d
1 N' D3 ]4 j7 M/ `0 v* L, U' [
end start
如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。 / c) t1 A$ n9 y& p( s1 N% P
, t: O' i; |+ o5 \# b
var currentpos,timer;, ~# }: ?+ L2 Z3 y+ r) V
function initialize()
{
timer=setInterval("scrollwindow()",10);2 o' B9 H% w8 [! n4 n2 D
}& y6 i) s% [, k3 A8 w+ M1 x
function sc(){0 N* B. c; U( J& Y
clearInterval(timer);
}: t9 H7 b) _; R) r' E
function scrollwindow(); ^9 f. C( O; m! R. {2 [& M2 R3 }
{# P/ \ U. ~5 u$ G) g: f. J' A7 V
currentpos=document.body.scrollTop;- p- A, c. H# r1 A R
window.scroll(0,++currentpos);
if (currentpos != document.body.scrollTop)
sc();" W9 B$ K* b$ h! `
}9 s. i) X. Q4 Y: }, _
document.onmousedown=sc* o7 @8 ]% r: \1 ^ m
document.ondblclick=initialize0 @1 H# O9 S9 e0 t' s
1 A8 g' e x |6 N" ]
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |