一、获取加载的luac文件
通过frida hook libccos2dlua.so 的luaL_loadbuffer函数对luac进行dump js代码如下,得到dump后的lua文件
// 要加载的目标库名
var targetLibrary = "libcocos2dlua.so";
var dlopen = Module.findExportByName(null, "dlopen"); // 6.0
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext"); // 高版本8.1以上
var bhook = 0;
const fopenPtr = Module.getExportByName(null, "fopen");
const fwritePtr = Module.getExportByName(null, "fwrite");
const fclosePtr = Module.getExportByName(null, "fclose");
// 定义 NativeFunction 封装
const fopen = new NativeFunction(fopenPtr, "pointer", ["pointer", "pointer"]);
const fwrite = new NativeFunction(fwritePtr, "ulong", ["pointer", "int", "int", "pointer"]);
const fclose = new NativeFunction(fclosePtr, "int", ["pointer"]);
function writeFile(path, content, size) {
const cPath = Memory.allocUtf8String(path);
const cMode = Memory.allocUtf8String("w");
var filePtr = fopen(cPath, cMode);
if (filePtr.isNull()) {
console.log("Failed to open file:", path);
return;
}
const written = fwrite(ptr(content), 1, size, filePtr);
console.log(`Requested to write ${size} bytes, actually wrote ${written} bytes to ${path}`);
fclose(filePtr);
}
function hookcocos2d() {
var baseAddress = Module.findBaseAddress(targetLibrary);
console.log("baseaddress is ", baseAddress);
if (baseAddress) {
var xxteafunc = baseAddress.add(0xEB3C9C);
var result = 0;
Interceptor.attach(xxteafunc, {
onEnter: function (args) {
//console.log(this.context.x8);
//console.log(hexdump(args[0]));
// console.log(hexdump(args[1]));
console.log(args[2]);
writeFile(`/data/data/packagename/files/lua_dump/unlua_${args[2]}`, args[1], args[2].toUInt32())
//console.log(hexdump(args[2]));1
//console.log(args[3]);
//result = args[4];
},
onLeave: function (retval) {
//console.log(hexdump(result))
}
});
}
}
Interceptor.attach(dlopen, {
onEnter: function (args) {
var path_ptr = args[0];
var path = ptr(path_ptr).readCString();
//console.log("[dlopen:]", path);
},
onLeave: function (retval) {
}
});
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
var path_ptr = args[0];
var path = ptr(path_ptr).readCString();
//console.log("[dlopen_ext:]", path);
if (path.indexOf(targetLibrary) !== -1) {
console.log(targetLibrary + " is being loaded via android_dlopen_ext.");
bhook = 1;
}
},
onLeave: function (retval) {
if (bhook == 1) {
bhook = 0;
hookcocos2d();
}
}
});
二、luac解密
看头文件为lua5.1版本 直接用unluac会报错
在解析lua number integrality 解析结果为8,一般number integrality 为1或者0(0表示lua数字为浮点数,1表示数字为浮点数) 此处为8,先对unluac进行修改跳过此错误(此处修改将其默认修改为1)
修改完毕后继续用luac进行反编译,继续报错如下
此处报错对应unluac代码如下,解析constanttype出了问题,一般类型为1,2,3,4
打开unLuac的调试配置
解析到非法的type类型为254,即为0xfe
依据字符串“binary string”定位到lua_undump函数。
层层深入往下跟进到此处,发现确实多了-2类型的constant,且为读取8个字节。结合上述number integrality 有问题,且此处ida反编译没有case2的情况,此处应该为读取number类型且该类型为整数而非浮点数。lua5.1默认是浮点数,此处修改原因大致如下
最后修改unluac的代码如下,完成最终的反编译。