样本原件
- taptap上下载最新的:阿xx病毒_1.0.17.apk
- 论坛里可以发外链的样本原件下载吗?望告知,先不发了。
工具清单
- Il2CppDumper-v6.6.2
- ida pro 7.0
- MT管理器
一、破解签名验证
使用MT管理器一键去除签名验证,获取到破解签名的后的apk
二、dump出游戏的函数信息
-
从apk中取出需要的源文件:
-
打开Il2CppDumper,依次选择libil2cpp.so和global-metadata.dat文件, 出现如下结果表示操作成功
-
上步操作将得到几个重要文件
- dump.cs 里面包含了游戏的函数和对应的地址信息
- script.json 后面ida需要用到
三、 ida分析的准备工作
- 打开ida32位,选择new,拖入libil2cpp.so,等待加载完成,时间有点久先去玩会吧
- 加载脚本文件,先选ida.py,再选上面dump出来的script.json
等待脚本运行完成
四、分析dump.cs
用文本软件打开dump.cs,这里要破解背包,背包的常用单词bag,在dump.cs里搜索bag,提一下我是怎么猜到用bag搜索的,在玩游戏的时候,里面有个广告,广告看完会给我解锁几格背包,通过这个线索去分析smali代码里相关逻辑可以看到代码里有bag这种关键词
发现有以下可以的代码:
// RVA: 0x39A3E8 Offset: 0x39A3E8 VA: 0x39A3E8
public int GetCurBagSize() { }
翻译过来就是获取当前的背包格数,尝试修改这个函数的返回值。可以看到函数上面有该函数的地址:0x39A3E8
回到ida软件,按快捷键g定位到0x39A3E8
跳转后右键选择图视图,先按p键添加函数,然后右键选择graph view视图查看流程图,
直接拉到底,查看流程的最终路径,重点关注R0寄存器,因为R0寄存器是用来存函数的返回结果。
光标定位MOV R0, R5这行代码,使用keypatch插件(如何安装请百度或者论坛里找),快捷键ctrl+alt+k
这里我要500个背包格子,所以给R0寄存器赋值500对应的16进制为0x1f4(注意:不要搞太多,否则游戏直接卡死),获取到7D 0F A0 E3这条指令,然后用MT编辑libil2cpp.so,用16进制编辑器打开,跳转到地址0039A4EC,然后将指令改成7D 0F A0 E3。修改后保存退出并在mt里保存并重签名,再安装处理后的apk。
打开游戏,发现游戏里的背包格子已经变成了500格,但是实际测试还是只能带10个格子的物品,这里的修改至少修改了显示效果。
五、如法炮制、继续分析
按上面的思路,继续搜索dump.cs里可疑的函数,发现以下代码很可疑
// Namespace:
public class CContainerBag : CContainerBase // TypeDefIndex: 5556
{
// Methods
// RVA: 0x4FB4D0 Offset: 0x4FB4D0 VA: 0x4FB4D0
public void .ctor() { }
// RVA: 0x4FB580 Offset: 0x4FB580 VA: 0x4FB580 Slot: 6
public override bool AddMateriel(ulong UID) { }
// RVA: 0x4FBFAC Offset: 0x4FBFAC VA: 0x4FBFAC Slot: 10
public override int GetCanAddNum(int nModelId) { }
}
CContainerBag里的GetCanAddNum,这个意思是获取可以添加的数量,我猜测这是指可以放进背包里的物品数量,结果证明我猜的是对的。把这个数量调的很大就可以。剩下的我先不说了,你们自己按上面的思路去改吧~
还有几个函数需要改的,提前透露下:
-
CContainerBase里的GetGridSize, 改这个是野外的时候背包的数量正确显示作用
// RVA: 0x4FE428 Offset: 0x4FE428 VA: 0x4FE428
public int GetGridSize() { }
-
GetGridLeft 改这个是解决一个bug,武器放到身上,在野外脱不下来即使背包里显示有格子
六、修改清单
-
0039A4EC处修改为7D 0F A0 E3
- 对应函数:GetCurBagSize (获取家中当前背包格子数量)
- arm指令:MOV R0, #0x1f4
- 16进制指令:7D 0F A0 E3
- 作用:家中背包格子显示数量,这个只是个显示作用
-
004FC6AC处修改为FF 0F 0F E3
- 对应函数:GetCanAddNum (获取家中当前可以添加的物品数量)
- arm指令:MOV R0, #0xffff
- 16进制指令:FF 0F 0F E3
- 作用:真正的可以添加无限的物品
-
004FE428处修改为 7D 0F A0 E3
- 对应函数:GetGridSize (获取野外当前背包格子数量)
- arm指令:MOV R0, #0x1f4
- 16进制指令:7D 0F A0 E3
- 作用:野外正确显示背包格子,显示作用
-
004FE408处修改为 7D 0F A0 E3
七、关键思路总结
之前都是破解smali层的代码,so层这是第一次尝试,ida也是第一次用,基本是靠参考论坛里的帖子和百度的。我这个破解过程主要是看流程图,对汇编代码没有看(也看不懂...), 因为我定位的这些函数都比较简单,函数的作用都是获取什么数值结果(getxxx),所以我主要是分析流程视图,重点关注路线的重点,有时候就1个终点,有时候有2个甚至多个,这种情况可以先关注到达终点路径比较多的那个终点(有点绕)。然后终点关注R0寄存器,使用MOV指令强行修改R0寄存器的值。要多试,不要怕失败。
|