编者:昨天一个叫aqtata的朋友发给我了个最新的密界文集, 本来想打包下载,可那样很多朋友) o% K( u8 h0 T3 T1 ?) @
会看不到里面的好文章.于是我决定把其中较浅显通俗的一些文章发到文章区,希望能对您有所帮助
作者 : Detten Detten@tiscali.be 3 R& k5 T1 @3 _: b" S$ o+ q
来源 : _blank>http://biw.rult.at/' c' o1 R0 p F* X% B1 I
1 ]) o. |7 g# I, g* r
翻译 : nbw _blank>http://www.vxer.com/
+ ~' }" ~% Y# n |2 u K: q9 a
1、前言
一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。" B3 q% B) m5 Z
那如何来写呢?
===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。
9 U9 U8 c9 Z+ Y2 q# ?6 |2 L( s+ E
===〉如果找到,打开该文件。& Z1 n- u5 O, a1 t& q- L9 q
===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。( v1 _/ Z' r' R$ L; n7 R
6 F, ?) I {" q9 E, t
===〉如果以上都无误,我们可以做需要调整
把文件指针移动到指定位置,然后写入新的操作码。# \$ \" i8 s5 h2 ]
===〉关闭文件,给出提示结果。" n/ q* g( q' D4 ]6 b- d# b5 j( ~. z
下面找一个你破解的文件,然后开始....
2、必要的API
做这个程序需要用到什么API呢?
HANDLE CreateFile( $ }9 s; m% t5 E% Z g+ J
LPCTSTR lpFileName, // pointer to name of the file ( N, v9 j0 ^3 r, W# k
DWORD dwDesiredAccess, // access (read-write) mode + o: `3 f6 m y/ E
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);- R" \8 m$ T5 t* u% Q
这个API函数用来打开或者创建文件。
dwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'% P$ u8 ?' A( P' E4 l" ~
dwCreationDistribution = 'OPEN_EXISTING' 我们只需要打开文件,如果文件不存在函数将返回失败,然后我们给出提示信息。
可以察看WIN32.HLP获取详细信息,如果你没有这个API库,可以找相关资料。
如你所见,这个API函数返回我们需要文件句柄。我们可以利用这个句柄做下一步:写文件。
BOOL WriteFile(
HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write ; [ S% o `. Z$ q8 E( E
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written 5 }. L6 n* e- R
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);
我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]" x& }% Y* `" C1 O, {" W
涉及到的hFile句柄就是CreateFile函数的返回值。0 d; @) j5 ]. e. K2 H
& d; Z4 C) T/ t. g& v
lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。; O5 N9 q4 d( Y. [
typedef struct _OVERLAPPED { // o
DWORD Internal; , k$ L9 V6 [- k! ]' p4 I$ _; A
DWORD InternalHigh; , W1 b4 Z0 D/ X0 k; R: M, b
DWORD Offset; , L: A1 S" C3 U$ z
DWORD OffsetHigh; 6 Q' R* X8 V8 X; X5 G4 M/ V# P) g# k
HANDLE hEvent;
} OVERLAPPED;
Offset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)$ K5 n5 z0 E b, ]# W/ I8 O7 U
K8 X5 G2 k/ I j! T6 D$ C# e
3、目标" ?- M) k% |3 F. K$ Q8 c& k
目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行) ) C3 E. P0 |5 k s
当然你肯定是不错的Cracker
并且很快找出来了需要修补的地方:
3 m7 B7 ]: q0 L/ @( w
Offset 53Fh : 74h, 15h -> 90h, 90h, G& J0 l( u! L4 p" u
以上就是我们所需要的所有信息。1 R& t- L8 S0 I% u1 G& L) B
2 J$ b) Z& \* C0 i6 L
4、代码9 a; a0 j: o4 x% h+ Y: ^. Z
2 E; E% I& J1 p5 b; X$ t6 e
386# ?. r d, ^' h: h# ~/ @+ _; m' ~
.model flat,stdcall
option casemap:none . L+ v/ s: K4 b8 i9 n- G" \8 h
include \masm32\include\windows.inc
include \masm32\include\user32.inc, u9 w" D8 J. d
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib/ u9 c) c; M, d5 b; }2 l
includelib \masm32\lib\kernel32.lib8 e% [3 o; h5 a( ^1 i+ J
' X( y6 V: `" |7 e+ H
.data 6 K0 v9 O j% `8 j" l7 v
FileName db "Crackme5.exe",0; ^7 _+ m4 U0 ~; A
AppName db "Crackme 5 Patch",00 ?- {+ @& Y' N& ^) N7 U# l; U* g
Done db "File patched succesfully !",0
NoFile db "Can't find crackme5.exe !",0
ReFile db "Wrong version of crackme5.exe !",0
WrFile db "Error writing to crackme5.exe !",0% _/ I3 l# V; [1 ~
RBuffer db 75h, 15h; V6 ]6 C4 S4 ^; Q
WBuffer db 90h,90h
OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL>
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?( g& g6 O. ~, Q: i
hwndname HWND ?
hFile HANDLE ?
Numb dd ?, l p6 ^! ]7 X! A3 a$ q
Buffer db 2 dup(?)
.const0 D$ T( h4 Q5 W* B4 U& Y( s
.code
start:+ ?' |8 z6 V. B, P/ A
invoke GetModuleHandleA, NULL
mov hInstance,eax
invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL - C+ U; G3 T* I7 n T& O
7 n& k' D5 n+ q: ]
.IF eax!=INVALID_HANDLE_VALUE
mov hFile, eax ; 存储文件句柄3 Y0 m% i! u$ |
Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节
mov ax, word ptr [Buffer] $ [! D4 I4 {8 H
.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-): M0 z' A) @' E9 W. e" y4 }; p
Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)( b, K h2 Q% u: _& f1 U+ l
.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息8 J* c" K% ^3 C! V& b
push MB_OK ! c. }5 ]! S/ Q1 J) n9 _7 p) m
push OFFSET AppName
push OFFSET Done ; 弹出信息地址入栈$ H7 s# Q D+ M8 M
.ELSE ;如果返回值不是2,那么弹出错误信息$ |9 O. j2 R- [ N8 b
push MB_OK OR MB_ICONINFORMATION1 Q9 x5 n6 a9 q0 V* P8 l
push OFFSET AppName9 ?1 k1 R; k4 G. B: c
push OFFSET WrFile) {. _+ C4 g/ M: |
.ENDIF
.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息2 E! H" c& O0 `7 ~, l
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET ReFile
.ENDIF 8 }. ~. ^+ Y0 \. U
.ELSE ; 如果未获得文件句柄,弹出文件不存在信息
push MB_OK OR MB_ICONINFORMATION! ~* h+ p/ Z, s8 B9 f P
push OFFSET AppName
push OFFSET NoFile
.ENDIF8 U2 c2 g: E8 x) p) z/ z. v) h
! y8 D2 e+ P0 t* P+ `; a9 W
push NULL' d, R; ^( ]9 o7 A
Call MessageBox
invoke CloseHandle, hFile ; 关闭文件
invoke ExitProcess,eax ; 退出
end start
& [, y6 T2 O$ v6 K, b; K0 e1 ]
如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。
var currentpos,timer;0 |% U: s" S" y. j+ C i+ ^
$ ^0 L E( C% s
function initialize()0 j; H1 U1 A- k7 x
{9 t5 l. `' ]! U7 k, R9 l
timer=setInterval("scrollwindow()",10);& y \4 n. M$ H7 G) t
}& n1 d- s! ]; O, B/ E0 _" g
function sc(){6 I& Q! W' `+ L! G' y
clearInterval(timer);
}
function scrollwindow()
{
currentpos=document.body.scrollTop;# `) |- n5 H" T( `- z+ E: K! X5 o
window.scroll(0,++currentpos);
if (currentpos != document.body.scrollTop)
sc();
}
document.onmousedown=sc+ r' U" L/ k0 {, G& `
document.ondblclick=initialize
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |