免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
内容参考于:易道云信息技术研究院
上一个内容:79.游戏分析工具闪屏问题优化与数据被修改高亮
GAMEHACKER2.exe 工具下载地址:79.游戏分析工具闪屏问题优化与数据被修改高亮
Sword2(剑侠情缘)这个游戏很老,在它的年代显示器分辨率是640*480(640是宽480是高),现在的分辨率最低也是1920*1080,高端显示器分辨率是4K、8K甚至更高的分辨率,用最低的1920*1080分辨率显示640*480看起来是非常的模糊,所以首先要修改游戏的分辨率,至少要改成1920*1080分辨率。
修改分辨率的思路是从游戏如何显示的地方下手,这样才会有机会修改分辨率,首先要搞清楚游戏是如何显示的然后在显示的时候肯定会用到640、480这俩数据,然后找到用640、480这俩数据的位置就可以分析出这俩变量的内存地址在哪了,然后更改这俩变量的值从而达到修改分辨率的效果。
然后显示的方式,显示是一个非常大的工程,做游戏一定会用到游戏引擎也就是会用到显示的技术,显示技术主流的有三种 GDI/GDI+、OpenGL、Direct
GDI/GDI+:微软公司提供比如窗口的界面全部用的GDI/GDI+技术
OpenGL:linux系统下用的多
Direct:是图形加速接口,它可让以windows为平台的游戏或多媒体程序获得更高的执行效率,加强3d图形和声音效果,微软提供的
然后查看游戏使用的是那种技术
首先打开Cheat Engine附加到游戏上并随便搜索一个数据
然后选择浏览相关的内存区域
如果用了某个显示技术一定会加载显示技术提供的类库或者函数,然后选择 枚举DLL和符号表
然后可以看到它有一个GDI32,这说明这个游戏有用到GDI的技术,如果没用到GDI的技术它不可能有GDI32这个模块,但是只看GDI不能作准它有可能用来GDI与OpenGL或GDI与Direct,因为画一个按钮也会用到GDI的技术,GDI的技术太普遍了,然后继续往下看,如果用到了OpenGL一定会有OpenGL.dll或者OpenGL32.dll这样的模块
然后游戏引擎比如Unity,游戏引擎和显示的关系是游戏引擎通过显示技术(或者说绘图技术)开发出的一个程序或者类库,也就是说就算用的引擎最终还是会用到 GDI/GDI+、OpenGL、Direct 这三种技术的
然后继续往下找可以看到它用了一个DDRAW的模块,这个模块是Direct,d3d9_x.dll类库是Direct9的类库,DDRAW.dll是Direct7或8的类库,然后剑侠情缘这个游戏就用的是Direct技术实现的显示,然后下一步弄清楚Direct是如何显示图形的就可以修改分辨率了
Direct是微软提供的所以去微软查资料
传送门:DirectDraw - Win32 apps | Microsoft Learn
不管Direct9还是7它本质上是一个类,是类用的时候就会创建对象,创建对象就有构造方法,所以先从文档中找构造方法,它有两个构造方法DirectDrawCreateEx 与 DirectDrawCreate,有了对象之后就可以利用对象在屏幕上画图了,证明游戏有没有用到那就在游戏一起启动就在这俩函数上下断点
然后使用 DirectDrawCreateEx 或 DirectDrawCreate只是得到了一个绘图对象指针,在绘图开始之前要做有几个函数必然要用到的第一个设置绘图的模式 SetCooperativeLevel 函数,它是一个纯虚函数没有任何实现,需要自己重写
然后还会用到 SetDisplayMode 函数,它也是一个纯虚函数,SetDisplayMode是就是用来设置分辨率的
SetDisplayMode的参数中文翻译,所以我们就拦截 SetDisplayMode 函数就可以反向追踪分辨率的变量在哪了。
然后打开Ollydbg.exe追踪函数,首先打开之前写的 GAMEHACKER2.exe工具,选择暂停和调试然后打开游戏,暂停的原因是我们要在游戏启动前下断点
然后打开可执行模块,随便点一个进去
进来之后CTRL + G,输入,DirectDrawCreate跳转到DirectDrawCreate函数中,原因是设置分辨率的函数是一个虚函数我们不知道函数地址,CTRL + G也跳不过去,所以要通过调用 DirectDrawCreate函数的位置往下找,如果 DirectDrawCreate函数CTRL + G跳不过去说明Ollydbg.exe还没把模块加载全,等待加载完就可以跳了
DirectDrawCreate函数入口打断点并运行游戏让它卡在断点处
卡在断点处了,剑侠情缘这个游戏是有检测多开的,如果卡不住看看是不是打开过游戏了
然后它的返回地址是6A51CB92
然后在6A51CB92处再打断点
然后按F9让它运行到6A51CB92位置,然后按两次f7
然后再按一次f7,这时就来到了游戏模块了
然后按CTRL+F9往前跳然后再按F7就会来到下图,可以看到调用了一排函数,通过上面说的函数调用顺序 DirectDrawCreate -》setcooperativel -》SetDisplayMode,然后下图中可以看到ASCII字符,这时代码中写的程序出错用来调试的提示,这也可以看出我们写代码时,这种提示不要用ASCII这样的明文信息这样就给逆向者提供了很大的助力因为现在我们可以看到它怎么调用的,正确的找SetDisplayMode函数是通过计算SetDisplayMode偏移得到的而不是通过无脑的分析,后面写如果计算SetDisplayMode函数偏移,这里先利用ASCII提示来找SetDisplayMode函数
在调用SetDisplayMode函数的位置打断点按F7
然后进入
然后按F8执行到下图红框位置可以看到EDX的值是取得全局变量然后它的值是十六进制的1E0换成十进制就是480
然后再按F8执行到下图红框位置可以看到edx的值是十六进制的280换成十进制就是640,所以很明显4391F0位置是480、4391EC位置是640这俩就是分辨率
然后我们这俩数据在栈中修改成1980*1080,修改方式是右击选择修改
点击修改之后弹出下图红框位置的弹框
直接写1920然后点确认,480改1080也是这样操作
修改之后的栈数据
然后直接让游戏继续运行
然后分辨率就被修改了