`
thecloud
  • 浏览: 877544 次
文章分类
社区版块
存档分类
最新评论

游戏修改器的基本工作原理

 
阅读更多

所谓游戏修改器,主要是通过修改游戏程序的内存数据或存盘文件来修改游戏中的相关数据,使之达到无敌等效果。

游戏修改器主要分为两类:单一游戏的修改器和通用游戏修改器。顾名思义,前者只能修改特定的游戏,此类修改器也叫无敌引导程序游戏;而后 者则能够以不变应万变,可以修改大多数的游戏。本文主要讨论后者,相比之下,前者是后者只留下修改功能的简化版

总的来说,游戏修改器主要的功能便是反复搜索并筛选某一特定内存地址并将其按照固定的周期修改为特定的值(所谓的锁定),当然,将内存换为文件便可以以同样的方式搜索文件了。

搜索和筛选是如何实现的呢?假如我们已经可以访问游戏的内存,我们将游戏的内存分块读入一个缓冲区,然后借由下面的函数搜索:

//在一个内存块中搜索内容
//
成功返回位置
//
失败返回-1
//(SE:
现在我发现这个顺序查找函数完全可以用STLstd::find()函数取代,原因是写文章的时候我还不太了解STL:)
intMemFind(intiStartPosition,LPBYTEpDestBuffer,intiDestBufferLength,LPBYTEpPatternBuffer,intiPatternBufferLength)
{
signedintiFoundPosition,i;
iFoundPosition=-1;
if(iStartPosition>iDestBufferLength)return-1;
for(i=iStartPosition;i<(iDestBufferLength+1);i++)
{
if(memcmp(&pDestBuffer[i],pPatternBuffer,iPatternBufferLength)==0)
{
iFoundPosition=i;
break;
}
}
returniFoundPosition;
}

由于游戏在内存或文件中保存的数据是二进制格式,因此,当我们搜索一个为123的整数时应用如下的格式:
intnPattern=123

dwOffset=MemFind(nStartPosition,pDestBuffer,nDestBufferLength,(LPBYTE)(&nPattern),sizeof(nPattern))
同样,可以这样搜索浮点类型:
floatrPattern=123

dwOffset=MemFind(nStartPosition,pDestBuffer,nDestBufferLength,(LPBYTE)(&rPattern),sizeof(rPattern))

由于内存中肯定会存在许多相同的数据,所以第一次我们肯定会搜索到许多地址,而真正我们要找的地址一定包含在其中。所以,我们建立一个临时文件将这些地址保存起来,并设置有效标志,如下代码所示:
structCTempItem
{
DWORDdwAddress;
BOOLbEnable;
};
CTempItemitem;
item.dwAddress=?????????;
item.bEnable=TRUE;
fwrite(&item,sizeof(item),1,fp);
接下来,当用户进行第二次搜索时,将这些保存在临时文件中的数据取出来,先看item.bEnable若等于FALSE则跳过,否则读取 item.dwAddress所指示的游戏内存,并于用户第二次输入的数值相比较,若发现相同,则设置item.bEnable=& nbsp;TRUE;若不同设置item.bEnable=FALSE,表示废弃。完成之后,再次把item写回文件,当所有item分析完之后,我们就 完成了第二次搜索。再接下来,bEnable=TRUE的地址还有很多,则仍然用第二次搜索的方式反复搜索,直到剩下1-2个地址为止。& nbsp;SE:应用读写缓冲区,即成批地读写,可以大大加快速度)

由以上介绍可以看出,游戏修改器的搜索分为2个阶段:第一次搜索和第234……次搜索,游戏修改器在第一次搜索出的很多地址中分析出与用户输入的数据 始终相同的地址。当我们有了目标地址,就可以按照用户的意愿定时或手动方式写入用户指定的数据,这便是游戏修改器的基本原理。

当然,这只是基本原理,当具体编写修改器将遇到许多具体的技术困难,以下章节将为您一一解答。

如何访问游戏程序的内存
当我们的修改器运行于Windows时,首先遇到的问题便是如何访问游戏的内存。

首先,在访问游戏的内存前我们还必须获得游戏进程的句柄,这可以通过ToolHelp函数获取系统中当前运行的所有进程的列表和各进程的ID,经由用户选择之后通过OpenProcess函数来获取。若您的修改器运行于后台,而前台是游戏的话,可以在用户按下弹出热键时使用 GetForegroundWindow函数获取游戏窗口的HWND,再使用GetWindowThreadProcessId转换成游戏进程的ID,再 使用OpenProcess函数获取游戏进程的句柄。

有了游戏 进程的句柄之后,便可以使用Windows提供的ReadProcessMemoryWriteProcessMemory这两个API来读写游戏的内 存了。但是,在Windows9x中每个进程均拥有各自独立的1GB虚拟地址空间,而在Win2000/XP下更是达到了2GB。显然,搜索这样大的地址 空间是不现实的,而且游戏也仅仅用了其中的几十到几百MB。所以,我们需要使用VirtualQueryEx这个函数来查询哪些是已经分配的地址,哪些是未用的地址。以下查询与搜索相结合的示范代码:

DWORDdwBaseAddress;
SYSTEM_INFOsi;
GetSystemInfo(si);
dwBaseAddress=si.lpMinimumApplicationAddress;
while(dwBaseAddress<si.lpMaximumApplicationAddress)
{
mbi.BaseAddress=(LPVOID)dwBaseAddress;
ProcessMem.Query((PVOID)dwBaseAddress,&mbi);
VirtualQueryEx(hProcess,(LPVOID)dwAddress),mbi,sizeof(mbi)
dwBaseAddress=(DWORD)mbi.BaseAddress+mbi.RegionSize;
if(mbi.State!=& nbsp;MEM_COMMIT||mbi.AllocationProtect!= PAGE_READWRITE);//
跳过未分配或不可读写的区域
{
continue;
}
//
搜索这块内存区域
}

资源:请到http://alphasun.betajin.com下载我写的一个很简陋的游戏修改器——GameProbe的源程序。
如何实现热键
热键的原理很简单,使用全局键盘HOOK就可以了,鉴于这方面的资料较多,具体的Hook使用方法请参阅MSDN或相关资料。
如何实现暂停游戏
这是游戏修改器必须具备的一项功能了,若不暂停游戏,搜索之前数值很可能会改变,从而造成找不到数据的现象。暂停游戏的办法有很多种,主要有:
1.Debug
法,这种方法利用DebugActiveProcess这个WindowsAPI将游戏修改器作为游戏的调试程序,游戏修改器可通过 Windows提供的调试事件(DebugEvents)来获取游戏的各个线程的句柄。但此法有一个缺点就是不能在关闭游戏前关闭修改器,否则 Windows将会自动终止游戏的运行,运用此方法的典型是FPE2000

2.通过使用 ToolHelp系列函数获取游戏进程的所有线程,并使用公开的OpenThread这个API来获得各线程的句柄并使用 SuspendThreadResumeThread来暂停或恢复游戏的运行,目前大部分程序运用此法。(BTW:著名 的GameMaster使用的是CreateProcess并通过Suspend游戏主线程的方法暂停游戏的,很显然,若游戏采用了多线程,此方法是欠妥的。)

但恼人的是Win9x下并没有 OpenThread这个API,不过我们可以通过一个未公开的使用TCB的方法在Win9x下替代OpenThread而获取 线程的句柄,从而达到了暂停游戏运行的目的。您可以到http://www.windrun.com/;下载Ligtest前辈编写的PauseProcess程序的源代码来学习,或者下载我的TestPopup

如何在游戏中弹出自己的界面
这个问题可以和热键问题一并解决:众所周知,Windows是一个消息驱动的32位操作系统。在Windows中,所有正在运的进程都有一个独立的2GB 的虚拟地址空间,进程之间相互不可见。Windows的绝大多数API与消息是不能跨越进程的。

“Hook” Windows中主要是用来截取消息的,形象说,就是用来消息的。Hook实际上是一个处理消息的程序段,每当特定的消息发出,在没有到达目的窗口前,Hook函数就先捕获该消息,即Hook函数先得到处理消息的控制权。而且如果你把Hook实现在DLL文件中,那么Hook函数将会自动被系统映射到会处理那个特定消息的窗口所在的进程虚拟地址空间中。例如,你可以用Hook来捕获系统中所有的键盘输入消息(WM_KEYDOWN)来 实现对电脑使用者的输入进行记录(关于Windows进程管理与Hook的详细用法,请参阅MSDN与相关资料)。

微软的DirectXWindows下的游戏带来了华丽的声光效果。但是由于DirectX采用直接访问硬件的方法提高多媒体与游戏程序的速度,因此导致了人们误以为在DirectX(确切地说是DirectDraw)下不能显示普通的Windows对话 框。

幸运的是,DirectX是支持GDI的,也 就是说游戏程序可以用常规的方法在DirectX下显示对话框(在微软DirectX8SDK中有名为 “FullScreenDialog”的例子)。所以现在我们的问题变为:如上所述,如何让我们的程序进入游戏的程序的内部并显示对话框。

这似乎是一个很棘手的问题。但是,有了上面所讲的Hook情况就大为不同了。我们知道既然Hook可以映射到别的进程内部,那么只要将显示对话框的函数以及对话框资源包括在HookDLL中不就可以调用DialogBox()了吗?完全正确!我们用SetWindowsHookEx()为系统设置一个键盘消息Hook,系统会自动将这个DLL映射到游戏的进程中。每当有键 盘消息,我们只要判断是不是我们所设定的热键,如果是就调用DialogBox()显示对话框即可。 (SE:还有一种方法可以把DLL插入别的进程,那就是利 用RemoteThread远线程,具体程序请参阅上文提到的PauseProcess程 序。)

您可以参阅我的TestPopup程序,就演示了在DirectX下弹出界面、暂停游戏、热键等功能。

如何调整游戏速度
游戏通常是通过timeGetTimeGetTickCount等几个与时间相关的API来控制速度的。因此,我们只要抢在游戏调用这些API之前调用 它们,并修改返回值,便可以调整游戏的速度了。具体的程序可以参阅我的SpeedMan,您可以免费下载它的源程序。 SpeedMan使用了《Windows核心编程》所提供的CApiHook类来拦 截timeGetTimeWindowsAPI

抓图功能
抓图功能很好实现。具体就是先暂停游戏,再通过使用GetForegroundWindow函数获取游戏窗口的HWND,最后DC就可以获得Bitmap 格式的屏幕图像了,至于如何保存成文件,或转换为Jpeg(可以使用IJLib)等,则不在本文讨论范围里了。

获取进程代码:

#include "stdafx.h"

#include <windows.h>

#include <tlhelp32.h>

int main(int argc, char* argv[])

{

HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);

if (!hSnapshot){

printf("CreateToolhelp32Snapshot ERROR!/n");

return 1;

}

PROCESSENTRY32 pe32;

pe32.dwSize = sizeof(PROCESSENTRY32 );

if (!Process32First (hSnapshot, &pe32))

{

printf("Process32First ERROR!/n");

}

do

{

printf("ProcID:%d---%s/n",pe32.th32ProcessID ,pe32.szExeFile );

}while(Process32Next (hSnapshot, &pe32));

return 0;

}

#include "stdafx.h"

#include "windows.h"

#include "tlhelp32.h"

#include "stdio.h"

int main(int argc, char* argv[])

{

PROCESSENTRY32 pe32;

pe32.dwSize = sizeof(pe32);

HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

if (hProcessSnap == INVALID_HANDLE_VALUE)

{

printf("CreateToolhelp32Snapshot 调用失败./n");

return -1;

}

BOOL bMore = ::Process32First(hProcessSnap,&pe32);

while (bMore)

{

printf("进程名称:%s/n",pe32.szExeFile);

printf("进程ID%u/n/n",pe32.th32ProcessID);

bMore = ::Process32Next(hProcessSnap,&pe32);

}

::CloseHandle(hProcessSnap);

return 0;

}

转自http://hack.gameres.com/showthread.asp?threadid=75739

分享到:
评论

相关推荐

    Unity着色器和屏幕特效开发秘笈PDF高清完全版

    译者序前 言第1章 漫反射着色1.1 引言1.2 创建基本的表面着色器1.2.1 准备工作1.2.2 如何操作1.2.3 实现原理1.2.4 参考1.3 为表面着色器添加属性1.3.1 如何操作1.3.2 如何操作1.3.3 参考1.4 在表面着色...

    C++游戏编程快速入门视频教程 高清不加密

    1.2.5 使用控制器控制游戏 1.2.6 确定游戏模式 1.3 面向对象的编程和游戏 1.3.1 理解OOP 1.3.2 在游戏中应用OOP 1.4 研究相关工具 1.4.1 编译器和开发环境 1.4.2 选择图形工具 1.4.3 选择声音和音乐...

    EUD Editor2 0.17.8.2.zip

    能对大部分游戏数据进行修改(除了基本的单位属性以外还包括按钮、动画、字幕、语音等等) 4.提供反作弊功能(绝对强力)和中文化功能(可以显示中文字幕,进行中文聊天等) 使用方法请自行查询

    C游戏编程从入门到精通(13M)

    按钮和菜单绘制 233 15.3 使用链表 238 15.4 对象事件函数 239 15.4.1 按钮的基本动作 239 15.4.2 菜单的基本动作 240 15.5 进行事件检测 243 15.6 界面例程 244 15.7 游戏实例 245 15.7.1 DOS游戏界面设计 245 ...

    [3D游戏与计算机图形学的数学方法.zip

    通过对本书的学习,游戏开发程序员可以对数学工具的基本原理有着深入的理解。 作为最新版本,本书在内容上做了一些扩充,引入了投影、阴影、物理、布料模拟和数值方法方面的知识。所有章节都重新做了修订,并按照...

    学OpenGL编3D游戏[含全部源码]

    全书以一个完整(基本)的3D游戏为主线,采用循序渐进的方法,从建立OpenGL图形环境入手,讲解3D基本图形、构图原理;从引入摄像机,建立天空、山地、树木,到3D模型使用和3D动画模型的显示。用鱼骨方式讲解相关知识...

    Java典型模块

    第1篇 Java开发必备基础 第1章 搭建Java开发环境 1.1 Java的过去、现在和未来 1.1.1 Java的历史 1.1.2 Java的语言特点 1.1.3 Java API简介 1.1.4 Java未来发展 1.2 Java程序设计环境 ...31.1.1 基本原理 ...

    [游戏开发] 达达房卡麻将二次开发VIP系统学习课程 [MP4] (16.66G)

    │ 第007课TCP网络传送的基本原理.rar- K7 a" O9 M* r0 h- q h6 U │ 第008课node.js使用Net模块搭建TCPserver_client.rar │ 第009课node.js二进制数据与Buffer模块.rar │ 第010课node.js_npm模块的安装和加载.rar...

    phaser-collection:相位器h5小游戏项目集锦

    对于一个前端菜鸟来说,我选择框架的基本原理就是,先入为主,能用,方便用,好用即可。简单的说就是有丰富的示例及代码,然后有完善的文档和社区供解决特定问题。phaser有我说的这些,但是刚开始使用的时候,存在的...

    Windows编程循序渐进.part2

    13.1.4 实例:游戏内存修改器 245 13.2 内存映射文件 249 13.2.1 内存映射文件的原理 249 13.2.2 实例:文件分割器 250 第14章 进程间通信 254 14.1 消息传递机制 254 14.1.1 消息传递 254 14.1.2 实例:...

    Windows编程循序渐进.part3

    13.1.4 实例:游戏内存修改器 245 13.2 内存映射文件 249 13.2.1 内存映射文件的原理 249 13.2.2 实例:文件分割器 250 第14章 进程间通信 254 14.1 消息传递机制 254 14.1.1 消息传递 254 14.1.2 实例:...

    Windows程序设计(第2版)王艳_源代码

     2.5 【实例】游戏内存修改器 第3章 Win32程序的执行单元   3.1 多线程   3.2 线程同步   3.3 设计自己的线程局部存储   3.4 设计线程类——CWinThread   3.5 【实例】多线程文件搜索器  第4章 ...

    VB编程资源大全(源码 其它4)

    g003.zip 代表和平的娱乐游戏,自带EXE(12KB) 596,g002.zip 一个迷宫游戏,还有地图编辑器呢,完全源码(230KB) 597,g001.zip 模仿windows中的扫雷,自带EXE(38KB) 598,p012_prtDB.zip 打印...

    基于51单片机8x8点阵贪吃蛇综合课程设计报告.doc

    31 赣南师范学院科技学院数学与信息科学系 《 贪吃蛇掌上游戏机 》 一、设计任务与要求 基本功能: 制作一个8*8点阵的贪吃蛇游戏,系统以单片机的c语言的软件设计,系统通过LED点 阵屏为载体显示数据,并用四个输入...

    minecraft-world-downloader:下载Minecraft世界

    一个Minecraft世界下载器,其工作原理是拦截并解密客户端与服务器之间的网络流量,以读取和保存块数据。 产品特点 不需要客户端修改,因此无论是否适用于每个游戏客户端 自动合并到以前的下载或现有的世界中 打开...

    基于stm32系统的投喂器控制系统设计+源代码+文档说明

    通过以上功能的结合便能较好的完成对宠物进行远程喂食的功能,实现对宠物的智能投喂,以及通过光电传感器(光电传感器由敏感元件、转换元件、基本电路三部分组成,其主要原理是光电效应。)来监测宠物的实时状况,...

    java源码包---java 源码 大量 实例

    2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性...

    c++ Builder+实例入门陈雪飞清晰版

    15.1.4 CGI的工作原理 15.2 编程思路 15.3 操作步骤 15.4 创意与超越 15.5 本章小结 第16章 网页浏览 16.1 基础知识 16.1.1 什么是WWW 16.1.2 什么是URL 16.1.3 打开URL和连接 ...

Global site tag (gtag.js) - Google Analytics