一、獲取加載的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的代碼如下,完成最終的反編譯。