游戏日志输出协助定位
定位游戏内关键数据的方法有多种,接下来笔者介绍一种比较巧妙的方法——根据游戏日志数据协助定位(适用于日志比较丰富的游戏)。有时候在复杂的游戏系统中定位自己想要的数据无异于大海捞针,这时结合游戏日志协助定位可能会有意想不到的效果。
本节以LOL为例,介绍使用游戏日志在定位游戏数据中的使用方法。背景:一般制作模拟按键的外挂,首先需要获取游戏当前的分辨率(如图 1所示)来判断当前窗口的大小,方便下一步模拟鼠标点击相关代码的开发。
图 1
那么如何定位出游戏当前分辨率和窗口模式数据呢,接下来将结合游戏日志进行尝试分析。
一.获取游戏日志
有两种方法可以获取当前对局的游戏日志:
1)直接打开“英雄联盟GameLogsGame - R3d Logs”,每局都有对应的日志文件。
2)手动dump,首先运行DebugView,再运行游戏,然后以游戏进程ID过滤日志,如图2所示,最后将游戏日志全量保存。
图 2
二.日志初步分析
LOL日志主要分为五种类型:“OKAY”,“WARN”,“ERROR”,“ALWAYS”,“COUNT”。游戏开发人员可能关注更多的是错误和警告,对于我们要想分析游戏,主要关注“ALWAYS”,它表示游戏的一些常规日志。只要细心我们便可从中发现很多蛛丝马迹,来协助我们定位游戏的关键数据或逻辑。图 3为提取的“ALWAYS”日志效果图。
图 3
从图3中便可以看到游戏的一些初始化信息。下面我们搜索“1920”来定位游戏分辨率相关信息,从图 4中可以看出游戏日志中确实存在分辨率和窗口模块相关数据。
图 4
三.日志结合逆向分析
使用PChunter Dump LOL核心模块(League of Legends.exe,本测试用例为6.4版本),用IDA以Binary方式打开核心模块,如图 5所示。
图 5
根据图 4日志字符串我们可以快速定位到游戏附近代码,然后分析上下文寻找保存游戏分辨率的数据,依次对下面四个日志进行定位。
日志1:r3dRenderer::SetMode: Trying resolution 1920x1080, bpp 32, windowMode 0, vsync off
日志2:In Riot::Win::Resize: Initial VideoMode(8cca018) and resolution (1920 x 1080)
日志3:In Riot::Win::Resize: Resized window to resolution 1920x1080
日志4:rr3dRenderLayer::InitDevice(XRes = 1920, YRes = 1080, BPP = 32, Flags=1024) enter
根据字符串的交叉引用分别可以找到对应的代码处,通过简要分析即可发现日志4的代码上下文存在全局变量,如图6所示。
图 6
根据打印日志处函数可以定位到XRes和YRes,然后会发现游戏会将XRes和YRes分别写到[0x157112C] + 0x20和[0x157112C] + 0x24处。通过CE验证数据的正确性,如图7所示,改变分辨率,监控的数据也会变化。
图 7
这样通过日志我们就可以快速定位到游戏关键数据在内存中的基址+偏移了。我们可以编写简易Demo进行测试,核心代码如下:
#define LOL_XYRES 0x157112C //游戏6.4版本,版本变化全局变量也会变化
while (true)
{
__try
{
DWORD dwXRes = *(DWORD *)(*(DWORD *)LOL_XYRES + 0x20);
DWORD dwYRes = *(DWORD *)(*(DWORD *)LOL_XYRES + 0x24);
DBGOUT(("[ReadXYResThread]: %d X %d", dwXRes, dwYRes));
Sleep(1000);
}__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGOUT(("[ReadXYResThread]: Except!"));
return FALSE;
}
}
验证效果:
图 8
如图8所示,在游戏分辨率改变时Demo可以实时监控到。
四.总结
结合游戏日志协助定位关键数据是一种巧妙的方法,但不一定适合所有游戏。在拿到一个游戏时,不妨先对它的日志进行大致的梳理,标记出比较重要的日志,若发现分析出比较重要的信息,便可结合字符串交叉引用快速定位。