发布于:2017-5-15 17:36 | 284569次阅读 作者: 管理员 | 原作者: TP | 来自: 原创
外挂描述 前段时间,游戏蜂窝出现一款名为腾讯桌球瞄准线辅助的外挂, 该外挂的功能如下图所示,玩家只要使用了该外挂既可延长瞄准线的长度。 实现原理 外挂首先通过下面这些文件,注入其中的libT_Ball.so到游戏进程里面。 libT_Ball.so模块在游戏启动时就注入到里面,然后开启一个线程,每隔一段时间扫描pocket.tencent.com.PocketCueUI:: drawBallTrace的字节码,一旦找到后,记录下来,然后取偏移修改0xE8和0x280的位置,填充一段字节码“22 00 00 40 40 00 00 00 00 00 00”。 然后后面mono引擎会把这段opcode编译成arm指令,最后执行的逻辑就被改变了。下面是修改前后对比图,左边是原逻辑,右边是修改后的逻辑。修改的是两根线的画出来的长度,一根被打球的方向线,另一个的白球弹开的方向线。外挂使得本来应该是乘以BallTrace的逻辑改成了直接乘以 3.0。 BallTrace本来是一个很小的值,比 3.0 小很多,如果直接乘以 3.0 ,那么画出来的线的整体长度就会增加,从而实现了外挂功能。 分析过程 分析过程中因为笔者一开始跳进了一个错误的大前提而浪费了分析时间,不过最后是推翻了原来的大前提而得出了分析结论了。下面就沿着之前的思路开始说起整个分析过程吧。 首先,使用外挂,发现精准的延长线,看得出不是因为识别UI而画线的,那么极有可能有进程在影响着游戏的逻辑。这个时候笔者尝试在进程的maps(cat /proc/pid/maps)中看是否有端倪,结果是看出来了,确实有进程注入。 进入/data/T_Ball目录,可以发现有四个文件,Injector很明显就是做注入操作的,这个时候可以不用管用什么方式注入的,反正就是注入了(这里说明下,外挂是直接注入的),注入的就是libT_Ball.so这个模块。 下面直接可以分析这个模块了。 首先要看看有没有使用常用的Hook模块,MSHookFunction,导入表看是否有导入这些函数,发现没有,暂时认为是没有Hook操作,这里当然不能排除自己写Hook指令。IDA打开libT_Ball.so,分析发现作者竟然没有抹去Log,这里可以直接运行一次外挂,然后在adb里面查看log,如下: 整个外挂流程已经很明显了,修改内存,实现外挂功能。因为之前对腾讯桌球进行过TDR验收,这里看得出来Trace的意思在桌球中代表瞄准线。这个时候,笔者马上认为外挂通过修改内存修改了桌球瞄准线的变量,影响了瞄准线长度,下面基于这个大前提分析下去。 找到了so的起始函数soMain,从这里下去分别把有关函数和变量都重命名了下。 下面跟进这个函数继续分析,有如下函数:
进入函数后有一个循环,隔一段时间sleep,直到找到进程名为“com.tencent.pocket”以及SearchTraceBase成功为止,这个时候外挂已经通过get_map_info_from_proc_name函数开辟了一大片内存来保存获得的进程maps信息。后面执行ModifyTrace函数。跟进SearchTraceBase下去,发现会有一段的过程,如下: 经过上面一大段的处理,最终其实v9 指向的串还是下面13个字节,因为笔者尝试在外挂注入游戏时对其模块进行Hook,并dump出了v9 的字节流,如下: 逐渐分析到如下函数search_tracebase: 获得可能的目标值,放在array_global_3[]数组中,array_global_3[0]保存着个数,后面保存的是地址值,然后执行下面的ModifyTrace。 判断字节前三个值是否为“03 3a 5f”,如果是的话,字节修改其偏移地址的值。 到了这里,笔者认为外挂很可能改的是和瞄准线有关的变量值,并坚持应该不会有什么问题了。这个时候笔者Hook住writeMemory函数,dump出如图上面的v8 的地址值所指向的size为11的内存,是“22 00 00 40 40 00 00 00 00 00 00”。 然后笔者基于“外挂应该是修改了成员变量数据或者非逻辑堆栈数据”的前提,做了很多工作,去想为什么外挂作者能够得到那一段恒定的字节流,并且去搜索取偏移修改。开始的时候,通过内存断点断在了外挂需要修改的位置,然后得出了的信息全部都是mono模块对这些字节进行读写,一直想不懂为什么不是游戏逻辑去读写这些内存,尝试换地址测试,得出的结果还是一样,都是mono的模块对地址进行读。 这里列一下外挂搜索出的地址偏移为0x280位置原先的字节流和替换的字节流如下: 原来的字节流:02 76 4f 14 00 04 6f 29 09 00 06 改后的字节流:22 00 00 40 40 00 00 00 00 00 00 笔者甚至已经确定了这个“00 00 40 40”一定是浮点型的数据 3.0 ,然后思考对应d的四字节“76 4f 14 00”是什么,这个完全不是标准的浮点格式。没想出来,那就从访问这些地址的mono模块入手,一开始还没想出来是什么,甚至在想游没有可能修改了引擎的 东西,然后又想如果是修改引擎不可能这么准确光影响了那根瞄准线的。接着笔者又断了相邻位置的内存地址,还是这几个东西,如下: 看到了这个opcode的取值还没开始想出这些是什么东西,因为笔者的大前提很坚固,修改了内存成员变量或者非逻辑的堆栈数据。 后来再看见了这个大循环,怎么看也像是opcode的选择执行,这个时候大前提有点动摇了。直接试图看看0x22是什么opcode,这个时候下载了一份mono的源码: 笔者用Source Insight打开源码,找到了那个switch大循环,并且交叉引用找到了一份表,如下: 找到了0x22对应的opcode, ldc.r4,然后马上想到后面那个“00 00 40 40”,恍然大悟,这个命令是 ldc.r4 3.0 ,后面的 00 是 nop的意思。这个时候,笔者之前认定的大前提被否定了。外挂修改的是opcode。这个时候,笔者马上想到了原来之前定点搜索的位置是另一个opcode。 把腾讯桌球的Assembly-Charp.dll拖进IDA,搜索字节流“03 3a 5f 00 00 00 02 7b”,结果如下: 这原来正正就是drawBallTrace的函数头: 然后偏移 0xE8 和 0x280,结果意料之中,直接patch原来的opcode,下面选取0x280的位置截图,如下: 最后,得出了上面外挂原理中的截图,把修改后的dll和修改前的进行对比,发现了外挂影响的是游戏逻辑,而不是游戏所使用的成员变量或非逻辑的堆栈数据 |
最新评论
查看全部评论(1)
发表评论