某手游cocos2dlua反编译

一、获取加载的luac文件

通过frida hook libccos2dlua.so 的luaL_loadbuffer函数对luac进行dump js代码如下,得到dump后的lua文件

javascript 复制代码
// 要加载的目标库名
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的代码如下,完成最终的反编译。

相关推荐
努力努力再努力wz14 小时前
【Lua 进阶系列】从 C++ 对象到 Lua 变量:一文理解 userdata、Lua 栈与元表绑定机制
c++·junit·lua
阿卡好可爱17 小时前
Lua 热更新不生效:改完文件线上仍是旧逻辑,package.loaded 与 upvalue 重绑定详解
数据结构·分布式·后端·架构·lua
Joy T18 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
寂寞的船2 天前
【Unity知识速递】第10期 Unity GC 零分配实战:从 UnityEngine.Pool 到手动 GC 控制的全链路优化
jvm·unity·c#·游戏引擎·lucene
Martina_03212 天前
AI生成3D场景的霓虹灯一开就糊成光团?用6步检查Emissive、Bloom与曝光
人工智能·3d·ai·自然语言处理·游戏引擎·材质·贴图
寂寞的船4 天前
【Unity知识速递】第8期 IL2CPP 托管堆内存碎片与原生堆交互机制深度解析
unity·游戏引擎·交互
淡海水5 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc
努力努力再努力wz5 天前
【Lua进阶系列】Lua 调试机制详解:从虚拟机调用栈、错误传播到 debug 库
junit·单元测试·lua
寂寞的船5 天前
【Unity Bug挑战】第10期 SerializeReference 内存泄漏之谜
unity·c#·游戏引擎·bug
炸薯条!7 天前
博客系统测试报告
开发语言·lua