【软件逆向-安卓真机无root环境下的单机游戏修改-IL2CPP】此文章归类为:软件逆向。
前言
之前在研究手游的il2cpp修改,选取了 Mine Survival
作为研究对象,由于手上没有root的机子,于是安装在了MuMu模拟器上
但是很快发现了问题,游戏只有arm的lib,由于一系列原因,导致我无法获取到 libil2cpp.so
的基址
在尝试了很多方法后都无法完美的解决这个问题,最终只能考虑安装在真机上了
但是目前并没有对机子root的打算,于是选取了注入 frida-gadget
的方案,这样没有root也可以对游戏进行修改了hhh
准备工作
基础工作不做过多介绍,学这个的应该都懂一点
我的设备
- 安卓真机 - Redmi Note 8
- 电脑 - Win10 专业版 22H2
推荐使用 ,可以将手机画面投屏到电脑,延迟低
开始操作
注入 frida-gadget
介绍
可以手动操作去理解原理,参考这篇文章
当然我这种懒汉肯定是选用自动化方案啦,使用 来自动化patch apk
安装 objection
- python版本 3.4+
- pip3版本 9.0+
- (可选)virtualenv版本 15+
全局安装
1
|
$ pip3
install
-U objection
|
虚拟环境安装
为了防止冲突,推荐安装在虚拟环境里
1
2
3
4
5
6
|
$ virtualenv myenv
$ .\myenv\Scripts\activate
$ pip3
install
-U objection
|
patch apk
确定以下命令安装并且可用,将其添加到环境变量中
- aapt -
- adb -
- jarsigner -
- apktool -
adb连接上安卓设备,执行下面的命令,就可以自动化的帮你patch好apk了
1
|
$ objection patchapk --
source
'.\Mine Survival_v2.5.3.apk'
|
安装测试
将Mine Survival_v2.5.3.objection.apk
安装到手机
1
|
$ adb
install
'.\Mine Survival_v2.5.3.objection.apk'
|
然后执行一下 frida-ps -U
,有如下回显就是成功了
1
2
3
4
|
$ frida-
ps
-U
PID Name
----- ------
21709 Gadget
|
测试一下,写个获取 libil2cpp.so
基址的脚本
1
2
3
4
|
Java.perform(
function
() {
var
module = Process.getModuleByName(
"libil2cpp.so"
);
console.log(module.base);
})
|
注入js
1
|
$ frida -U Gadget -l .\hook.js
|
可以看到成功获取到了libil2cpp.so
的基址
frida-il2cpp-bridge
很好用,不多解释了
安装测试
执行下面的命令来安装 frida-il2cpp-bridge
1
|
$ npm
install
--save-dev frida-il2cpp-bridge
|
修改 package.json
1
2
3
4
5
6
7
8
9
10
|
{
"main"
:
"index.ts"
,
"scripts"
: {
"prepare"
:
"npm run build"
,
"watch"
:
"frida-compile index.ts -w -o hook.js"
},
"dependencies"
: {
"frida-il2cpp-bridge"
:
"^0.9.0"
}
}
|
新建一个 index.ts
,测试一下输出unity版本
1
2
3
4
5
|
import
"frida-il2cpp-bridge"
;
Il2Cpp.perform(() => {
console.log(
"Unity version: "
+ Il2Cpp.unityVersion);
});
|
执行 npm run watch
编译一下,然后再开个console执行 frida -U Gadget -l .\hook.js
可以看到成功输出了unity的版本
开始修改
通过分析 il2cppdumper
dump后得到的 Assembly-CSharp.dll
,发现了 Inventory
这个类,可以看到他有一个 AddItems
的方法,那我们就可以想办法调用他来添加物品
现在来跟踪一下这个类
1
2
3
4
5
6
7
8
9
10
11
|
import
"frida-il2cpp-bridge"
;
Il2Cpp.perform(() => {
console.log(
"Unity version: "
+ Il2Cpp.unityVersion);
const AssemblyCSharp = Il2Cpp.domain.assembly(
"Assembly-CSharp"
).image
const Inventory = AssemblyCSharp.class(
"Inventory"
);
Il2Cpp.trace(
true
).classes(Inventory).and().attach();
});
|
拾取一个物品,可以看到他调用了 Inventory::AddDropItem
这个方法
那么就可以hook他来调用 Inventory::AddItems
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import
"frida-il2cpp-bridge"
;
Il2Cpp.perform(() => {
console.log(
"Unity version: "
+ Il2Cpp.unityVersion);
const AssemblyCSharp = Il2Cpp.domain.assembly(
"Assembly-CSharp"
).image
const Inventory = AssemblyCSharp.class(
"Inventory"
);
const AddDropItem = Inventory.method(
"AddDropItem"
);
AddDropItem.implementation =
function
(item): boolean {
this
.method(
"AddItems"
).invoke(115, 999);
const result =
this
.method<boolean>(
"AddDropItem"
).invoke(item);
return
result;
};
});
|
拾取物品,可以看到我们拥有了许多核导弹(喜)
完结撒花
感谢开源项目的维护者们
frida-il2cpp-bridge
还是很强大的,可以去学习一下
写的可能有点乱,有问题还请指出hh
更多【软件逆向-安卓真机无root环境下的单机游戏修改-IL2CPP】相关视频教程:www.yxfzedu.com