Android脱壳反编译
有壳
查壳(仅供参考)
APK helper
APK helper工具用于查看apk文件简单信息,包括包名、证书、版本、文件信息等
PKiD 查壳工具
PKiD工具,将apk文件拖入可以查看是否加壳
有壳的情况可以采取以下措施:
1、Xposed框架
1、百度搜索FDex2、MT管理器、开发者助手、Xposed Installer、要实验的软件(同声翻译超级版),下载相应的APP安装包,在手机或模拟器中安装
2、Xposed Installer的基本原理是修改了ART/Davilk虚拟机,将需要hook的函数注册为Native层函数。当执行到这一函数是虚拟机会优先执行Native层函数,然后再去执行Java层函数,这样完成函数的hook。在安装Xposed时会遇到一下问题:
(1)安装框架时报TheXposed framework is not installed.Please download the latest ZIP file from XDAand flash it manually via recovery.
下载SDKplatform23,放到模拟器安装目录的platforms文件夹下
(2)安装完XposedInstaller后,打开软件,状态为Xposed框架未安装
点击official,选在我们需要的版本进行安装
安装完成后重启模拟器即可生效
在模块中勾选FDex2软件,重启模拟器后生效
脱壳步骤
1、打开开发者助手,赋予相应权限及悬浮窗
2、打开要脱壳的目标APP,点击开发者助手悬浮窗,可查看该APP是否加壳
3、打开FDex2,点击要脱壳的APP名称,弹出dex输出目录等信息,保存该路径
4、打开MT管理器,进入/data/user/0/android.translate.xxx,查看hook出来的dex文件
5、上图红色框内的dex文件不能编译,所以我们需要把它移动到左侧文件列表中
6、在/data/app/android.translate.xxx-1路径下找到要脱壳的目标软件包,点击base.apk查看其详细信息
7、点击查看,可以进入目标软件的各文件路径
8、在步骤5中找到与步骤7中classes.dex文件大小差不多的dex文件,用dex编辑器打开,查看里面是否含有步骤3中的hook包名
9、找到对应dex文件并删除多余的dex文件,对该文件重命名为classes.dex文件,
并移动到软件安装包内(如果报无权限,可在属性中修改相应权限)
10、AndroidManifest.xml用反编译方式打开,把第15行的com.tencent.StuShell.TxAppEntry替换成18行的android.translate.xuedianba.BaseApplication,替换完之后删除第16-18行
保存并退出文件
11、提示:在压缩文件中更新,点击确定
12、打开软件的功能选项,点击apk签名
13、签名成功后,点击安装(此处要先卸载之前安装的版本,卸载完之后安装即可)
注:除此之外,在夜神新版的模拟器上,以Android5.1的框架安装Xposed3.5后,会有云下载框架,不会有安装问题
2、drizzleDumper
adb连接夜神模拟器
-
打开夜神模拟器,打开设置,调成手机模式,初次进入的话,进入设置,点击版本号5次,可以激活使用开发者模式,进入后打开USB调试功能
-
打开文件资源管理器,进入夜神模拟器的安装位置,在地址栏输入cmd,回车,会打开cmd窗口,进入的路径就是夜神模拟器的安装位置。我的默认安装位置:E:\ProgramFiles\yeshen\Nox\bin
-
输入nox_adb.exe connect 127.0.0.1:62001即可以连接到adb
或者是 adb connect 127.0.0.1:52001
adb connect 127.0.0.1:62001
-
adb devices查看连接设备情况
拖进模拟器
1、在模拟器下,执行adb push E:\01安装包\02app\Android砸壳\drizzleDumper-master /data/local/tmp (前面是物理机下drizzleDumper工具地址,后面是模拟器下指定地址)
2、adb shell进入shell模式,查看:
3、执行命令exit,退出shell模式,且用步骤1里的命
adb push C:\Users\Administrator\Desktop\apk\anma_driver.apk /data/local/tmp
将要脱壳的APP放入到模拟器中
4、赋予drizzleDumper超级权限
chmod 777 /data/local/tmp/drizzleDumpe/libs/x86/drizzleDumper
脱壳
1、adb shell下执行/data/local/tmp/drizzleDumpe/libs/x86/drizzleDumper com.amcx.driver
2、可见脱了壳的文件保存在/data/local/tmp文件中
3、Frida
使用Frida的方式有两种:一种是模拟器(雷电、夜神均可);另一种是手机(需要root)。
第一种:模拟器(夜神为主)
配置环境:windows10(客户端)、模拟器(服务端)
1、Windows安装python并安装frida模块
python3 -m pip install frida
python3 -m pip install frida-tools
2、在github上下载frida-server(https://github.com/frida/frida/releases),frida提供了各种系统平台的server,这里直接使用适用于模拟器版本的
解压后,进入模拟器的bin中,如夜神默认安装目录的bin中:
此处打开cmd,输入如下命令:
nox_adb.exe devices
如果出现以上内容,那么代表也可以当做adb使用。
接下来,将解压出来的frida-server放到bin目录下并执行以下命令将frida放入模拟器的/data/local/tmp文件目录中
adb push frida-server64 /data/local/tmp
进行端口转发:
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
切换到Android 执行的shell中:
adb shell
切换到root权限并在Android的目录中进行赋权:
su
cd /data/local/tmp/
chmod 755 frida-server86
再执行frida-server86达到运行server端效果:
./frida-server86
3、测试安装环境
windows主机上开启另外一个cmd,输入命令 frida-ps -U ,这行命令是列出手机上所有的进程信息,如果出现进程信息则说明环境搭配成功:
注:额外的hook测试1
import sys
import frida
jscode = """Java.perform(function () {
var OnlineJudgeApp = Java.use('com.yuanrenxue.onlinejudge2020.OnlineJudgeApp');
OnlineJudgeApp.getSign.implementation = function (j) {
send("参数: j");
send(j);
var sign = this.getSign(j);
send("结果: sign");
send(sign);
return sign;
}
});"""
# 等待绑定的回调函数
def message(message, data):
if message["type"] == 'send':
print(message['payload'])
else:
print(message)
process = frida.get_remote_device().attach('com.yuanrenxue.onlinejudge2020') # 按包名的方式附加js脚本
script = process.create_script(jscode) # 加载已有的js代码
script.on("message", message) # 绑定发送时接收的回调函数
script.load() # 载入js脚本
sys.stdin.read() # 等待系统输入
运行后,在app内输入任意数字,然后点击查询,就会打印如下内容
参数: j
12
结果: sign
X+lUrtCOyoCzrGmT6rWEhzLoQJ#TpWJap+OjyrYQEOYldr#k+qFGqru45T9wkiEMXr#g56yICvMzo02JCtFYxlY5GTNk9oxAov3cA0ZW8b+s5vBUdI==
额外测试2
import frida
import sys
#获取设备信息
rdev = frida.get_remote_device()
#获取在前台运行的APP
front_app = rdev.get_frontmost_application()
print (front_app)
你在模拟器上运行一个微信。
weixin = "com.tencent.mm"
# 枚举进程中加载指定模块中的导出函数
session = rdev.attach(weixin) # 也可以使用attach(pid)的方式
# 我找了半天,老版本的enumerateModules方法没了,现在只能通过js入口
jscode = """
Process.enumerateModules({
onMatch:function(exp){
send(exp.name);
},
onComplete:function(){
send("stop");
}
})
"""
script = session.create_script(jscode)
def on_message(message, data):
print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()
4、下载脱壳脚本并运行(前提是app没有反模拟器,如果有请在被root的手机上执行整个操作)
frida脚本地址:
https://github.com/hluwa/FRIDA-DEXDump
下载后运行,在手机端点击启动app,app启动后,pc端运行python3 main.py
选择进程(双进程一般是防止ida,gdb等程序挂载),这里选择12597,直接输入1,一般选择高进程,猜测原因是壳的保护进程优先启动,被保护的进程后启动
找到保存路径:
用jadx打开,几个看看,发现源代码暴露了出来:
注:该方法不一定完全有用,主要看情况,反正不少银联app没成功过
无壳
1、Apktool
反编译 xml 文件和 dex 文件,并可以将编译后的项目重新打包成 apk2、dex2jar
将 classes.dex 转换为「.jar」文件)3、jd-gui
查看「.jar」文件
1、Apktool
我们可以通过 Apktool 可以将 apk 文件进行反编译,但是直接把 apk 的扩展名改成「.zip」也可以对其进行解压并得到一些资源文件。
左边是直接解压,右边是通过apktool反编译的
- META-INF 里保存 App 的签名信息
- classes.dex
.dex 是 Dalvik 虚拟机上的可执行文件,需要使用 dex2jar 将其转换为 jar 文件- AndroidManifest.xml
Android 清单文件,向 Android 系统提供应用的必要信息。- assets
存放一些资源文件字体,声音等。- lib
存放第三方库- original
存放未经过反编译的等 AndroidManifest.xml 文件- res
存放资源文件,例如图片,颜色,字符等。- smali
smali 里存放的是 java 编译成的 smali 代码,smali 相当于 Android 虚拟机上运行的语言。直接解压可以得到一些资源文件,但是 AndroidManifest.xml 和其他的 xml 文件都是乱码,通过 Apktool 进行反编译,可以最大限度的还原这些文件的内容。
cd apk目录
apktool d test.apk
运行完成后,得到一个包含资源文件和代码的文件
注意:此时 dex 文件直接反编译成了 smali文件,而我们需要的是 .dex 文件。
此时再运行:
$ apktool d -s -f test.apk
-d 反编译 apk 文件
-s 不反编译 dex 文件,而是将其保留
-f 如果目标文件夹存在,则删除后重新反编译
补充:Dex2jar
将上一步得到的 classes.dex 文件(有时候还有 classes2.dex,说明方法数过多,把它当成 classes.dex 处理就好了)复制到 dex2jar 解压好的目录中。
- 在命令行中运行:
sh d2j-dex2jar.sh classes.dex
如果提示:
d2j-dex2jar.sh: line 36: ./d2j_invoke.sh: Permission denied
执行
sudo chmod +x d2j_invoke.sh
后再次执行
sh d2j-dex2jar.sh classes.dex
运行成功,在当前目录下生成了 classes-dex2jar.jar 文件
安装好 jd-gui 之后,用其将 classes-dex2jar.jar 打开,就可以看到反编译出来的 java 代码了!
当然使用jadx_v1.2.0.zip可以直接看到classes.dex文件代码
2、在线反编译
地址:
http://www.decompileandroid.com/?utm_source=androiddevtools&utm_medium=website
3、JEB 反编译工具
JEB是一款Android应用程序反编译工具,用于逆向分析、代码审计,具有静态分析和动态分析的能力
下载地址:https://www.pnfsoftware.com
双击bat文件启动,直接将需要反编译的apk丢进去即可
Manifest文件是清单文件(元数据文件),用来定义扩展或档案打包相关数据包含了不同部分中的名/值对数据
Bytecode是字节码,里面内容是smali代码
简单使用
右键Decompile, 将 什么什么语言 转换成 java 语言
按Ctrl+b
下断点
打包签名新的APK
1、对原始的apk进行反编译:
apktool d -s -f test.apk
2、对打开生成的test目录进行修改
假如修改背景图,那么背景图.jpg 为另一张准备好的图片替换3、重新打包:
apktool b test -o newtest.apk -b 是指 build b_test 是刚才反编译出的文件所在的目录 -o 用于指定新的文件名称,这里指定为「newtest.apk」
4、得到新的 apk 文件
注意:但此时的 apk 文件是不能安装的,还需要对其进行签名。
5、对新的 Apk 进行签名
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore testjks -storepass password newtest.apk aliasName
签名文件是我自己生成的,没有办法使用 Apk 原来的签名进行签名。
6、成功
评论区