一、制作背景和原理:
在平时玩游戏的过程中,大家肯定会接触过形形色色的修改,特别是看到一些高手出的某某全能修,x项修改器,煞是羡慕,其实制作这样写一个这样的修改器一点也不神秘, 好了,请各位看官一同随我去揭开修改器之谜......“修改器”程序的就是修改我们想要数据的地址里面的数值,这句话比较拗口,但是这是“修改器”程序的关键。下面就以时兴的Normal tanks(坦克大战)为例,和大家讨论怎样去DIY一个游戏修改器请大家移步且随我步骤慢慢来。
二、找到我们想要的内存地址:
这是很关键的一步, 给大家介绍一款优秀的内存编辑工具)。
在游戏中按热Ctrl+Tab返回桌面,在Quick Memory Editor中点击Add Task 。
搜索炮弹的数量,当前游戏中是50,在Search value中填入50,然后点击Search,搜索速度很快,这会出来很结果,然后回到游戏里,随便放几炮,当前炮弹数量变为了47,然后返回桌面,在Quick
Memory Editor中的Search value中填入47,点击Search, 这时候出来了几个结果,结果还是不是很精确。返回游戏,再随便放几炮,当前炮弹数量变成了43,再在Quick Memory
Editor搜索43,这时候出来了仅一个结果,这就是我们需要的内存地址了,记下来004C9C84,等会儿我们要用到。
三、介绍两个关键 API函数ReadProcessMemory()和 WriteProcessMemory():
详细的注释我表明在函数里
①BOOL ReadProcessMemory(
HANDLE hProcess, // 目标进程句柄
LPCVOID lpBaseAddress, // 读取数据的起始地址
LPVOID lpBuffer, // 存放数据的缓存区地址
DWORD nSize, // 要读取的字节数
LPDWORD lpNumberOfBytesRead ); // 实际读取的数据大小地址
ReadProcessMemory()用于读取游戏进程中制定的内存数据; 在实际操作中,我们用它来读取存放炮弹数量地址中的数据。
②BOOL WriteProcessMemory(
HANDLE hProcess, // 目标进程句柄
LPVOID lpBaseAddress, // 进程的起始地址
LPVOID lpBuffer, // 数据内容
DWORD nSize, // 需要写入的字节数
LPDWORD lpNumberOfBytesWritten); // 实际写入的数据大小的地址
WriteProcessMemory()和上面的ReadProcessMemory()用法一样,在实际操作中,我们用它来修改存放炮弹数量地址中的数据。
四、编程实现游戏修改(完整代码):
#include
HINSTANCE g_hInst;
HWND g_hWnd;
char szAppName[]="TankFix"; //The name of the exe
char szTitle[]="坦克大战修改";
DWORD addr=0x004C9C84; //存放炮弹数量的内存地址
DWORD pid; //坦克大战的PID
int val=1000; //炮弹要修改的数量
//-------------------------------------------------------------------------------------------------
// WndProc- 窗口函数
//-------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
{
// int wmId,wmEvent;
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_TIMER:
{
HWND hw=FindWindow(NULL,"Normal-tanks"); //FindWindow()得到坦克大战程序的句柄
HANDLE hProcess; //定义坦克大战的进程句柄
if (hw!=0)
{
SetForegroundWindow(hw); //使我们的坦克大战设置为当前窗口
GetWindowThreadProcessId(hw,&pid); //得到游戏的PID号
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid); //打开进程PROCESS_ALL_ACCESS参数,制定进程可读可写
WriteProcessMemory(hProcess,(LPVOID)addr,&val,4,0); //向坦克大战进程内存中写入数据
}
else
MessageBox(g_hWnd,"游戏还没有运行吧!","提示信息",MB_OK|MB_ICONINFORMATION);
}
default:
return (DefWindowProc(hWnd,message,wParam,lParam));
}
return 0;
}