逆向思路:先进行思路的设计,然后再动手分析
实战:修改游戏分辨率640×480变成1920×1080
一. 分析思路
- 游戏显示→用到了分辨率这个数据→跟踪到数据源头→修改数据
游戏显示用到什么技术呢?答:绘图技术
GDI/GDI+:
openGl:Linux下用的比较多
Direct:
这款游戏用到的显示技术,一定会有某种特征存在。我们可以用CE去找到这个特征,从而得知游戏用到了什么技术!
经过CE实证得出游戏绘图技术是Direct技术
- 通过在msdn的查找和对技术的猜测,游戏加载对应的模块以后一定会执行DirectDrawCreateEx 或DirectDrawCreate
实证:在DirectDrawCreate,DirectDrawCreateEx下断点,通过逆向分析和Ctrl+F9,F7,把调用DirectDrawCreate的函数框架描绘出来
-
最后分析到了使用到屏幕分辨率的地址,然后通过修改栈上的数据(1920×1080),运行,验证了自己的猜想是正确的。
提出问题:为什么我们在x96dbg跳转到SetDisplayMode函数,跳转不过去呢?
二.确定虚函数的地址
理论知识:这个函数是DLL里面的函数,我们可以利用Window的Dll的一个特性:系统xxxx.dll在每个进程中的基址相同
LPVOID lDx{};
DirectDrawCreateEx(NULL, &lDx, IID_IDirectDraw7, NULL);
if (lDx) {
LPDIRECTDRAW7 lDx7 = (LPDIRECTDRAW7)lDx;
lDx7->SetDisplayMode(1, 2, 3, 4, 5);
}
实证:在测试进程中得到SetDisplayMode的地址,然后下断点,运行游戏。
总结:通过确定虚函数地址,我们也可以把调用函数的框架描绘出来。
三.制作补丁
- 通过对SetDisplayMode函数的逆向分析
int global_43d740 = 1;
int global_4391F8 = 0x10;//bpp
int global_43d75C = 0x698880;//Direct指针
int global_4391F0 = 0x1E0;//height
int global_4391EC = 0x280;//width
void SetDisplayMode() {
int num1 = 0;
int num2 = 0;
int width = 0x280;
int height = 0x1E0;
if (global_43d740) {
setDisplay(,,,)
}
}
发现规律:我们可以通过去改变全局变量宽度和高度数值,达到改变游戏的分辨率;