二周目后没事做于是写了一个用来修改游戏数据的小程序,与上次的那个C++写的控制台版不同,这次我做了一个GUI的,用的是纯C + Win32 SDK。
游戏貌似有做过反调试,OD附加不了,不知道为什么。至于基址我只找到了金币的,其他的比如人物数据好像有加密太难找所以放弃了。反正如果修改其他的也会严重降低游戏的乐趣。
0x01: UI设计
0x02: 消息处理函数
都写了注释不用多说。
0x03: 初始化什么的就交给InitProgram()了
1 | HANDLE InitProgram( |
- FindWindow()发现并获得窗口句柄
- GetWindowThreadProcessId()传入窗口句柄得到Pid
- OpenProcess()得到想要的游戏句柄并传回主函数
- GetModuleAddress后面再详细介绍
有一点需要注意的是,OpenProcess在Vista以上系统中需要更高的权限,一开始我试过提权SE_DUBUG,但OpenProcess仍然返回NULL,查一下错误代码说是权限不够,以内置管理administrator运行问题解决。
所以最后我把工程中的那个UAC Excution Level 设置为”Require Administrator”,这样程序如果在Vista以上版本Windows中运行经过UAC确定后也能获得和内置管理员一样的权限。
0x04: 获取游戏的模块地址
看上去感觉好复杂,至于为什么要用到这个函数,答案是系统的变迁。在当年XP时代,申请地址都是从是00400000开始的,例如这样的地址+偏移 : “FairyFencer.exe + ABCD”等价于”00400000 + ABCD”。而到了Vista以后,PE头文件的地址会变动,不再是固定的00400000。然后也就用到了下面这函数。
1 | DWORD GetModuleAddress( |
最后返回一个DWORD地址值, 过程如下:
- 定义了一个 MODULEENTY32 的结构体变量 ModuleEntry
- 把Pid赋给其成员th32ModuleID
- 成员swSize的值设置成结构体MODULEENTRY32的大小
- CreateToolHelp32Snapshot创建快照
- 遍历模块直到找到FairyFencer.exe为止
- 成员modBaseAddr的值就是模块地址,return dModuleAddress
- 具体的参数和用法请查阅MSDN
0x05: 核心函数,修改内存数值
1 | BOOL Cheat( |
- 4个传入参数分别是游戏句柄,修改的类型,修改值,模块地址
- 3个DWORD形变量表示基址,2级和3级地址
- switch()根据uType判断修改的类型然后进行相关读写内存操作
到这里就结束了
0x06: 测试
最后附上工程源码及成品链接:http://pan.baidu.com/s/1pJGb6Fx
Copyright © 雪峰 2015
先前发表在我的Qzone中,现在搬运过来,谢谢大家的支持.
原文链接: http://user.qzone.qq.com/806361380/blog/1441012553