最近一些群里出现了会以最大音量外放音频且无法退出的恶搞Android App,造成了一些不好的影响。恰好借这个机会尝试通过逆向工程分析其原理,同时这个App也使用了Lua脚本并进行了加密,也借此机会实践一下Lua脚本解密。
下文中会给出Lua脚本的解密代码,需要使用 GCC/Clang 等C/C++ 编译器进行编译后执行。
我们首先使用Apktool对其进行解包,假设App的文件名为 App.apk
App.apk
java -jar apktool.jar d App.apk 等待执行完后,打开解包生成的App文件夹 我们需要关注其中几个文件(夹) assets,存放资源文件,包含Lua脚本lua和音频文件mp3 lib,本地库(Native Library)文件夹,包含编译后的本地代码(Native Code)的so文件 smail,存放smail文件,包含Dalvik字节码,是对App的Java代码反向成中立字节码的结果 AndroidManifest.xml,包含App的信息 查看AndroidManifest.xml的内容,可以发现以下样本App信息 App名为送给最好的TA 包名为com.sgzh.dt 0x03 分析Java部分 进入smail,我们可以看到Java部分的代码结构,可以看出存在com.androlua、com.nirenr、com.luajava等包名,搜索相关项目可以发现App的大部分代码均来自于AndroLua_pro。 AndroLua_pro是一个使用Lua编写Android应用的项目,换而言之,Java部分极有可能并不是应用的主体部分,重要操作很有可能会写在Lua中。 除了AndroLua_pro的代码外,我们还发现了com.b.a.a com.b.a.b这两个经过混淆的包名,经过查证得知里面的代码来源于TextWarrior。 我们得知其Java代码基本都是来源于现有项目,无太大分析价值,我们将分析重点放于Lua脚本上。 0x04 分析C部分 在进入Lua部分前,我们使用文本编辑器查看assets文件中的init.lua和main.lua,会发现他们并不是Lua代码,也不是编译后的luac,可以得知Lua脚本被加密了,我们需要先对其进行解密。 AndroLua_Pro所使用的Lua工具LuaJava会加载依赖库libluajava.so,我们使用IDA打开这个文件。LuaJava会使用luaL_loadbuffer或者luaL_loadbufferx函数对Lua脚本进行加载,这个函数也是一个加入Lua脚本解密代码的常见位置,我们在IDA中找到这一函数,并使用自带插件对其进行反编译,可以看到如下内容 (上图为方便阅读,已反混淆变量名) 与AndroLua_pro的原始代码比较,可以发现加入了Lua脚本解密的代码,我们可以参考这一代码,使用C语言编写一个简单的解密工具 #include 文章目录前言分析 前段时间的O泡果奶病毒火了一把,虽然平时很少看android,却也来了兴趣,大致看了一下,也搜了搜,知道了关键点在lua上,可惜之前没接触过lua,当时并没有把脚本解出来。今天看到了一个lua解密的帖子,就试了下,没想到真的成功了,在此作一下记录吧 android目录结构 关键的lua逻辑目录 关键文件是main.lua 使用编辑器看也不是luac文件 当我看到这个帖子时,翻看了下android的目录,果然看到了libluajava.so文件 又了解到libluajav AndroLua 开源项目教程 AndroLuaLua and LuaJava ported to Android项目地址:https://gitcode.com/gh_mirrors/an/AndroLua 项目介绍 AndroLua 是一个将 Lua 解释器移植到 Android 平台的开源项目。该项目不仅包括 Lua 语言本身,还集成了 LuaJava,使得开发者可以通过 Lua 访问几乎... 去年在看雪论坛写了一篇《浅析android手游lua脚本的加密与解密》的精华文章,今年写一篇番外篇,将一些lua反编译对抗的内容整合一起,并以3个实例作为说明(包括2018腾讯游戏竞赛和梦幻西游手游相关的补充),文章开头还增加了相关工作,方便大家学习lua逆向时使用。本文由3篇文章整合成1篇,所以内容上面有点多,有兴趣的朋友需要点耐心,当然也可以跳着看。最后,请大佬们不吝赐教。最最后,... 为了方便开发,编写了一个Lua预编译的小工具,配合我的框架 Loxodon.Framework使用,源码下载地址:Loxodon.Framework.Xlua使用Lua预编译工具可以将Lua脚本预编译为字节码文件,并且可以选择是否加密该文件。Lua官方的luac命令编译的字节码分64位和32位,如果想编译64位和32位兼容的字节码,请参考XLua的官方文件,有关通用字节码编译的部分《通用字节码》。... 反编译本人用到的是luajit-decomp,这里需要注意,luajit-decomp默认的lua版本为5.1,luajit版本为2.0.2,我们需要下载对应lua和luajit的版本,编译后替换luajit-decomp下的lua51.dll、luajit.exe、jit文件夹。源码用了宏,计算出来的结果就是上表中opmode的结果。如SETLIST,原opcode为34,opmode为0x14,找到的opmode的第8个字节也为0x14,则实际上SETLIST的opcode为8。 随着手游的发展,越来越多的Cocos-lua端游开发者转移到手游平台。Lua脚本编写逻辑的手游也是越来越多,如梦幻西游、刀塔传奇、开心消消乐、游龙英雄、奇迹暖暖、疾风猎人、万万没想到等手游。随着Lua手游的增加,其安全性更值得关注,在此归纳一些常用的分析方法,同时介绍一些辅助工具。Android平台的apk包可以直接解压,找到./lib目录下的so逻辑模块,一个个分析其so,寻找是否内嵌lua引擎(一般情况下,最大的so最有可能内嵌lua引擎)。 这里有个小技巧,当有很多so文件的时候,一般最大的文件是我们的目标(文件大是因为集成了lua引擎)。其中lua是明文代码,直接用记事本就能打开,luac是lua编译后的字节码,文件头为0x1B 0x4C 0x75 0x61 0x51,lua虚拟机能够直接解析lua和luac脚本文件,而luaJIT是另一个lua的实现版本(不是原作者写的),JIT是指Just-In-Time(即时解析运行),luaJIT相比lua和luac更加高效,文件头是0x1B 0x4C 0x4A。 其中lua是明文代码,直接用记事本就能打开,luac是lua编译后的字节码,文件头为0x1B 0x4C 0x75 0x61 0x51,lua虚拟机能够直接解析lua和luac脚本文件,而luaJIT是另一个lua的实现版本(不是原作者写的),JIT是指Just-In-Time(即时解析运行),luaJIT相比lua和luac更加高效,文件头是0x1B 0x4C 0x4A。这个情况主要是先解密后反编译,反编译主要是通过luajit-decomp项目,它能够将luajit字节码反编译成伪lua代码。 还是以大神apk为例,通过前面分析app解密lua脚本,我们能够解密大神apk的lua脚本,现在我们来解密其资源(配置文件和图片等)。我们以比较重要的配置文件为例,未解密之前: 文件头部也有签名值:fuckyou!。看到这,我们首先就想到是不是也是用xxtea加密的,我们用上面的方法,先xxtea解密,再解压,发现依旧是乱码,在操作的过程中就出现了错误,显然,要否定我们刚才的猜想...
java -jar apktool.jar d App.apk 等待执行完后,打开解包生成的App文件夹 我们需要关注其中几个文件(夹) assets,存放资源文件,包含Lua脚本lua和音频文件mp3 lib,本地库(Native Library)文件夹,包含编译后的本地代码(Native Code)的so文件 smail,存放smail文件,包含Dalvik字节码,是对App的Java代码反向成中立字节码的结果 AndroidManifest.xml,包含App的信息 查看AndroidManifest.xml的内容,可以发现以下样本App信息 App名为送给最好的TA 包名为com.sgzh.dt
等待执行完后,打开解包生成的App文件夹 我们需要关注其中几个文件(夹)
App
assets
lua
mp3
lib
so
smail
AndroidManifest.xml
查看AndroidManifest.xml的内容,可以发现以下样本App信息
送给最好的TA
com.sgzh.dt
0x03 分析Java部分 进入smail,我们可以看到Java部分的代码结构,可以看出存在com.androlua、com.nirenr、com.luajava等包名,搜索相关项目可以发现App的大部分代码均来自于AndroLua_pro。 AndroLua_pro是一个使用Lua编写Android应用的项目,换而言之,Java部分极有可能并不是应用的主体部分,重要操作很有可能会写在Lua中。 除了AndroLua_pro的代码外,我们还发现了com.b.a.a com.b.a.b这两个经过混淆的包名,经过查证得知里面的代码来源于TextWarrior。 我们得知其Java代码基本都是来源于现有项目,无太大分析价值,我们将分析重点放于Lua脚本上。 0x04 分析C部分 在进入Lua部分前,我们使用文本编辑器查看assets文件中的init.lua和main.lua,会发现他们并不是Lua代码,也不是编译后的luac,可以得知Lua脚本被加密了,我们需要先对其进行解密。 AndroLua_Pro所使用的Lua工具LuaJava会加载依赖库libluajava.so,我们使用IDA打开这个文件。LuaJava会使用luaL_loadbuffer或者luaL_loadbufferx函数对Lua脚本进行加载,这个函数也是一个加入Lua脚本解密代码的常见位置,我们在IDA中找到这一函数,并使用自带插件对其进行反编译,可以看到如下内容 (上图为方便阅读,已反混淆变量名) 与AndroLua_pro的原始代码比较,可以发现加入了Lua脚本解密的代码,我们可以参考这一代码,使用C语言编写一个简单的解密工具 #include 文章目录前言分析 前段时间的O泡果奶病毒火了一把,虽然平时很少看android,却也来了兴趣,大致看了一下,也搜了搜,知道了关键点在lua上,可惜之前没接触过lua,当时并没有把脚本解出来。今天看到了一个lua解密的帖子,就试了下,没想到真的成功了,在此作一下记录吧 android目录结构 关键的lua逻辑目录 关键文件是main.lua 使用编辑器看也不是luac文件 当我看到这个帖子时,翻看了下android的目录,果然看到了libluajava.so文件 又了解到libluajav AndroLua 开源项目教程 AndroLuaLua and LuaJava ported to Android项目地址:https://gitcode.com/gh_mirrors/an/AndroLua 项目介绍 AndroLua 是一个将 Lua 解释器移植到 Android 平台的开源项目。该项目不仅包括 Lua 语言本身,还集成了 LuaJava,使得开发者可以通过 Lua 访问几乎... 去年在看雪论坛写了一篇《浅析android手游lua脚本的加密与解密》的精华文章,今年写一篇番外篇,将一些lua反编译对抗的内容整合一起,并以3个实例作为说明(包括2018腾讯游戏竞赛和梦幻西游手游相关的补充),文章开头还增加了相关工作,方便大家学习lua逆向时使用。本文由3篇文章整合成1篇,所以内容上面有点多,有兴趣的朋友需要点耐心,当然也可以跳着看。最后,请大佬们不吝赐教。最最后,... 为了方便开发,编写了一个Lua预编译的小工具,配合我的框架 Loxodon.Framework使用,源码下载地址:Loxodon.Framework.Xlua使用Lua预编译工具可以将Lua脚本预编译为字节码文件,并且可以选择是否加密该文件。Lua官方的luac命令编译的字节码分64位和32位,如果想编译64位和32位兼容的字节码,请参考XLua的官方文件,有关通用字节码编译的部分《通用字节码》。... 反编译本人用到的是luajit-decomp,这里需要注意,luajit-decomp默认的lua版本为5.1,luajit版本为2.0.2,我们需要下载对应lua和luajit的版本,编译后替换luajit-decomp下的lua51.dll、luajit.exe、jit文件夹。源码用了宏,计算出来的结果就是上表中opmode的结果。如SETLIST,原opcode为34,opmode为0x14,找到的opmode的第8个字节也为0x14,则实际上SETLIST的opcode为8。 随着手游的发展,越来越多的Cocos-lua端游开发者转移到手游平台。Lua脚本编写逻辑的手游也是越来越多,如梦幻西游、刀塔传奇、开心消消乐、游龙英雄、奇迹暖暖、疾风猎人、万万没想到等手游。随着Lua手游的增加,其安全性更值得关注,在此归纳一些常用的分析方法,同时介绍一些辅助工具。Android平台的apk包可以直接解压,找到./lib目录下的so逻辑模块,一个个分析其so,寻找是否内嵌lua引擎(一般情况下,最大的so最有可能内嵌lua引擎)。 这里有个小技巧,当有很多so文件的时候,一般最大的文件是我们的目标(文件大是因为集成了lua引擎)。其中lua是明文代码,直接用记事本就能打开,luac是lua编译后的字节码,文件头为0x1B 0x4C 0x75 0x61 0x51,lua虚拟机能够直接解析lua和luac脚本文件,而luaJIT是另一个lua的实现版本(不是原作者写的),JIT是指Just-In-Time(即时解析运行),luaJIT相比lua和luac更加高效,文件头是0x1B 0x4C 0x4A。 其中lua是明文代码,直接用记事本就能打开,luac是lua编译后的字节码,文件头为0x1B 0x4C 0x75 0x61 0x51,lua虚拟机能够直接解析lua和luac脚本文件,而luaJIT是另一个lua的实现版本(不是原作者写的),JIT是指Just-In-Time(即时解析运行),luaJIT相比lua和luac更加高效,文件头是0x1B 0x4C 0x4A。这个情况主要是先解密后反编译,反编译主要是通过luajit-decomp项目,它能够将luajit字节码反编译成伪lua代码。 还是以大神apk为例,通过前面分析app解密lua脚本,我们能够解密大神apk的lua脚本,现在我们来解密其资源(配置文件和图片等)。我们以比较重要的配置文件为例,未解密之前: 文件头部也有签名值:fuckyou!。看到这,我们首先就想到是不是也是用xxtea加密的,我们用上面的方法,先xxtea解密,再解压,发现依旧是乱码,在操作的过程中就出现了错误,显然,要否定我们刚才的猜想...
进入smail,我们可以看到Java部分的代码结构,可以看出存在com.androlua、com.nirenr、com.luajava等包名,搜索相关项目可以发现App的大部分代码均来自于AndroLua_pro。 AndroLua_pro是一个使用Lua编写Android应用的项目,换而言之,Java部分极有可能并不是应用的主体部分,重要操作很有可能会写在Lua中。
com.androlua
com.nirenr
com.luajava
除了AndroLua_pro的代码外,我们还发现了com.b.a.a com.b.a.b这两个经过混淆的包名,经过查证得知里面的代码来源于TextWarrior。
com.b.a.a
com.b.a.b
我们得知其Java代码基本都是来源于现有项目,无太大分析价值,我们将分析重点放于Lua脚本上。
在进入Lua部分前,我们使用文本编辑器查看assets文件中的init.lua和main.lua,会发现他们并不是Lua代码,也不是编译后的luac,可以得知Lua脚本被加密了,我们需要先对其进行解密。
init.lua
main.lua
AndroLua_Pro所使用的Lua工具LuaJava会加载依赖库libluajava.so,我们使用IDA打开这个文件。LuaJava会使用luaL_loadbuffer或者luaL_loadbufferx函数对Lua脚本进行加载,这个函数也是一个加入Lua脚本解密代码的常见位置,我们在IDA中找到这一函数,并使用自带插件对其进行反编译,可以看到如下内容 (上图为方便阅读,已反混淆变量名) 与AndroLua_pro的原始代码比较,可以发现加入了Lua脚本解密的代码,我们可以参考这一代码,使用C语言编写一个简单的解密工具
LuaJava
libluajava.so
luaL_loadbuffer
luaL_loadbufferx
#include