Androlua逆向
去年dasctf x cbctf有道题是Androlua,学长出的一道题,来看看这个逆向流程.
介绍
首先了解Androlua:
AndroLua 是一个轻量级的移动开发框架,它将 Lua 这种简洁高效的脚本语言引入到 Android 平台上。通过 AndroLua,开发者可以利用 Lua 编程语言进行快速原型开发或者对现有应用程序进行扩展。AndroLua 支持运行 Lua 5.2 版本的代码,并提供了一系列 Android SDK 中的类库供 Lua 脚本调用,让开发者能够轻松地操作设备的各种功能,如网络通信、多媒体处理、传感器数据读取等。
逆向流程
由于是以lua为主要,所以安卓包的作用主要是调用lua文件,开头一般是调用init.lua,main.lua这些文件(放在资源目录中)
可以直接定位相关文件.
一般是不加密,可以直接提取用Lua Decompiler反编译.
倘若加密,一般是libluajava.so中的luaL_loadbufferx方法进行加密.
实战
拿学长的题目看看
private void d() {
if (new File(this.b + "/init.lua").exists()) {
try {
int LloadFile = this.k.LloadFile(this.b + "/init.lua");
if (LloadFile == 0) {
this.k.newTable();
LuaObject luaObject = this.k.getLuaObject(-1);
this.k.setUpValue(-2, 1);
int pcall = this.k.pcall(0, 0, 0);
if (pcall == 0) {
if (J == null) {
LuaObject field = luaObject.getField("app_key");
if (field.isString()) {
J = field.toString();
StatService.setAppKey(field.toString());
}
LuaObject field2 = luaObject.getField("app_channel");
if (field2.isString()) {
StatService.setAppChannel(this, field2.toString(), true);
}
StatService.setOn(this, 1);
}
LuaObject field3 = luaObject.getField("appname");
if (field3.isString()) {
setTitle(field3.getString());
}
LuaObject field4 = luaObject.getField("app_name");
if (field4.isString()) {
setTitle(field4.getString());
}
LuaObject field5 = luaObject.getField("debugmode");
if (field5.isBoolean()) {
this.F = field5.getBoolean();
}
LuaObject field6 = luaObject.getField("debug_mode");
if (field6.isBoolean()) {
this.F = field6.getBoolean();
}
LuaObject field7 = luaObject.getField("theme");
if (field7.isNumber()) {
setTheme((int) field7.getInteger());
return;
} else {
if (field7.isString()) {
setTheme(R.style.class.getField(field7.getString()).getInt(null));
return;
}
return;
}
}
LloadFile = pcall;
}
throw new LuaException(a(LloadFile) + ": " + this.k.toString(-1));
} catch (Exception e) {
sendMsg(e.getMessage());
}
}
}
可以找到这个(其实压根没理解他的流程,大概就是加载)
那么我们就要去本地库看看,因为这里有加密.
但是很奇怪,我arm库找半天找不到,问了学长说有,后面看了32位的,突然反编译出来(?)
可以用unidbg来hook出来,解密lua.当然解密逻辑还蛮简单的,脚本也可以.
int __fastcall luaL_loadbufferx(int a1, _BYTE *a2, size_t byte_count, int a4, int a5)
{
_BYTE *v9; // r0
int v10; // r1
int v11; // r2
_DWORD v13[2]; // [sp+8h] [bp-28h] BYREF
v13[0] = a2;
v13[1] = byte_count;
if ( *a2 == 27 && a2[1] != 76 )
{
v9 = malloc(byte_count);
if ( byte_count )
{
*v9 = 27;
if ( byte_count != 1 )
{
v10 = 0;
v11 = 1;
do
{
v10 += byte_count;
v9[v11] = a2[v11];
++v11;
}
while ( byte_count != v11 );
}
}
v13[0] = v9;
}
return j_lua_load(a1, (int)sub_E6AA, (int)v13, a4, a5);
}

浙公网安备 33010602011771号