愉快的玩Win32 SDK开发 - Fairy Fencer F修改

二周目后没事做于是写了一个用来修改游戏数据的小程序,与上次的那个C++写的控制台版不同,这次我做了一个GUI的,用的是纯C + Win32 SDK。

Screenshot

游戏貌似有做过反调试,OD附加不了,不知道为什么。至于基址我只找到了金币的,其他的比如人物数据好像有加密太难找所以放弃了。反正如果修改其他的也会严重降低游戏的乐趣。


0x01: UI设计

UI


0x02: 消息处理函数

Code1

都写了注释不用多说。


0x03: 初始化什么的就交给InitProgram()了

1
2
3
4
HANDLE InitProgram(
_In_ HWND hDlg,
_Out_ DWORD *dModuleAddress
);

Code2

  • FindWindow()发现并获得窗口句柄
  • GetWindowThreadProcessId()传入窗口句柄得到Pid
  • OpenProcess()得到想要的游戏句柄并传回主函数
  • GetModuleAddress后面再详细介绍

有一点需要注意的是,OpenProcess在Vista以上系统中需要更高的权限,一开始我试过提权SE_DUBUG,但OpenProcess仍然返回NULL,查一下错误代码说是权限不够,以内置管理administrator运行问题解决。

Code2

所以最后我把工程中的那个UAC Excution Level 设置为”Require Administrator”,这样程序如果在Vista以上版本Windows中运行经过UAC确定后也能获得和内置管理员一样的权限。


0x04: 获取游戏的模块地址

看上去感觉好复杂,至于为什么要用到这个函数,答案是系统的变迁。在当年XP时代,申请地址都是从是00400000开始的,例如这样的地址+偏移 : “FairyFencer.exe + ABCD”等价于”00400000 + ABCD”。而到了Vista以后,PE头文件的地址会变动,不再是固定的00400000。然后也就用到了下面这函数。

1
2
3
4
DWORD GetModuleAddress(
_In_ HWND hDlg,
_In_ DWORD dPid
);

Code3

最后返回一个DWORD地址值, 过程如下:

  • 定义了一个 MODULEENTY32 的结构体变量 ModuleEntry
  • 把Pid赋给其成员th32ModuleID
  • 成员swSize的值设置成结构体MODULEENTRY32的大小
  • CreateToolHelp32Snapshot创建快照
  • 遍历模块直到找到FairyFencer.exe为止
  • 成员modBaseAddr的值就是模块地址,return dModuleAddress
  • 具体的参数和用法请查阅MSDN

0x05: 核心函数,修改内存数值

1
2
3
4
5
6
BOOL Cheat(
_In_ HANDLE hGameHandle,
_In_ UINT uType,
_In_ DWORD dValue,
_In_ DWORD dModuleAddress,
);

Code4

  • 4个传入参数分别是游戏句柄,修改的类型,修改值,模块地址
  • 3个DWORD形变量表示基址,2级和3级地址
  • switch()根据uType判断修改的类型然后进行相关读写内存操作

到这里就结束了


0x06: 测试

Program

Test

最后附上工程源码及成品链接:http://pan.baidu.com/s/1pJGb6Fx

Copyright © 雪峰 2015
先前发表在我的Qzone中,现在搬运过来,谢谢大家的支持.
原文链接: http://user.qzone.qq.com/806361380/blog/1441012553