用JEB打开,首先扫一眼AndroidManifest.xml
的相关信息
是一个androlua
项目,稍微搜一下就可以知道是用Lua写android。所以安卓本体是一个框架,里面提供的诸多功能都是可选接口。
于是目标直指assetes
目录下的几个lua
文件
dump出来查看一下发现并不符合lua
的文件头,但是两个文件都以0x1b
作为首字节,说明还是有标志的,后面的内容是被加密了
那么还是得回头看一下安卓是怎么加载lua文件的
application是最早执行的类,于是从manifest
文件中获得类名
看了一下没有具体的信息,于是找到Launcher
对应的Activity
,这是最早显示的Activity
Activity
的执行顺序依次为static块
,构造函数
,onCreate
在onCreate
中发现调用了startActivity
进入Main
类
这时先关注一下父类,LuaActivity
父类的onCreate
被首先调用了(第一行super.onCreate()
),发现里面有一些加载方法
getLuaPath
里拿到的就是main.lua
和init.lua
,通过doFile
函数加载,双击进去发现最终指向了Native函数_LloadFile
Native函数就要去动态链接库so中去找了,从lib目录下拿到libluajava.so
用IDA打开,在函数窗口中搜索LloadFile
,即可找到它
继续往里跟,在loadFileX
中注意到首字符比较0x1b
,第二个字符比较0x4c
也就是在确认是否加密
因此这里是可以直接塞入未加密的luac
脚本的
如果第二个字符不是0x4c
,也就是被加密了,则调用loadbufferx
函数
其实基本可以猜到,函数尾部加了x
的就是非lua
原版的自定义加密函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNQHveKa-1569599143832)(https://i.loli.net/2019/09/27/dgsvzUAOwu5kHjn.png)]
加密逻辑还是蛮简单的,size就是整个文件的字节数,每个字节异或一下x
直接照抄
import sys
filename = sys.argv[1]
with open(filename, "rb") as f:
data = f.read()
f = open(filename + "__", "wb")
f.write(b"\x1b")
size = len(data)
v10 = 0
for i in range(1,size):
v10 += size
c = data[i]^(v10+ ((((0xFFFFFFFF80808081 * v10) >> 32) + v10) >> 7) + ((((0xFFFFFFFF80808081 * v10) >> 32) + v10) < 0))
f.write(bytes((c&0xff,)))
解密得到lua5.3的脚本,用unluac
可以反编译出结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVmE4htQ-1569599143834)(https://i.loli.net/2019/09/27/5WJL6yRkBmfM97s.png)]
init
里负责初始化,main
里开始播放声音,然后注册了一个计时器Ticker
,定时将声音调到最大
另外还有一个onKeyDown
设定按键,当按键为KEYCODE_BACK
即返回键的时候也会将声音调到最大
我的手机只有锁屏键和音量键,测了一下是没有阻碍的
主要还是定时器注册上了以后后台也会继续运行╮(╯_╰)╭
代码量只有这些,所以所谓截屏、收集信息等等都是无稽之谈。。。
它也没有把自己注册为系统apk,也没有要root权限,也没有任何其他的对抗,只要冷静的拉出任务栏把它划掉然后长按卸载即可。。