-
Notifications
You must be signed in to change notification settings - Fork 1
/
dumpUnityluafile.js
196 lines (168 loc) · 6.35 KB
/
dumpUnityluafile.js
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//
//get_self_process_name()获取当前运行进程包名
//参考:https://github.com/lasting-yang/frida_dump/blob/master/dump_dex_class.js
function get_self_process_name()
{
var openPtr = Module.getExportByName('libc.so', 'open');
var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
var readPtr = Module.getExportByName("libc.so", "read");
var read = new NativeFunction(readPtr, "int", ["int", "pointer", "int"]);
var closePtr = Module.getExportByName('libc.so', 'close');
var close = new NativeFunction(closePtr, 'int', ['int']);
var path = Memory.allocUtf8String("/proc/self/cmdline");
var fd = open(path, 0);
if (fd != -1)
{
var buffer = Memory.alloc(0x1000);
var result = read(fd, buffer, 0x1000);
close(fd);
result = ptr(buffer).readCString();
return result;
}
return "-1";
}
function hook_dlopen()
{
var is_can_hook = false;
Interceptor.attach(Module.findExportByName(null, "dlopen"),
{
onEnter: function (args)
{
var pathptr = args[0];
if (pathptr !== undefined && pathptr != null)
{
var path = ptr(pathptr).readCString();
//console.log("dlopen:", path);
if (path.indexOf(soName) >= 0)
{
this.is_can_hook = true;
console.log("\n" + soName + "_path:", path);
}
}
},
onLeave: function (retval)
{
if (this.is_can_hook)
{
dumpUnityLua();
console.log("dlopen finish...");
}
}
}
);
Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
{
onEnter: function (args)
{
var pathptr = args[0];
if (pathptr !== undefined && pathptr != null)
{
var path = ptr(pathptr).readCString();
//console.log("android_dlopen_ext:", path);
if (path.indexOf(soName) >= 0)
{
this.is_can_hook = true;
console.log("\n" + soName + "_path:", path);
}
}
},
onLeave: function (retval)
{
if (this.is_can_hook)
{
dumpUnityLua();
console.log("android_dlopen_ext finish...");
}
}
}
);
}
//写入 lua 文件
function modifyUnityLua()
{
Java.perform(function ()
{
console.log("modifyUnityLua...");
var moduleBaseAddress = Module.getBaseAddress("libil2cpp.so");
var nativePointer = moduleBaseAddress.add(luaL_loadbuffer);
console.log("luaL_loadbuffer offset:" + nativePointer);
Interceptor.attach(nativePointer,
{
onEnter: function (args)
{
var size = args[2].add(is32).toInt32();
var name = args[3].add(is32).readUtf16String();
console.log("fileSize: " + size);
console.log("fileName: " + name);
if (name.indexOf("PlayerDataManager") >= 0)
{
//打印出想改的文件的字节码,打印出来后,复制到 icyberchef ,转换为16进制码,
//再保存到010,再修改,注意字节码长度要一样(增加或删掉的字节码会导致文件长度不一样),否则可能出错
//可以利用里面的注释补齐字节码
/*console.log(hexdump(args[1].add(is32),
{
offset: 0,
length: size,
header: true,
ansi: true
}
)); */
//需要保证写入的文件和原文件的长度必须一致,否则可能出错
//也就是参数中的 size ,和写入的 mybuff 长度必须一致
Memory.writeByteArray(args[1].add(is32), mybuff);
}
},
onLeave: function (retval)
{
}
}
);
}
);
}
//dump lua 文件
function dumpUnityLua()
{
Java.perform(function ()
{
console.log("dumpUnityLua...");
var moduleBaseAddress = Module.getBaseAddress("libil2cpp.so");
var nativePointer = moduleBaseAddress.add(luaL_loadbuffer);
console.log("==nativePointer", nativePointer);
Interceptor.attach(nativePointer,
{
onEnter: function (args)
{
var size = args[2].add(is32).toInt32();
var name = args[3].add(is32).readUtf16String();
console.log("size: " + size);
console.log("name: " + name);
if (name.indexOf("/") >= 0)
{
name = name.replace(/\//g, "_");//文件名带有正斜杠,替换为下划线
}
var file = new File("/sdcard/Android/data/" + get_self_process_name() + "/files/" + name, "wb");
file.write(Memory.readByteArray(args[1].add(0xc), size));
file.flush();
file.close();
},
onLeave: function (retval)
{
}
}
);
}
);
}
/**
unity中hook的函数
// Namespace: LuaInterface
public class LuaDLL // TypeDefIndex: 5749
public static int luaL_loadbuffer(IntPtr luaState, byte[] buff, int size, string name); // 0x127E5DC
*/
var soName = "libil2cpp.so"
var luaL_loadbuffer = 0x127E5DC
//重新写入的文件流
var mybuff = [45, 45, 91, 91, 10, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61];
var is32 = 0xc;//游戏32位写0xc, 游戏64位写0x14
setImmediate(hook_dlopen);