概况
有时想执行exe文件直接执行frida的hook,需要通过DLL inject的方式实现。
程序在加载DLL时会优先加载当前目录的,所以可以伪造一个DLL加载我们自己准备好的DLL,然后执行原有DLL的方法。
使用
可以使用 Ultimate-ASI-Loader 实现注入。unity会加载version.dll,下载对应版本的 version.dll 放到游戏根目录,下载 frida-gadget.dll 改名为 frida-gadget.asi 。
增加配置文件frida-gadget.config。
1
2
3
4
5
6
7
| {
"interaction": {
"type": "script",
"path": "frida.js",
"on_change": "reload"
}
}
|
然后就是 frida.js 文件,下面是一个AI生成的例子,这个例子是Hook CHECK_FILE_INTEGRITY 方法,直接返回true。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| "use strict";
// 仅适用于当前 GameAssembly.dll 构建:
// SHA-256 db1c25ebdc0d1a8c3718971039db718323caae04e94c5a93f17e208827f2036e
const CHECK_FILE_INTEGRITY_RVA = 0x3d4e50;
const POLL_INTERVAL_MS = 10;
let installed = false;
function readIl2CppString(value) {
if (value.isNull()) return "<null>";
try {
const length = value.add(0x10).readS32();
if (length < 0 || length > 0x10000) return `<invalid length=${length}>`;
return value.add(0x14).readUtf16String(length) || "";
} catch (error) {
return `<read failed: ${error}>`;
}
}
function installHook() {
if (installed) return;
const gameAssembly = Process.findModuleByName("GameAssembly.dll");
if (gameAssembly === null) return;
installed = true;
Interceptor.attach(gameAssembly.base.add(CHECK_FILE_INTEGRITY_RVA), {
onEnter(args) {
this.rootPath = readIl2CppString(args[1]);
this.targetPath = readIl2CppString(args[2]);
this.expectedLength = args[3].toInt32();
},
onLeave(retval) {
const originalResult = (retval.toInt32() & 0xff) !== 0;
retval.replace(ptr(1));
send(
`[FILE-INTEGRITY BYPASS] originalResult=${originalResult} ` +
`effectiveResult=true expectedLength=${this.expectedLength}\n` +
`root=${this.rootPath}\n` +
`target=${this.targetPath}`,
);
},
});
send(
`[READY] CheckFileIntegrity hook installed at ` +
`${gameAssembly.base.add(CHECK_FILE_INTEGRITY_RVA)}`,
);
}
send("[BOOT] frida.js loaded; waiting for GameAssembly.dll");
const installTimer = setInterval(() => {
installHook();
if (installed) clearInterval(installTimer);
}, POLL_INTERVAL_MS);
installHook();
|
如何找到这个位置
这个游戏检查了dll的大小等,游戏中随机延迟使用协程弹窗报错,使用AI从错误码入手,使用IDA MCP静态分析,分析了很久才找到弹窗的相关代码。然后分析什么情况才会弹窗,最后看这个变量是哪里赋值的。