浅析钱柜娱乐开户手游lua脚本的加密与解密

转载 2017年11月12日 21:51:47

本文转载自
梦幻西游手游美术资源加密分析
浅析钱柜娱乐开户手游lua脚本的加密与解密

lua、luac、luaJIT三种文件的关系

lua手游过程中有三种文件:lua、luac、luaJIT。lua是明文代码,直接用记事本就能打开;luac是lua编译后的字节码,文件头为0x1B 0x4C 0x75 0x61 0x51,lua虚拟机能够直接解析lua和luac脚本文件;而luaJIT是另一个lua的实现版本,JIT是指Just-In-Time(即时解析运行),luaJIT比lua和luac更加高效,文件头是0x1B 0x4C 0x4A。
这里写图片描述

lua脚本的保护

一般有安全意识的游戏厂商都不会直接把lua源码脚本打包到APK中发布,所以一般对lua脚本的保护有下面3种。
1.在加载lua脚本之前解密(luaL_loadbuffer)
2.将lua脚本编译成luaJIT字节码再加密打包(loadChunksFromZIP)
3.修改lua虚拟机中opcode的顺序
下面用几个实例说明如何获取lua源码。

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

54捕鱼

查看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。
这里写图片描述
一直向上回溯,来到下图,发现xiaoxian为密钥,XXFISH为签名。
这里写图片描述
直接分析loadChunksFromZIP函数的源码会发现调用了XXTea算法。这里本来需要配置一个cocos2d的开发环境来写解密函数,但是我偷个懒,直接用别人写好的一个小工具cocos-lua、quick-cocos等游戏引擎的lua加密文件破解工具
这里写图片描述
解密后的文件如下。
这里写图片描述
这几个都是更新游戏的代码,是luajit的文件,所以接下来需要反编译。IDA中查看下lua版本和luajit版本。
这里写图片描述
这里写图片描述
反编译用的是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编辑器格式化代码。

捕鱼达人4

这个游戏主要是用IDA动态调试so文件,然后用IDC脚本把lua文件全部dump下来。IDA加载libcocos2dlua.so文件,定位到函数luaL_loadbuffer。

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;                                                
    AddBpt(bp_addrese);                                                     
    while(1)
    {
        code = GetDebuggerEvent(WFNE_SUSP|WFNE_CONT, 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);                       
        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;
    };
}

通过IDC脚本获取的部分数据如下。
这里写图片描述
虽然文件的后缀名是.luac,但其实都是明文的lua脚本。

梦幻西游

lib下存在libcocos2dlua.so,基本上确定是lua写的。在assets\HashRes目录下,存在很多被加密的文件,这里存放的是lua脚本和游戏的其他资源文件。
这里写图片描述
HashRes中的文件夹名称和子文件名组合成了一个4字节的Hash名,如下图反编译so文件后看到的寻找资源的Hash路径。
这里写图片描述
先分析图片是怎样加载的,在IDA中定位到cocos2d::Image::initWithImageData()这个方法。
这里写图片描述
比较文件头然后解密,之后判断了该图片是否压缩了,如果压缩了就解压缩,ccz和gzip是coocs2dx源码中本来就有的,lzma是梦幻后加的。
这里写图片描述
解压后先通过cocos2d::Image::detectFormat()这个方法判断是什么类型的图片,然后根据类型加载这个图片。
这里写图片描述
lua的加载比图片加载稍微复杂一点,定位到cocos2d::LuaStack::luaLoadBuffer()这个方法。这里IDA 7.0反编译出来有点问题,所以换到IDA 6.8了。
这里写图片描述
最终得到的lua资源文件为lua编译过的二进制文件,并不是lua源码,想得到源码就得反编译luac文件。但是梦幻西游修改了lua虚拟机中的opcode,所以不能直接用工具。那么怎么在IDA中寻找opcode呢?大致有以下几种方法。
1.IDA搜索opname
这里写图片描述
通过交叉引用来到这里。
这里写图片描述
off_8D281C为opname的地址,byte_874DC0为opmode的地址,进入opmode地址查看。
这里写图片描述
到这一步,已经能还原部分opcode了,因为有一些opmode是唯一的。比如SETLIST原opcode为34,opmode为0x14,找到的opmode的第8个字节也为0x14,则实际上SETLIST的opcode为8。不过opmode不唯一的太多,所以这种方法仅仅能还原下面的opcode。
这里写图片描述
2.通过luaV_execute或者symbexec中的switch循环
lua源码和IDA F5后的代码其实差别还是有的,而且源码用了大量的宏,所以源码只是用来参考、理解lua虚拟机的解析过程,在还原的过程中再打开一个没有修改opcode的libcocos2dlua.so文件,这样对比查找就方便多了。一般最大的switch循环就是。
这里写图片描述
还可以通过luaV_execute中的字符串如initial value must be a number,limit must be a number,step must be a number等定位。
这里写图片描述
实在不行就只能自己去看源码,找特征或者找结构了。比如下面这个游戏,很有可能是选择2个opcode对应1个原opcode。
这里写图片描述
这里写图片描述
最后的结果如下。
这里写图片描述
这里写图片描述
工具:https://github.com/houjingyi233/extract-menghuanxiyou-resource

skynet项目lua代码简单加密

skynet总体跟 erlang很像,理念都是基于Actor模型,即万物皆Actor,Actor之间通过发送消息进行通信。不同的是,skynet使用 c 和 lua实现,这两个语言相较erlang比较...
  • cwqcwk1
  • cwqcwk1
  • 2015年08月13日 01:19
  • 5415

Lua文件加密

项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚本编译为字节码(bytecode)从而实现加密,试了一下,确实可行。 下面是使用原生的lua解释器编译字节码: ...
  • netcaoniao
  • netcaoniao
  • 2015年10月15日 19:25
  • 2979

luajit lua文件加密工具

cocos2dx-lua项目发布时,为了保护lua源码,需要对lua进行加密。通常分为两种方式:加密文件和编译为字节码。 1、加密文件   前提是你不用luajit,而使用lua。这样这种方法是真...
  • u013886824
  • u013886824
  • 2014年11月10日 15:10
  • 2036

Lua 脚本的加密

原文链接:http://www.cocoachina.com/bbs/read.php?tid=205802 项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚...
  • a673544319
  • a673544319
  • 2017年07月02日 16:50
  • 434

lua脚本加密解密

  • 2014年01月06日 16:51
  • 308KB
  • 下载

cocos 使用Luajit将Lua脚本编译为bytecode,从而实现加密

项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚本编译为字节码(bytecode)从而实现加密,试了一下,确实可行。 下面是使用原生的lua解释器编译字节码: ...
  • laozitianxia
  • laozitianxia
  • 2015年06月04日 17:54
  • 1343

游戏脚本lua

  • 2013年08月16日 11:21
  • 137KB
  • 下载

一个用lua写的游戏脚本实例

  • 2010年04月19日 13:28
  • 137KB
  • 下载

skynet lua加密方法

最近在看skynet的代码,总体感觉跟 erlang很像,理念都是基于Actor模型,即万物皆Actor,Actor之间通过发送消息进行通信。(这里说的“万物”倾向于表示有能动作用,有独立行为的个体。...
  • u014659211
  • u014659211
  • 2016年03月14日 12:55
  • 484

cocos lua 加密与解密 混淆 (版本cocos3.4)

cocos luacompile cocos luacompile OverviewUsageAvailable ArgumentsSamples Overview Compile the .l...
  • Kaitiren
  • Kaitiren
  • 2015年03月19日 14:17
  • 14067
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅析钱柜娱乐开户手游lua脚本的加密与解密
举报原因:
原因补充:

(最多只允许输入30个字)