解密lua

进入关键函数Lua_loader_buffer首先判断第一个字符为=

之后根据base64解码表映射解密base64,其中将第一个字符替换为0x1d,即为0x1d+0x2b=H
在这里插入图片描述

解码base64后的结果如下所示

如果第一个字符为0x1c进行异或解密

最后再将第一个字符0x1c替换为0x78,进行inflate解码,解码完成后将第一个字符替换为28(0x1c)

解密算法如下

import base64
import base64
import zlib
fp=open("main.lua","rb")
buffer=fp.read()
buffer=b'H'+buffer[1:]
buffer=base64.b64decode(buffer)
init=0
buffer_dec1=[]
for i in buffer:
    init=init^i
    buffer_dec1.append(init)
buffer_dec1=bytes(buffer_dec1)
buffer_dec2=b'\x78'+buffer_dec1[1:]
decompressed = zlib.decompress(buffer_dec2)
print(decompressed[0])
with open("main.lua_dec","wb") as f:
    f.write(b'\x1b'+decompressed[1:])

得到Luas的文件,利用unluac反编译,提示错误的signature

看了下lua文件头,修改第一个字符为0x1b

java -jar unluac.jar main.lua_dec 

成功反编译,不过得到类似如下的文件 字符串都被加密

_ENV["u\229\136\006\133\020\186"]("o\024\148;\177G")
_ENV["o\024\148;\177G"]("l\021\141*\169\\\199<\225\158-\229\016")
_ENV["o\024\148;\177G"]("m\023\130&\174F\248$\024\151|\149")
_ENV["o\024\148;\177G"]("q\239\150\022\186.\220\004\236d\026\136\004\166j\159")
_ENV["o\024\148;\177G"]("o\019\136.\164R\2064\255\145\r\160i\156")
_ENV["o\024\148;\177G"]("j\025\1472\1866")
_ENV["i\018\174-\219~\244\144"]["{\230\138.\157\020\129\r"

lua字符串解密

跟踪lua 5.3源码。

lua_load()@lapi.c
  |-lua_lock()
  |-luaZ_init()
  |-luaD_protectedparser()
  | |-luaZ_initbuffer()
  | |-luaD_pcall()                    # 实际调用的是f_parser()
  | | |-zgetc()                       # 获取第一个字符,判断是否已经编译
  | | |                               #=================
  | | |-checkmode()                   # 1. 如果是二进制
  | | |-luaU_undump()                 #  1.1 加载预编译的二进制代码
  | | |-checkmode()                   # 2. 如果是文本
  | | |-luaY_parser()
  | | | |-mainfunc()
  | | |   |-luaX_next()
  | | |   | |-llex()
  | | |   |-statlist()                # 词法解析主函数
  | | |     |-statement()             # 根据相应的词法进行处理
  | | |       |-ifstat()              #
  | | |       |-whilestat()
  | | |                               #=================
  | | |-luaF_initupvals()
  | |-luaZ_freebuffer()               # 释放一系列缓存
  | |-... ...
  |-lua_unlock()

发现load_string函数被魔改

static TString* LoadString(LoadState* S) {
  size_t size = LoadByte(S);
  if (size == 0xFF)
    LoadVar(S, size);
  if (size == 0)
    return NULL;
  else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
    char buff[LUAI_MAXSHORTLEN];
    LoadVector(S, buff, size);
    return luaS_newlstr(S->L, buff, size);
  } else { /* long string */
    TString* ts = luaS_createlngstrobj(S->L, size);
    LoadVector(S, getstr(ts), size); /* load directly in final place */
    return ts;

解密算法大致如下

  int x=size-1;
    int v5=b.charAt(0)^x;
    int v6=x+v5;
    char v8=(char)x;
    for(int i=0;i<size-1;i++){
	    v8=(char)((char)x%255);
	    x+=v6;
	    b.setCharAt(i,(char)(((char)b.charAt(i))^((char)v8)));

修改unluac LstringTypejava中的代码即可实现解密得到源码

require("import")
import("android.app.*")
import("android.os.*")
import("android.widget.*")
import("android.view.*")
import("layout")
activity.setTheme(R.Theme_Blue)
activity.setTitle("HelloWorld")
activity.setContentView(loadlayout(layout))
function start.onClick()
  print("thank")
  os.execute("/data/local/tmp/edh269")

https://gohalo.me/post/lua-sourcecode.html

进入关键函数Lua_loader_buffer首先判断第一个字符为=之后根据base64解码表映射解密base64,其中将第一个字符替换为0x1d,即为0x1d+0x2b=H解码base64后的结果如下所示如果第一个字符为0x1c进行异或解密最后再将第一个字符0x1c替换为0x78,进行inflate解码,解码完成后将第一个字符替换为28(0x1c)解密算法如下import base64import base64import zlibfp=open("main.lua","rb")
把工具放到D盘APK文件夹,然后把要加密或者解密的apk名字改成1.apk,点击加密或解密bat就能实现apk的伪加密或解除伪加密功能,就是打开后apk文件带*,要解压出来需要密码,但是真正的密码是不存在的因为这个是伪加密。 如果想放别的文件夹请自行用记事本打开bat进行修改。
大家好我是于你,我今天晚上测试了## andlua加密方式 我发现andlua官方加密并不是base64加密,我尝试了很多解密方式发现:andlua中的lua文件不知道是哪一种,各种解码都试了都不行,我用luatool解密确实很顺,但是有时候电脑不在身边,就想知道andlua是什么加密方式,这样才可以进行解密
2018.05.02更新 这段时间在翻备份的硬盘,突然发现了以前的分析项目和代码,从里面提取了之前附件的内容,现在上传给大家,真是柳暗花明又一村啊。附件包括201703版本的梦幻手游里面提取的so文件和一些加密后的资源文件(包括lua脚本),并包括了2个扑鱼APK文件,最后还打包了解密代码,供大家参考。 附件太大,快100MB,上传不来论坛,我又放到百度网盘了...... 链接:https://pan.baidu.com/s/1DVgH0qHYPkiHB...
​Android对话框是一种程序与用户交互的方式,通常用于显示当前程序的提示信息和相关说明。对话框一般以小窗口的形式展示在Activity之上,对话框显示时,处在下层的Activity失去焦点,对话框便可以接收用户交互的信息。 普通对话框 一般只显示提示信息,通常有“确定”和“取消按钮”,如下: 代码如下: public void close(View view){ new AlertDialog.Builder(this) .setTitle("普通