游戏小常识:2D游戏里,我们看到的人物,帐篷,技能栏都是通过贴图技术在显卡上得以显示的
实战:修改游戏中技能栏图片在屏幕上的位置
一.修改思路
1.游戏的绘图技术→绘图函数→用到坐标→修改它→方案不可行!
原因:A.屏幕上需要用到坐标的地方太多了,很难确定技能栏的坐标,需要一个个的排除
B.游戏一定会对绘图函数这些底层函数进行再次封装,就算拿到数据了也不好分析
2.Ctrl+F9可以显示/隐藏图标,显示代表用到了绘图技术→绘图函数→用到坐标→修改它→可行
猜测:显示/隐藏功能是通过一个bool变量去控制要不要进行绘图
实证:通过CE的数据搜索功能进行实证
当开关为1时,游戏会去调用绘图函数,那它一定会用到坐标。
3.面向对象技术
猜测:猜想游戏中使用到了面向对象技术
实证:当技能栏显示的时候,利用CE的找出是什么访问了这个地址进行取证
如果游戏使用了面向对象的技术,那么UI坐标这个数据一定会在类的成员属性中
观察,修改数据进行测试
怎么生成补丁呢?
- 通过CE的数据观察得知,绿色的代表全局变量;有两种可能,要么是先天赋予的值,要么是后期赋予的值
- 因此我们可以跟随入口点去跟踪他,然后把值给锁定,然后生成补丁
二.使用解决方案2来实现UI的修正功能
目的:不要过度的依赖面向对象的技术,而是要把逆向分析的技术提升到一定的境界,最后再结合上这个技巧。
先上CE,在上x96dbg😎
猜测+推断:通过修改JE的机器码,发现游戏的技能栏那一列不显示了
右键设置条件断点,使游戏在画技能栏这个实例对象的时候停下来
跟进去,继续修改被调用函数里面的JE指令,观察游戏画面,推断绘图函数就在这段代码里面
为什么这种形式的指令,要么是虚函数,要么是函数指针呢?
call dword ptr ds:[eax+C]
当执行0040BF88的CALL,发现这个函数是递归函数,猜测这个有个链表的数据结构,那么推断另一个函数就是绘图函数,真相只有一个✔。修改这个函数的二进制指令,使这个函数的功能失效,验证我们的猜想
尝试修改栈中的数据,发现数据又被改了回来,说明数据是被时时刻刻计算后写入进去的
猜测计算UI的高度和宽度的计算公式:一个变量+一个常量计算而来的。所以我们需要找到这个计算过程,然后就可以下手了。
利用OD的内存写入断点定位到要分析的函数
逆向分析这个函数,猜测EDI地址存储了窗口区顶部,窗口区左侧的相对高度和宽度;通过平移和上移游戏窗口来验证
因此我们可以推断ESI+28就是UI左边的绝对宽度 ;ESI+2C 就是UI顶部的绝对高度
三.制作补丁
1.重新运行游戏,在43D790+28处设置内存断点,找到内存被修改的瞬间
2.寻找合适的位置
通过自己的理智脑和经验猜测这个函数可能是初始化成员变量的地方,不是我们想要的合适点
继续运行,来到了这个函数CALL, 单步运行下去,可以观察到43D790+2C变成了411;可以推断这个函数就是我们要找的那个函数
Ctrl+F9,F7,再次验证了我们的猜想
经过观察,我们猜测在上面的函数执行完后,程序就完成了计算完对应的值,然后写入到对应的内存,这时候我们可以尝试写入我们想要的值
修改0x40BF61处的代码验证我们的猜测
mov eax,43D7B8
mov dword ptr [eax],0xBE
mov eax,43D7BC
mov dword ptr [eax],0x2BB
mov eax,447Dc0
mov dword ptr [eax],0x2FD
mov eax,447Dc4
mov dword ptr [eax],0x287
mov eax,1
RETN 4