2017年计算机等级考试二级C++辅导:制作一个简单的游戏修改器

时间:2017-06-08 15:26:00   来源:无忧考网     [字体: ]

  一、制作背景和原理:
  在平时玩游戏的过程中,大家肯定会接触过形形色色的修改,特别是看到一些高手出的某某全能修,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;
  }