首页
论坛
专栏
课程

[原创]浅析android手游lua脚本的加密与解密

2017-4-11 16:01 71828

[原创]浅析android手游lua脚本的加密与解密

2017-4-11 16:01
71828

2018.05.02更新

        这段时间在翻备份的硬盘,突然发现了以前的分析项目和代码,从里面提取了之前附件的内容,现在上传给大家,真是柳暗花明又一村啊。附件包括201703版本的梦幻手游里面提取的so文件和一些加密后的资源文件(包括lua脚本),并包括了2个扑鱼APK文件,最后还打包了解密代码,供大家参考。

        附件太大,快100MB,上传不来论坛,我又放到百度网盘了......

        链接:https://pan.baidu.com/s/1DVgH0qHYPkiHBIiV2UsU7g 密码:ipt3


2018.04.09更新

附件是真的找不到了, 大家主要理解思路吧。百度网盘的附件好多朋友都下载和保存过,能不能发一份到论坛上传?感谢感谢~


2017.04.15更新

1. 在编辑过程中,5.1后半段内容(解密和反编译部分)被删除了,现在补上。

2. 在3.3里说到,“修改lua项目中的opcode后,编译生成lua.exe再替换到反编译目录下,就可以反编译”,这一句是错误的,正确是“修改lua项目中的opcode后,重新编译反编译工具luadec51项目,就可以反编译了”,已经修改。


0.前言

     这篇文章是本人在学习android手游安全时总结的一篇关于lua的文章,不足之处欢迎指正,也欢迎大牛前来交流。本文目录如下:
目录
0. 前言
1. lua脚本在手游中的现状
2. lua、luac、luaJIT三种文件的关系
3. lua脚本的保护
     3.1 普通的对称加密,在加载脚本之前解密
     3.2 将lua脚本编译成luaJIT字节码并且加密打包
     3.3 修改lua虚拟机中opcode的顺序
4. 获取lua代码的一般方法
     4.1 静态分析so解密方法
     4.2 动态调试:ida + idc + dump
     4.3 hook so
     4.4 分析lua虚拟机的opcode的顺序
5. 三个游戏的lua脚本解密过程
     5.1 54捕鱼
     5.2 捕鱼达人4
     5.3 梦幻西游手游
6. 总结
参考文章

     

    主要用到的工具和环境:

1 win7系统一枚
2 quick-cocos2d-x的开发环境(弄一个开发环境方便学习,而且大部分lua手游都是用的cocos2d-x框架,还有一个好处,可以查看源码关键函数中的特征字符串,然后在IDA定位到关键函数,非常方便)
3 IDA6.8(分析so文件+动态调试so)
4 vs2015(编写解密代码)这里建议用vs2013来编译运行cocos2d-x,vs2015太多坑要填了.....
5 AndroidKiller 1.3.1(反编译apk,其中apktool.exe是最新版)
6 luadec51(反编译luac)
7 luajit-decomp(反编译luaJIT)
等等...
    
1.lua脚本在手游中的现状
     略。
2.lua、luac、luaJIT三种文件的关系

     在学习lua手游过程中,本人遇到的lua文件大部分是这3种。其中lua是明文代码,直接用记事本就能打开,luac是lua编译后的字节码,文件头为0x1B 0x4C 0x75 0x61 0x51,lua虚拟机能够直接解析lua和luac脚本文件,而luaJIT是另一个lua的实现版本(不是原作者写的),JIT是指Just-In-Time(即时解析运行),luaJIT相比lua和luac更加高效,文件头是0x1B 0x4C 0x4A。


     luac:

    


     luajit:

     
     
3.lua脚本的保护

     一般有安全意识的游戏厂商都不会直接把lua源码脚本打包到APK中发布,所以一般对lua脚本的保护有下面3种:


3.1 普通的对称加密,在加载脚本之前解密

     这种情况是指打包在APK中的lua代码是加密过的,程序在加载lua脚本时解密(关键函数luaL_loadbuffer ),解密后就能够获取lua源码。如果解密后获取的是luac字节码的话,也可以通过反编译得到lua源码,反编译主要用的工具有unluac和luadec51,后面会具体分析。


3.2 将lua脚本编译成luaJIT字节码并且加密打包

     因为反编译的结果并不容易查看,所以这种情况能够较好的保护lua源码。这个情况主要是先解密后反编译,反编译主要是通过luajit-decomp项目,它能够将luajit字节码反编译成伪lua代码。


3.3 修改lua虚拟机中opcode的顺序

     这种情况主要是修改lua虚拟机源码,再通过修改过的虚拟机将lua脚本编译成luac字节码,达到保护的目的。这种情况如果直接用上面的反编译工具是不能将luac反编译的,需要在程序中分析出相对应的opcode,然后修改lua项目的opcode的顺序并重新编译生成反编译工具,就能反编译了,后面会具体分析。     


     一般上面的情况都会交叉遇到。


4.获取lua源码的一般方法

     这里主要介绍4种方法,都会在第5节中用实例说明。


4.1 静态分析so解密方法

     这种方法需要把解密的过程全部分析出来,比较费时费力,主要是通过ida定位到luaL_loadbuffer函数,然后往上回溯,分析出解密的过程。


4.2 动态调试:ida + idc + dump

     这里主要通过ida动态调试so文件,然后是定位到luaL_loadbuffer地址,游戏会在启动的时候通过调用luaL_loadbuffer函数加载必要的lua脚本,通过在luaL_loadbuffer下断点 ,断下后就可以运行idc脚本将lua代码导出(程序调用一次luaL_loadbuffer加载一个lua脚本,不写idc脚本的话需要手动导N多遍.....)。


4.3 hook so

     跟4.2原理一样,就是通过hook函数luaL_loadbuffer地址,将代码保存,相比4.2的好处是有些lua脚本需要在玩游戏的过程中才加载,如果用了4.2的方法,游戏过程中 中断一次就需要手动运行一次idc脚本,而且往往每次只加载一个lua文件,如果是hook的话,就不需要那么麻烦,直接玩一遍游戏,全部lua脚本就已经保存好了。


4.4 分析lua虚拟机的opcode的顺序

     这里主要是opcode的顺序被修改了,需要用ida定位到虚拟机执行luac字节码的地方,然后对比原来lua虚拟机的执行过程,获取修改后的opcode顺序,最后还原lua脚本。


5.三个游戏的lua脚本解密实例

     好了,下面用3个例子来说明上面的情况。


5.1 54捕鱼
     首先用AndroidKiller 加载,然后查看lib目录下的so文件,发现libcocos2dlua.so文件,基本可以确定是lua脚本编写的了。这里有个小技巧,当有很多so文件的时候,一般最大的文件是我们的目标(文件大是因为集成了lua引擎)。既然有lua引擎,肯定有lua脚本了,接着找lua脚本。资源文件和lua脚本文件都是在assets目录下。发现游戏的资源文件和配置文件都是明文,这里直接修改游戏的配置文件就可以作弊(比如修改升级炮台所需的金币和钻石,就可以达到快速升级炮台的目的),然后并没有发现类似lua脚本的文件。
     顺手解压了一下res目录下的liveupdate_precompiled.zip,发现解压失败,看来是加密了(看名字就知道是更新游戏的代码)这里说明一下,一般遇到xxxx_precompiled.zip的这种文件,都是quick-cocos2d-x框架(quick简单来说就是对lua的拓展实现),在quick-cocos2d-x框架下可以用compile_scripts命令将lua文件加密打包成xxxx_precompiled.zip,游戏运行时再解密加载。注意,这种方式打包的lua脚本一般都会被编译成luaJIT,加载的关键函数是loadChunksFromZIP,可以在IDA中直接搜索该函数,如果找不到可以搜索字符串luaLoadChunksFromZIP来定位到函数
     OK,了解了原理接下来开始动手分析,将libcocos2dlua.so拖到IDA中加载,函数中直接搜索loadChunksFromZIP,定位后F5。

    

     一直向上回溯(交叉引用 ),来到下图,发现解密的密钥和签名,其中xiaoxian为密钥,XXFISH为签名

    

     进去函数里面看看,其实会发现调用了XXTea算法,这里我们也可以直接分析loadChunksFromZIP函数的源码(所以配置一个cocos2d的开发环境还是非常有必要的)。查看源码里的lua_loadChunksFromZIP函数的原型:
int CCLuaStack::lua_loadChunksFromZIP(lua_State *L)
{
    if (lua_gettop(L) < 1)
    {     // 这里可以发现用字符串也可以定位到目标函数
        CCLOG("lua_loadChunksFromZIP() - invalid arguments");
        return 0;
    }
...
        if (isXXTEA)
        {
            // decrypt XXTEA
            // 这里调用了解密函数
            xxtea_long len = 0;
            buffer = xxtea_decrypt(zipFileData + stack->m_xxteaSignLen,
                                   (xxtea_long)size - (xxtea_long)stack->m_xxteaSignLen,
                                   (unsigned char*)stack->m_xxteaKey,
                                   (xxtea_long)stack->m_xxteaKeyLen,
                                   &len);
            delete []zipFileData;
            zipFileData = NULL;
            zip = CCZipFile::createWithBuffer(buffer, len);
        }
...
}

 

    接下来直接写解密函数(在cocos2d-x项目里面写的解密函数,很多工具直接可以调用)

void decryptZipFile_54BY(string strZipFilePath)
{
        CCFileUtils *utils = CCFileUtils::sharedFileUtils();
        unsigned long lZipFileSize = 0;
        unsigned char *szBuffer = NULL;
        unsigned char *zipFileData = utils->getFileData(strZipFilePath.c_str(), "rb", &lZipFileSize);
        xxtea_long xxBufferLen = 0;
        szBuffer = xxtea_decrypt(zipFileData + 6,           //6为签名XXFISH的长度
               (xxtea_long)lZipFileSize - (xxtea_long)6,    //减去签名的长度
               (unsigned char*)"xiaoxian",                  //xiaoxian为密钥
               (xxtea_long)8,                               //密钥的长度
               &xxBufferLen);
        //获取zip里面的所有文件
        CCZipFile *zipFile = CCZipFile::createWithBuffer(szBuffer, xxBufferLen);
        int count = 0;
        string strFileName = zipFile->getFirstFilename();
        while (strFileName.length())
        {
               cout << "filename:" << strFileName << endl;
               unsigned long lFileBufferSize = 0;
               unsigned char *szFileBuffer = zipFile->getFileData(strFileName.c_str(), &lFileBufferSize);
               if (lFileBufferSize)
               {
                       ++count;
                       ofstream ffout(strFileName, ios::binary);
                       ffout.write((char *)szFileBuffer, sizeof(char) * (lFileBufferSize));
                       ffout.close();
                       delete[] szFileBuffer;
               }
               strFileName = zipFile->getNextFilename();
        }
        delete[] zipFileData;
}

    

    解密后的文件如下:

     这几个都是更新游戏的代码,是luajit的文件,所以接下来需要反编译。IDA中查看下lua版本和luajit版本,字符串分别搜索lua+空格和luajit+空格:

 

    lua版本为5.1


    luajit版本为2.1.0


    反编译本人用到的是luajit-decomp,这里需要注意,luajit-decomp默认的lua版本为5.1,luajit版本为2.0.2,我们需要下载对应lua和luajit的版本,编译后替换luajit-decomp下的lua51.dll、luajit.exe、jit文件夹。反编译时需要注意的文件和文件夹:

    

    这里需要下载版本为2.1.0-beta2的luajit,并且编译生成文件后,复制LuaJIT-2.1.0-beta2\src路径下的lua51.dll、luajit.exe文件和jit文件夹覆盖到luajit-decomp目录中。luajit-decomp用的是autolt3语言,原脚本默认是只反编译当前目录下的test.lua文件,所以需要改一下decoder.au3文件的代码。修改后的代码另存为jitdecomp.au3文件,编译后为jitdecomp.exe。并且增加了data目录,目录下有3个文件夹,分别为:

luajit:待反编译的luajit文件
asm:反汇编后的中间结果
out:反编译后的结果


     将解密后的文件放到luajit文件夹,运行 jitdecomp.exe,反编译的结果在out目录下,结果如下:

     这个反编译工具写得并不好,反编译后的文件阅读起来挺困难的,而且反编译的lua格式有问题,所以不能用lua编辑器格式化代码。


5.2 捕鱼达人4

     这个游戏主要是用ida动态调试so文件,然后用idc脚本把lua文件全部dump下来的方法。首先用AndroidKiller加载apk,在lib目录下有3个文件夹,不同的手机cpu型号对应不同的文件夹 。本人的手机加载的目标so文件在armeabi-v7a文件下:


     接着,ida加载libcocos2dlua.so文件,定位到函数luaL_loadbuffer,可以在函数中直接搜索,也可以字符串搜索"[LUA ERROR]"来定位到函数中,函数分析如下:

LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,const char *name)


     所以在ARM汇编中,参数R0为lua_State指针,参数R1为脚本内容,R2为脚本大小,R3为脚本的名称,写一段IDC脚本dump数据即可:

#include <idc.idc>
static main()
{
    auto code, bp_addrese,fp,strPath,strFileName;
    bp_addrese = 0x7573022C;                                                // luaL_loadbuffer函数地址 ,静态分析获取的函数地址+so文件的地址得到
    AddBpt(bp_addrese);                                                     // 下断点,也可以手动下断
    while(1)
    {
        code = GetDebuggerEvent(WFNE_SUSP|WFNE_CONT, 15);                   // 等待断点发生,等待时间为15秒
        if ( code <= 0 )
        {
            Warning("错误代码:%d",code);
            return 0;
        }
        Message ("地址:%a, 事件id:%x\n", GetEventEa(), GetEventId());      // 断点发生,打印消息
        strFileName = GetString(GetRegValue("R3"),-1,0);                    // 获取文件路径名
        strFileName = substr(strFileName,strrstr(strFileName,"/")+1,-1);    // 获取最后一个‘/’后面的名字(文件的名字)去掉路径
        strPath = sprintf("c:\\lua\\%s",strFileName);                       // 保存lua的本地路径
        fp = fopen(strPath,"wb");
        savefile(fp,0,GetRegValue("R1"),GetRegValue("R2"));
        fclose(fp);
        Message("保存文件成功: %s\n",strPath);
    }
}
//字符串查找函数,从后面向前查找,返回第一次查找的字符串下标
static strrstr(str,substr1)
{
    auto i,index;
    index = -1;
    while (1)
    {
        i = strstr(str,substr1);
        if (-1 == i) return index;
        str = substr(str,i+1,-1);
        index = index+i+1;
    };
}


     ida动态调试so文件网上有很多文章,这里就不详细说明了。通过idc脚本获取的部分数据如下:

     虽然文件的后缀名是.luac,但其实都是明文的lua脚本。


5.3.梦幻西游手游

     AndroidKiller反编译apk,查看lib下存在libcocos2dlua.so,基本上确定是lua写的:


     在assets\HashRes目录下,存在很多被加密的文件,这里存放的是lua脚本和游戏的其他资源文件


     接着找lua脚本的解密过程,用ida加载libcocos2dlua.so文件,搜索luaL_loadbuffer函数,定位到关键位置,这里就是解密的过程了:
 
     分析解密lua文件过程如下:

 

    这里需要实现Lrc4解密的相关函数,还有Lzma解压函数需要自己实现,其他几个都是cocos2d平台自带的函数,直接调用就可以了。上面的流程图实现的函数如下:

bool decryptLua_Mhxy(string strFilePath, string strSaveDir)
{
        bool bResult = false;
        char *szBuffer = NULL;
        int nBufferSize = 0;
        CCFileUtils *utils = CCFileUtils::sharedFileUtils();
        unsigned long ulFileSize = 0;
        char *szFileData = (char*)utils->getFileData(strFilePath.c_str(), "rb", &ulFileSize);
        if (strncmp(szFileData, "L:grxx", 6))
        {
               if (!strncmp(szFileData, "__sign_of_g18_enc__", 0x13))
               {
                       szBuffer = szFileData + 0x13;
                       nBufferSize = ulFileSize - 0x13;
                       bResult = decrypt((unsigned char*)szBuffer, nBufferSize);
               }
        }
        else if (!strncmp(szFileData + 6, "__sign_of_g18_enc__", 0x13))
        {
               unsigned char *pData = (unsigned char *)szFileData + 0x19;
               int nLen = ulFileSize - 0x19;
               bResult = decrypt(pData, nLen);
               if (ZipUtils::isGZipBuffer(pData, nLen))
               {
                       nBufferSize = ZipUtils::ccInflateMemory(pData, nLen, (unsigned char**)&szBuffer);
               }
               else if (ZipUtils::isCCZBuffer(pData, nLen))
               {
                       nBufferSize = ZipUtils::inflateCCZBuffer(pData, nLen, (unsigned char**)&szBuffer);
               }
               else if (LzmaUtils::isLzmaBuffer(pData, nLen))
               {
                       nBufferSize = LzmaUtils::inflateLzmaBuffer(pData, nLen, (unsigned char**)&szBuffer);
               }
               else
               {
                       bResult = false;
               }
        }
        if(bResult)
               saveLuaData(szBuffer, nBufferSize, strSaveDir);
        return bResult;
}


     解密函数过程如下:


     decrypt()实现代码如下:

bool decrypt(unsigned char *pData, int nLen)
{
        Lrc4 *pLrc4 = new Lrc4;
        Lrc4_lrc4(pLrc4);
        Lrc4_s(pLrc4, pData, nLen);
        return true;
}


    Lrc4结构如下:

#define DATA_SIZE 256
struct Lrc4
{
        unsigned char pData[DATA_SIZE];  //初始化时计算得到的256个字节
        int nIndex;                      //记录下标
        int nPreIndex;                   //记录前一个下标
};


     其他函数的具体实现请看DecryptData_Mhxy.cpp文件,这里就不贴代码了。解密后的文件如下:


     可以看出,解密后的文件为luac字节码,但是这里直接用反编译工具是不能反编译luac字节码的,因为游戏的opcode被修改过了,我们需要找到游戏opcode的顺序,然后生成一个对应opcode的luadec.exe文件才能反编译。下表为修改前后的opcode:


     lua虚拟机的相关内容就不说明了,百度很多,这里说明下如何还原opcode的顺序。首先需要定位到opmode的地方,IDA搜索字符串"LOADK",定位到opname的地方,交叉引用到代码,找到opmode:


     off_B02CEC为opname的地址,byte_A67C00为opmode的地址,进入opmode地址查看:

   
     这里没有把全部数据截图出来,可以看出,这里的opmode跟原opmode是不对应的。原opmode在lua源码中的lopcodes.c文件中:


     源码用了宏,计算出来的结果就是上表中opmode的结果。这里对比opmode就可以快速对比出opcode,因为opmode不相等,那么opcode也肯定不相等,到这一步,已经能还原部分opcode了,因为有一些opmode是唯一的。比如下面几个:

     如SETLIST,原opcode为34,opmode为0x14,找到的opmode的第8个字节也为0x14,则实际上SETLIST的opcode为8。


     接下来就需要定位到luaV_execute函数,然后对比源码来还原其他的opcode,直接IDA搜索字符串"initial value must be a number"可以定位到luaV_execute 函数,再F5一下。接着打开lua源码中的lvm.c文件,找到luaV_execute函数,就可对比还原了。lua源码和IDA F5后的代码其实差别还是有的,而且源码用了大量的宏,所以源码只是用来参考、理解lua虚拟机的解析过程,本人在还原的过程中,会再打开一个没有修改opcode的libcocos2dlua.so文件,这样对比查找就方便多了。

     最后修改lua源码 lopcodes.h中的opcode、lopcodes.c的opname和opmode,重新编译并生成luadec51 .exe(需要将lua源码中的src目录放到luadec51的lua目录下才能编译),就OK了,写个批处理文件就可以批量反编译。一个文件反编译的结果:


6.总结

     总结一下解密lua的流程,拿到APK,首先反编译,查看lib目录下是否有libcocos2dlua.so,存在的话很大可能这个游戏就是lua编写,lib目录下文件最大的就是目标so文件,一般情况就是libcocos2dlua.so。接着再看assets文件夹有没有可疑的文件,cocos2dx框架都会把游戏的资源文件放到这个文件夹下,包括lua脚本。其次分析lua加密的方式并选择解密脚本的方式,如果可以ida动态调试,本人一般都会选择用idc脚本dump代码。最后如果得到的不是lua明文,还需要再反编译一下。

     不足之处:第一个是此文是本人逆向lua手游时的总结,而且本人逆向的手游可能不是很多,所以有些观点比较片面,不足之处请指正。第二个就是文章是事后写的,并且写文章的时间比较仓促,所以有些步骤写得可能不详细,欢迎讨论。如果有必要,会写一篇《如何一步一步还原梦幻手游opcode》,但是如果看过lua源码,对lua比较熟悉的话,找出来我想应该不是问题的。第三个就是luajit的反编译并不完美,用的是luajit-decomp反编译工具,工具作者也说只是满足了他自己的需求,所以如果可以的话,想自己实现一个luajit的反编译工具,而且梦幻luac的反编译好像部分代码也反编译失败了,可能自己遗漏了点什么吧,就先这样吧.....(2018/07/10 增加:梦幻西游手游lua代码反编译失败的修复 请点这里


参考文章

腾讯游戏安全中心《Lua游戏逆向及破解方法介绍》 http://gslab.qq.com/portal.php?mod=view&aid=173

Kaitiren的专栏《Quick-cocos2d-x 与Cocos2dx 区别》http://blog.csdn.net/kaitiren/article/details/35276177

littleNA《梦幻手游部分Luac反编译失败的解决方法》 https://litna.top/2018/07/08/梦幻手游部分Luac反编译失败的解决方法/

.....


附件

找不到附件了.....



[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最后于 2018-7-10 19:32 被littleNA编辑 ,原因:
打赏 + 1.00
打赏次数 1 金额 + 1.00
 
赞赏  CCkicker   +1.00 2017/05/08
最新回复 (53)
bengou 2017-4-11 16:08
2
0
谢谢分享
cqzhou 2017-4-11 16:45
3
0
谢谢分享  赞一个
奔跑的阿狸 1 2017-4-11 17:13
4
0
竟然有我梦幻的,必须赞
MaYil 2017-4-11 19:28
5
0
厉害了我的哥,  谢谢分享
huuio 2017-4-12 11:47
6
0
支持
huluxia 2017-4-12 22:45
7
0
厉害了我的哥期待下一篇文章
笨笨雄 14 2017-4-17 09:42
8
0
我也看的腾讯那文章,并没有什么卵用,楼主要是早点写,我就懒得自己搞了。。。
Sam.com 2017-4-18 01:45
9
0
谢谢分享~~
seacathello 2017-4-18 09:06
10
0
楼主,可以留个联系方式吗?我有一个apk  反编译的问题想请教,有偿。我的联系方式是229605841.
CCkicker 2017-4-21 10:23
11
0
厉害了我的哥期待下一篇文章 
江南四号地铁 2017-4-21 10:52
12
0
谢谢分享~~
marsboys 2017-4-22 03:56
13
0
支持一下!
bambooqj 2017-4-22 19:31
14
0
luajit反编译出来了的.根本看不懂..而且隔空调用有时候还有问题.师傅是怎么解决的.
xxRea 2017-4-24 11:08
15
0
luajit反编译出来的代码可读性实在是太差劲了。
有没有更好的反编译工具?
还有,luajit反编译出的代码,修改后能够再编译成luajit吗
littleNA 3 2017-4-24 22:10
16
0
bambooqj luajit反编译出来了的.根本看不懂..而且隔空调用有时候还有问题.师傅是怎么解决的.
确实本文章中的luajit反编译工具反编译的结果很难看,这个我也在研究,你可以试试  @笨笨雄  版主那篇文章中的其他反编译工具。
littleNA 3 2017-4-24 22:28
17
0
xxRea luajit反编译出来的代码可读性实在是太差劲了。 有没有更好的反编译工具? 还有,luajit反编译出的代码,修改后能够再编译成luajit吗[em_41]
是的,这个工具不是很好用,你可以试试    @笨笨雄    版主那篇文章中的反编译工具。
反编译出来的代码应该都有各种问题吧,如果没有问题的话那就可以直接用,luajit是支持明文脚本的;如果反编译的结果有问题(编译不再通过),那只能修改luajit的汇编代码了,再生成文件。以上都还只是理论,我没有试过。
bambooqj 2017-4-25 15:16
18
0
市面上大部分luajit的工具  github能找的  宝宝都试过了..全部基于线性扫描.优化之后的可读性.仍然很差..什么时候能编程.ILCODE转C#的效果就很厉害了.
笨笨雄 14 2017-5-2 09:42
19
0
bambooqj 市面上大部分luajit的工具 github能找的 宝宝都试过了..全部基于线性扫描.优化之后的可读性.仍然很差..什么时候能编程.ILCODE转C#的效果就很厉害了.
做肯定能做的,就是没有经济利益,基本都是坑。讲道理,看雪要是能把各种坑掉的项目都接手继续做下去,就可以圈更多的用户了
gtict 2017-5-17 16:42
20
0
问下楼主,,梦幻你修改的lua源码lopcode.c哪个版本的,,我对比了一下5.1.3的,,区别很大。。感觉不太对~~求指点点
littleNA 3 2017-5-20 22:08
21
0
gtict 问下楼主,,梦幻你修改的lua源码lopcode.c哪个版本的,,我对比了一下5.1.3的,,区别很大。。感觉不太对~~求指点点
5.1.5,里面的代码放到了lopcodes.def和lopmodes.def文件,修改下就好了。
另外直接修改opcode和opmode达到的效果不好(存在bug),想到另外一种方式(在加载code之后再替换),而且反编译工具luadec有一些bug,目前正在写相关的文章,之后会发上来。
大王叫我挖坟 3 2017-5-21 10:00
22
0

网上jit的资料太少了,之前看见jit都害怕,现在看着楼主写的感谢爽多了,谢谢分享,好东西啊,收藏了

AndroidK 2017-6-2 22:14
23
0
关于对解密lua后的实际应用能写一个栗子嘛?
xxRea 2017-6-21 00:06
24
0
必须点个赞
学外挂 2017-6-23 10:23
25
0
  连接挂了  能传一份吗
voidFunction 2017-8-19 17:26
26
0
楼主能对  lua虚拟机opcode  是怎么找到的可以详细的讲解一下吗?  我一直卡在这里动不了了.....
gslab实验室 2017-8-21 14:22
27
0
楼主你好,我是gslab游戏安全实验室的,感谢您对gslab的支持,想来转载您这篇文章到gslab官网上,不知道可以吗
littleNA 3 2017-8-21 15:52
28
0
voidFunction 楼主能对 lua虚拟机opcode 是怎么找到的可以详细的讲解一下吗? 我一直卡在这里动不了了.....[em_2]
文章应该写的比较详细了,你是卡在哪一步呢?一个都还原不了还是说还原了部分?如果是还原了部分,剩下的那些,需要对比代码的结构才能还原(具体每个指令的代码结构文章没有写出来,得你自己去看源码),比如  add操作,那你需要找到一个类似  2个寄存器相加并保存  的代码,接着记录opcode就OK了。
littleNA 3 2017-8-21 15:53
29
0
gslab实验室 楼主你好,我是gslab游戏安全实验室的,感谢您对gslab的支持,想来转载您这篇文章到gslab官网上,不知道可以吗
OK。没有问题~
voidFunction 2017-8-22 15:13
30
0
littleNA 文章应该写的比较详细了,你是卡在哪一步呢?一个都还原不了还是说还原了部分?如果是还原了部分,剩下的那些,需要对比代码的结构才能还原(具体每个指令的代码结构文章没有写出来,得你自己去看源码),比如 ad ...
非常感谢楼主的指导,  我现在已经解决了我的难题.  再次感谢!!!
koflfy 1 2017-9-5 14:18
31
0
mark,感谢楼主。。。
聖blue 2017-9-28 18:41
33
0
不错!!!!!!
zm的乖乖 2017-9-29 13:28
34
0
楼主看到回帖,一定要回帖啊!
sshhll 2017-11-8 13:10
35
0
mark,谢谢分享
linfengtai 2017-11-28 23:23
36
0
希望大佬能写一个luajit解密工具。这实在太难了
lxsll 2017-12-24 18:21
37
0
网盘链接挂了    能传一份吗
芃杉 2018-1-23 14:06
38
0
mark
unixc 2018-2-27 17:38
39
0
楼主,能不能附件在传下,动手练习
泪落晨曦 2018-3-29 11:57
40
0
同求大佬的附件再传一下
veyronss 2018-4-1 01:08
41
0
我已经看了n变了,基础太差  真看不懂
littleNA 3 2018-4-9 14:36
42
0
学外挂 连接挂了 能传一份吗
各位不好意思,链接确实挂了。找过好几次都没有找到附件。看看论坛里下载过的朋友能不能上传一份咯......
xxRea 2018-4-10 15:24
43
0
你好,我在还原opcode过程中遇到一点麻烦。
从反编译出来的代码中看,opcode的顺序没有被修改.(我编译了一份原版的lualib,用来做对比).
但是我用原版的unluac工具进行反编译,无法正确的反编译。
您能帮我看下,是否我再对比opcode的过程中出错了吗。
工程是ios64位代码,已经砸壳处理,可以直接反编译.
其中luaV_execute函数的地址为sub_100768BFC。
耽误您的时间,万分抱歉。

工程下载地址:
https://pan.baidu.com/s/1_UK_j7RSNwIEFJYTBoon2A

附件中是一份 Luac文件。
最后于 2018-4-10 15:24 被xxRea编辑 ,原因:
上传的附件:
xxRea 2018-4-11 19:51
44
0
xxRea 你好,我在还原opcode过程中遇到一点麻烦。从反编译出来的代码中看,opcode的顺序没有被修改.(我编译了一份原版的lualib,用来做对比).但是我用原版的unluac工具进行反编译,无法正确的 ...
luac的文件结构,和标准的luac不一致,第12个字节与标准的不一致,导致unluac 抛出异常
抛出异常的代码.目前还无法解决
  protected void parse_number_integrality(ByteBuffer buffer, BHeader header, LHeaderParseState s) {
    int lNumberIntegralityCode = 0xFF & buffer.get();
    if(header.debug) {
      System.out.println("-- Lua number integrality code: " + lNumberIntegralityCode);
    }

    if(lNumberIntegralityCode > 1) {
      throw new IllegalStateException("The input chunk reports an invalid code for lua number integrality: " + lNumberIntegralityCode);
    }

    s.lNumberIntegrality = (lNumberIntegralityCode == 1);
  }



非标准luac头部信息



标准luac头部信息



最后于 2018-4-12 13:15 被xxRea编辑 ,原因:
huangxubang 2018-4-23 23:58
45
0
感谢大的指点。没附件了,看着有些模糊。
wtfkx 2018-4-29 18:53
46
0
你好,请问用ida  下断loadbuffer。这个函数地址需要打开游戏才能找到,但是这个时候loadbuffer已经执行完了,已经断不下来了。
请问我那里搞错了吗

更新:我已经找到原因了。原来是我找错so了。是armeabi-v7里面,不是armeabi里面。。。
最后于 2018-4-30 20:20 被wtfkx编辑 ,原因: 作者666
littleNA 3 2018-5-2 21:37
47
0
huangxubang 感谢大的指点。没附件了,看着有些模糊。
刚上传了附件。
huangxubang 2018-7-21 19:47
48
0
littleNA 刚上传了附件。
感谢大大,上次没看到你的回复。不过你的附件,我在github找到了,也不知道是不是你上传的。个人反编译成功了部分代码。询问一下,改完代码的luajit编译,是不是也要修改opcode,然后生成新的luajit,再生成新的luac,我想打包回去。
littleNA 3 2018-7-26 09:40
49
0
huangxubang 感谢大大,上次没看到你的回复。不过你的附件,我在github找到了,也不知道是不是你上传的。个人反编译成功了部分代码。询问一下,改完代码的luajit编译,是不是也要修改opcode,然后生成新的lu ...
你说的流程应该是没有问题的。但是游戏引擎一般都支持明文脚本的加载,所以也可以不用生成新的 luac。
卿卿吾吧 2018-9-30 21:19
50
0
大佬,求帮我反编译一个小文件,就一个。梦幻的。我Q997260108   感谢!
游客
登录 | 注册 方可回帖
返回