编写一个文件补丁
来源:互联网 发布:人工智能将来发展方向 编辑:程序博客网 时间:2024/05/16 14:15
作者 : Detten Detten@tiscali.be
翻译 : nbw www.vxer.com
来源 : http://biw.rult.at/
1、前言
一但破解了一个程序,你就想把成果共享给别人。为了不用把整个破解后的程序上传,你可以制作一个小补丁来修改程序中必要的字节。
那如何来写呢?
===〉首先找到需要打补丁的文件。大多数补丁认为该文件处在自己当前目录下。
===〉如果找到,打开该文件。
===〉然后检查打开的文件是不是和所破解的文件。比如我们可以检查文件大小,或者随机检查一些字节,或者最好检查将要被修改的字节。
===〉如果以上都无误,我们可以做需要调整:)
把文件指针移动到指定位置,然后写入新的操作码。
===〉关闭文件,给出提示结果。
下面找一个你破解的文件,然后开始....
2、必要的API
做这个程序需要用到什么API呢?
HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
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
);
这个API函数用来打开或者创建文件。
dwDesiredAccess 应该设置为: 'GENERIC_WRITE OR GENERIC_READ' ,因为需要读写文件;
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'
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
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);
我们用这个函数把2个字节写入需要打补丁的文件(当然是在正确的位置)[译者:作者的例子是写2个字节,我们做的时候根据需要]
涉及到的hFile句柄就是CreateFile函数的返回值。
lpOverlapped应该指向一个 OVERLAPPED 结构,我们需要用它设定正确的文件指针。
typedef struct _OVERLAPPED { // o
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED;
Offset的内容是需要写入的地址。(译者:注意不是内存中的虚拟地址)
3、目标
目标程序是Crackme5.exe,假定我们现在获取不到正确的序列号,而需要对他打补丁(译者:这个程序我也没有,大家知道意思就行)
当然你肯定是不错的Cracker:) 并且很快找出来了需要修补的地方:
Offset 53Fh : 74h, 15h -> 90h, 90h
以上就是我们所需要的所有信息。
4、代码
386
.model flat,stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
.data
FileName db "Crackme5.exe",0
AppName db "Crackme 5 Patch",0
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
RBuffer db 75h, 15h
WBuffer db 90h,90h
OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL>
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndname HWND ?
hFile HANDLE ?
Numb dd ?
Buffer db 2 dup(?)
.const
.code
start:
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
.IF eax!=INVALID_HANDLE_VALUE
mov hFile, eax ; 存储文件句柄
Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; 读取要修改的2个字节
mov ax, word ptr [Buffer]
.IF ax == word ptr [RBuffer] ; 如果判断正确 (75h,15h) 就覆盖他们 :-)
Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ;写入新的代码(90h 90h)
.IF Numb == 2 ; 如果返回值为 2, 弹出成功信息
push MB_OK
push OFFSET AppName
push OFFSET Done ; 弹出信息地址入栈
.ELSE ;如果返回值不是2,那么弹出错误信息
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET WrFile
.ENDIF
.ELSE ; 如果读取的2个字节不正确,弹出文件选择错误信息
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET ReFile
.ENDIF
.ELSE ; 如果未获得文件句柄,弹出文件不存在信息
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET NoFile
.ENDIF
push NULL
Call MessageBox
invoke CloseHandle, hFile ; 关闭文件
invoke ExitProcess,eax ; 退出
end start
如果你看懂了上面的代码,就可以制作自己的文件补丁。当然也可以编写的更人性化一些,比如添加上选择文件路径的对话框,但那就是另外一个题目了。
原文:
Make a standalone patch
1. General Theory
Once you patched a program you cracked, you might want to share it. Instead of uploading the entire executable, you can make a small patch that changes the neccessary bytes.
Now how are we going to do that?
=> First we have to look for the file we have to patch. Most patches suppose that the file is in the same directory.
=> If it's there, we have to open it.
=> Next we should check if it's the exact same file as the one we cracked. We could eg. check the size, or some random bytes, or even better, the bytes we are going to patch.
=> If it is the same, we can do the neccessary adjustments : )
Put the filepointer on the right position, and write the new opcodes to it.
=> Close the file, and give a message about the status.
Take a program you just cracked, or use this example I will use.
Let's code this...
2. API Theory
What API's will we need to code this?
First of all, we will have to open the executable. The suitable API is :
HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
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
);
This API is used for opening, or creating a file.
dwDesiredAccess should be 'GENERIC_WRITE OR GENERIC_READ' because we want to read and write from/to the file.
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'
dwCreationDistribution = 'OPEN_EXISTING' We only want to open a file that is there. If it's not there, the function will fail, and we can give an Error Message.
Check your WIN32.HLP for details. If you don't have this API library, get it in the Reference section.
As you can see the API returns the handle of the file we requested. We need this handle for the next step : writing to the file.
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
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);
We will use this API to write the two bytes to the file (in the right place, of course :)
The handle hFile is the one CreateFile has returned.
lpOverlapped should point to an OVERLAPPED structure. We need this to put the filepointer at the right offset.
typedef struct _OVERLAPPED { // o
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED;
Offset will contain the position where we want to write.
3. The Target
The Target is crackme5.exe, let's say we don't find a valid serial, and we want to patch it.
Of course you are a good cracker : ) and you found the bytes to patch quickly.
Here they are :
Offset 53Fh : 74h, 15h -> 90h, 90h
That's all the information we need : )
4. The Code
; Find the complete source and binary here.
.386
.model flat,stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
.data
FileName db "Crackme5.exe",0
AppName db "Crackme 5 Patch",0
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
RBuffer db 75h, 15h
WBuffer db 90h,90h
OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL>
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndname HWND ?
hFile HANDLE ?
Numb dd ?
Buffer db 2 dup(?)
.const
.code
start:
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
.IF eax!=INVALID_HANDLE_VALUE
mov hFile, eax ; Store handle of file
Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos ; Read the 2 bytes we are going to patch
mov ax, word ptr [Buffer]
.IF ax == word ptr [RBuffer] ; If they are the right ones (75h,15h) we replace them :-)
Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos ; Write the new bytes (90h 90h)
.IF Numb == 2 ; If the number of bytes written = 2, give Done Message
push MB_OK
push OFFSET AppName
push OFFSET Done ; Push Done-Message
.ELSE ; If number of Bytes != 2, Give Error-writing-Message
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET WrFile
.ENDIF
.ELSE ; If the 2 bytes read are not the right ones, Give Error-Version-Message
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET ReFile
.ENDIF
.ELSE ; If the handle was not returned, Give Error-NoFile-Message
push MB_OK OR MB_ICONINFORMATION
push OFFSET AppName
push OFFSET NoFile
.ENDIF
push NULL
Call MessageBox
invoke CloseHandle, hFile ; Close File
invoke ExitProcess,eax ; Exit
end start
If you understand the code above, which is self-explanatory, you can try to make a simular patch for another target.
Now you can make a simple WIN32ASM-patch. Of course we can also make a more user-friendly version eg. with an open-dialogbox to select the target. But that will be covered in a next tutorial about the subject : )
If you have questions, remarks about this tutorial, mail me!
Greetings,
Detten
Detten@tiscali.be
- 编写一个文件补丁
- xml编写一个文件
- 编写一个dll文件
- 内存补丁程序编写
- linux 补丁文件, 一个最简单的patch的格式
- 如何做补丁文件
- diff补丁文件解析
- Linux补丁文件语法
- linux2文件补丁操作
- patch 补丁文件制作
- 补丁文件概述
- 可执行文件内存补丁文件补丁工具
- 如何编写一个文件捆绑工具
- 编写一个简单的proc文件
- 编写一个xml文件,并加上样式
- C++编写一个文件打包工具
- 如何编写一个CocoaPods的spec文件
- 如何编写一个CocoaPods的spec文件
- 动态连接库和钩子
- RP问题
- 知识工作者的消费时代
- JUnit使用指南
- 如何编写Loader
- 编写一个文件补丁
- 简单介绍一下Dian团队(非官方版本)
- 用 AJAX 来控制书签和回退按钮
- 基于mock对象和JUnit框架简化Spring Web组件单元测试
- Visual SourceSafe 数据库安全性简介
- Mark,从今天开始写blog 。
- 我的GMail邮箱使用了500M了
- [c-programming]编译器字节对齐问题-结构字段对齐问题
- WIN32 Virus Run in Ring3