frida的使用

手机:小米9,已经root,android 10
电脑:win11
软件:frida-tools==12.5.1(frida==16.7.19), frida-server==16.0.10

frida是一个用于在电脑上远程注入手机apk进程进行hook调试的软件.
有电脑端frida和手机端frida-server

一,安装frida-server到手机

frida 是一款基于 Python + JavaScript 的 Hook 与调试框架,首先电脑端使用命令 pip install frida-tools 安装 frida 模块(此命令默认会安装最新版的 frida 和 frida-tools,如),

pip install frida-tools==12.5.1

frida-tools的版本不是frida版本,为什么要指定版本,因为frida-server对机器有兼容性,经过测试frida-server16.0.10,对android 7和android 10兼容性最好, frida-tools 12.5.1里面是frida16.7.19是可以正常和frida-server16.0.10通信的.

然后下载 frida-server16.0.10,下载地址:https://github.com/frida/frida/releases

frida-server 要根据你电脑端pip安装的 frida 版本,一定要用这个命令查看才准确

#查看frida版本
frida --version

如果不知道自己手机是什么平台,通过下面adb命令查看

adb shell
#查看手机平台是arm64还是x86
getprop ro.product.cpu.abi
#查看手机大量信息
getprop | grep product

经过测试17.2.17兼容性不佳,安卓7会报错,根据issure里推荐16.0.10,发现16.0.10兼容性最好,下载frida-server-16.0.10-android-arm64.xz后
解压到d盘目录,解压得到其中的文件,将其重命名为frida-server(重命名只是用于方便后续使用)

将下载好的 frida-server 使用 adb push 命令传到手机的 /data/local/tmp/ 目录下,并给予 777 读、写、执行的权限,然后直接运行 frida-server,正常不会有任何输出,当然也可以使用 & 等方式让其在后台运行。

如果默认的27042被占用,或者为了防止被识别,我们可以用-l命令修改监听端口为其他端口如27052

cmd命令如下
(如果没有安装adb ,请自行下载platform-tools,里面有adb)
复制文件到手机

d:
adb push frida-server /data/local/tmp/

启动server

adb shell
su
cd /data/local/tmp/
chmod 777 frida-server
ls -l
./frida-server

成功启动图片如下


成功启动

如果出现的错误,附解决办法(全部实践解决)

错误一:

Unable to load SELinux policy from the kernel: Failed to open file ?/sys/fs/selinux/policy?: Permission denied

解决:手机需要先root,并且进adb shell 后先输入su启用超级用户root权限

错误二:

Unable to start: Error binding to address 0.0.0.0:27042: Address already in use

解决:
进adb shell,
用ps -e | grep frida-server
查看已启动的frida-server进程
kill 进程id结束


image.png

错误三:
python安装的frida版本和 手机上frida-server版本不一致也会报错:电脑上运行frida时,提示未找到frida-server
解决:用相同版本

错误四:

unable to stat file for the executable "/memfd:frida-helper-32 (deleted)": No such file or director

这个是frida-server版本和这个版本的安卓系统不兼容,我用17.2.17安装在andriod7的老手机都提示这个错误,
结局:根据issure里面找到,用16.0.10版本就行, 于是下载frida-server-16.0.10-android-arm64,果然解决了

二,电脑启动frida

设置frida端口转发监听(新开cmd窗口)
27042,27043端口用于frida-server通信的默认端口号,主要用于客户端连接服务端。

adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043

遍历手机进程,这一步就能判断是否和手机的frida server通信成功

frida-ps -U

如果提示错误
Failed to enumerate processes: unable to find process with name 'system_server'
那就是手机被root或者frida电脑版本和手机版本不对应

下面就是双端frida安装并通信成功的


image.png

记住这里的进程名,后续会用到,这里三方应用一般是中文名,系统服务是英文,是app自己设置的,不同于我们一直使用的包名。

三,逆向实践

首先把apk下载到d盘根目录,通过adb安装apk到手机,

adb install momo3.2.apk
image.png

安装后手机打开app试试会不会闪退,不会闪退才可以正常脱.

接着,查看手机安装的所有包名

adb shell pm list packages

找到一个com.maimemo.android.momo就是我们今天要实践的对象,

这次我们时间脱x60的壳,利用frida-dexdump,自动化脱壳,

正式脱壳前确保已经adb shell连上手机,并且手机已经启动frida-server监听

方法一:

我们直接用frida-dexdump来脱,新开一个cmd,安装frida-dexdump

pip install frida-dexdump

进行脱壳,-f是重新启动这个包进行注入脱壳

frida-dexdump -U -f com.maimemo.android.momo
image.png

d盘目录就出现一个包名,里面有脱好的dex文件


image.png

这些文件就可以用jadx直接打开,里面就有代码.肯定体积最大的那个就是我们要找的主文件
打开发现出错


image.png

image.png

不用着急,dex是需要修复的,接下来拿出我们的反编译神器,MT管理器,里面有个dex修复功能(需要开通会员),
去mt官网下载,https://mt2.cn/download/,然后安装到手机

adb install mt2.19.apk

把所有dex文件全部打包成dex3.2.zip,传到手机里

adb push dex3.2.zip /data/local/tmp/

手机里打开mt,进入/data/local/tmp/,解压zip,全选所有dex文件,
点dex文件,选dex修复


4267f0c8dcbe340b8f57cea292e2bce.jpg

b262c9b20a4629aab89a6f57200594b.jpg

可能会提出有的文件修复出错,没关系,只要我们最大的dex文件修复成功就行了

修复后压缩为dex3.2ok.zip
电脑上用adb pull命令传出来,解压后,打开jadx,全部拖到jadx窗口中,这样就成功了

adb pull /data/local/tmp/dex3.2ok.zip
image.png

至此,脱壳完成,可以欣赏他的源码了

~
`
~
~
~
~
~

~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~

=================以下内容可不看我没有进行实践操作========

方法二(历史久远,自定义强,需要大神写好js):

https://github.com/GuoQiang1993/Frida-Apk-Unpack

我们把dexDump.js下到d盘根目录,
我们可以把需要执行的js写到一个js文件,然后通过frida执行
命令行执行:

frida -U -f com.maimemo.android.momo -l dexDump.js

pip install frida-dexdump
frida-dexdump -U -f com.maimemo.android.momo

扩展:frida语法学习

加载脚本有两种方式,
一种Attach模式,是直接进程存在的情况,frida注入.
这种情况使用进程名,一般是中文

frida -U -n 抖音 test.js

一种 Spawn模式,是不管进程在不在,都由frida重新启动app掌握控制权并注入。
这种情况下,需要用-f参数,并使用包名

frida -U -f com.ss.android.ugc.aweme test.js

基础使用

1、在Java环境中运行

Java.perform(function () {

}

2、Hook Class

const TargetClass = Java.use('com.example.app.MainActivity');
TargetClass.login.implementation = function (username, password) {
    console.log(`用户名: ${username}, 密码: ${password}`);
    return this.login(username, password); // 继续原逻辑
};

3、打印堆栈

console.log(Java.use("android.util.Log").getStackTraceString(
    Java.use("java.lang.Exception").$new()
));

4、构造函数

Java.use("classname").$init(params)

5、内部类

Java.use("classname$innerclassname")

6、取变量里面的值

obj.name.value

其中name是变量名,后面需要跟一个value,才能拿到实际的值
7、枚举某个类的实例

Java.choose(className, callbacks)

例如我们想拿到Activity的实例,做一些事情,就可以用这个方式来做。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容