比较好的android论坛,[原创]送给最好的TA app分析

概述

今天群里有人传了个apk文件,名字叫送给最好的TA。这是一个整人app,安装并打开会播放一段音频,并循环调节媒体音量,维持最大值。从后台划掉/卸载/关机都可以停止该程序。

网传所谓的截图、获取设备信息并上传等行为均不存在。反编译后看到的截图相关代码实际上并没有被调用,只是打包apk时封装进去的类,关键逻辑位于main.lua中。

apk分析

拿到样本之后,别急着安装运行,先看看它的目录结构。

b07aeffc1b025831911083f9a9f50a86.png

打开assets文件夹,看到有一个mp3文件以及两个加密后的lua脚本:

a95b444bd4d29626982df09475df5b5c.png

运行app后会自动播放这个音频文件,先对它进行替换。

这里使用AU对该mp3进行静音处理后,重打包并签名。

(其实也可以替换成自己想要播放的音频)

找到加载lua的关键函数

众所周知,lua脚本需要加载,而在加载之前肯定是要先解密的,所以只要找到解密函数,然后就可以把解密后的lua脚本dump出来。

使用IDA打开libluajava.so,经过分析找到函数luaL_loadbufferx

luaL_loadbufferx的第二个参数是加密的字节数组,第三个参数是大小,第四个参数是lua文件位置。

程序在这个函数中加载加密lua脚本,其中对脚本进行了解密操作。

根据第四个参数我们可以区分目前加载的lua脚本名称,从而选择性地dump

(即在函数开头下断点,查看第四个参数内容)

luaL_loadbufferx函数伪代码如下:

2c37a2cd99d93a25767ab475def9357f.png

首先对输入的字节数组进行判断,如果以1B开头,且第二位不是0C,则进行解密操作,否则直接调用j_lua_load加载lua脚本

在第41行下断点即可获取到解密后的字节数组,从而dump

动态调试进行dump

具体步骤可以参考我之前写的文章

IDA在第41行断下之后,运行python脚本dump即可

import idaapi

data = idaapi.dbg_read_memory(0xf4daff00, 0x3000)

fp = open('d:\\dump.lua', 'wb')

fp.write(data)

fp.close()

此处的0xf4daff00, 0x3000需要替换成解密后字节的起始地址和长度

长度写大一点也没事,可以再用010Editor删除(所以我这写的0x3000)

分析lua

由于dump出来的lua是字节码,并不是源码形式。所以还需要反编译后才能查看源码。(使用unluac_2015_06_13.jar进行反编译)

init.lua中进行包名、版本号、主题、权限等配置

local L0_0

appname = "送给最好的TA"

appver = "1.0"

appcode = "10"

appsdk = "15"

path_pattern = ""

packagename = "com.sgzh.dt"

theme = "Theme_DeviceDefault_Dialog_NoActionBar_MinWidth"

app_key = ""

app_channel = ""

developer = ""

description = ""

debugmode = false

L0_0 = {

"INTERNET",

"WRITE_EXTERNAL_STORAGE"

}

user_permission = L0_0

主要功能在main.lua中完成:

require("import")

import("android.app.*")

import("android.os.*")

import("android.widget.*")

import("android.view.*")

import("android.view.View")

import("android.content.Context")

import("android.media.MediaPlayer")

import("android.media.AudioManager")

import("com.androlua.Ticker")

activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)

activity.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE)

m = MediaPlayer()

m.reset()

m.setDataSource(activity.getLuaDir() .. "/0.mp3")

m.prepare()

m.start()

m.setLooping(true)

ti = Ticker()

ti.Period = 10

function ti.onTick()

activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)

activity.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE)

end

ti.start()

function onKeyDown(A0_0, A1_1)

if string.find(tostring(A1_1), "KEYCODE_BACK") ~= nil then

activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)

end

return true

end

首先设置音频源文件路径为0.mp3,使用单曲循环模式播放音频。然后使用Ticker循环调节媒体音量至最大值,同时拦截了返回键。

主要功能其实跟以前那个叫目力的app差不多。(不过今天这个apk的音频就太那啥了...)

静音样本下载

dump出来的lua

最后于 2019-10-2 13:56

被xhyeax编辑

,原因: 样本补链

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值