cocos2d lua游戏逆向 打印日志(通杀)

最近再看某 棋牌类游戏 需要逆向其socket 发送 与 接收具体数据

一般这种类型的游戏都是脚本 游戏代码在

apk 目录 assets 下

我们直接解压改apk 获取到 源码 

 结果所有的lua 文件全是加密的 

像这种文件 也是可以解密出来的 

直接hook  luaL_loadbuffer 函数

具体细节可以参考这位大佬的文章

https://www.52pojie.cn/thread-1478717-1-1.html

int my_luaL_loadbuffer(void *lua_state, char *buff, size_t size, char *name) {
    LOGD("pzhpkg lua size: %d, name: %s", (uint32_t) size, name);  // 打印lua脚本的大小和名称

    if (name != NULL) {
        //strdup()在内部调用了malloc()为变量分配内存

        char *name_t = strdup(name);
        if (name_t != " " && name_t[0] != ' ') {
            FILE *file;
            char full_name[256];
            int name_len = strlen(name);
            if (8 < name_len <= 100) {
                char *base_dir = (char *) "/data/data/com.ln3aa.ebw0mux7.c2nh8yjuj/";
                //LOGD("pkg base_dir: %s", base_dir);
                int i = 0;
                while (i < name_len) {
                    if (name_t[i] == '/') {
                        name_t[i] = '.';
                    }
                    i++;
                }
                //---------------------------------------
                //if (!strstr(name_t, "-------------") && !strstr(name_t, "local _")) { //local
                if (strstr(name_t, ".luac")) {

                    sprintf(full_name, "%s%s", base_dir, name_t);
                    //lua脚本保存
                    //LOGD("pzhpkg full_name: %s", full_name);
                    file = fopen(full_name, "wb");
                    //LOGD("pzhpkg file * : %p", file);
                    if (file != NULL) {
                        //LOGD("pzhpkg  save name: %s", full_name);
                        fwrite(buff, 1, size, file);
                        fclose(file);
                        free(name_t);
                    }else
                    {
                    	LOGD("fopen fail ");
                    	LOGD("fopen: %s\n", strerror(errno));
                    }





                    //lua脚本hook加载
                    /*file = fopen(full_name, "r");
                    if (file != NULL) {
                        LOGD("[Tencent]-------path-----%s", full_name);
                        fseek(file, 0, SEEK_END);
                        size_t new_size = ftell(file);
                        fseek(file, 0, SEEK_SET);
                        char *new_buff = (char *) alloca(new_size + 1);
                        fread(new_buff, new_size, 1, file);
                        fclose(file);
                        return origin_luaL_loadbuffer(lua_state, buff, size, name);
                    }*/




                }
            }
        }
    }

    return origin_luaL_loadbuffer(lua_state, buff, size, name);
}

  解密后发现打印是关闭的 

既然是通杀打印 那是不需要解密 通过深入查看cocos 的源码发现 lua 和c++ 交互会用到一个叫

lua_pushlstring 的函数  我们可以直接hook该函数 实现打印通杀

if(Java.available){
    Java.perform(function()
    {

         //hook带string字符串参数的函数
         var resbuffstring = null;
         Interceptor.attach(Module.findExportByName("libqpry_lua.so" , "lua_pushlstring"),{
            onEnter: function(args) {
                var tempStr = Memory.readCString(args[1])
                //console.log("hook lua_pushlstring  onEnter args[1] " + tempStr);
               
                var bool = tempStr.indexOf("msgid");
                //console.log("args[1] " , tempStr);
                var card_listb = tempStr.indexOf("card_list"); // && card_listb > 0
                console.log("args[1] " , tempStr);

    
            },
            onLeave:function(retval){
        
                //console.log("hook lua_pushlstring  onLeave ");
            }
         });
    }
    
    );
}

脚本使用 frida -U "包名" -l hookfun.js

打印日志效果 '{"msgid":107,"subid":2003,"card_list":[{"user_id":1540568,"card":[13,29,45]},{"user_id":1781910,"card":[13,29,45]},{"user_id":9896473,"card":[2,13,10]}]}';

可以看到其 斗地主游戏 的玩家牌值 已经出来了


版权声明:本文为pengzhenghui123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>