参考: https://frida.re/docs/
frida可以监控某个进程,修改进程的入口, 修改执行的内容. 特别强大
在反编译的过程中会被使用.
例子不说了.
不过在我的本机上, 运行前面的单机例子没问题, 运行 Android的例子就不行了.
安装 : 要使用pip3 来安装
PC端:
$ pip3 install frida-tools (需要先安装好python 3 )
C:\Users\luelue>pip3 install frida-tools Collecting frida-tools Downloading frida-tools-10.4.1.tar.gz (43 kB) |████████████████████████████████| 43 kB 212 kB/s Collecting colorama<1.0.0,>=0.2.7 Downloading colorama-0.4.4-py2.py3-none-any.whl (16 kB) Collecting frida<16.0.0,>=15.0.0 Downloading frida-15.1.8.tar.gz (9.1 kB) Collecting prompt-toolkit<4.0.0,>=2.0.0 Downloading prompt_toolkit-3.0.21-py3-none-any.whl (374 kB) |████████████████████████████████| 374 kB 312 kB/s Collecting pygments<3.0.0,>=2.0.2 Downloading Pygments-2.10.0-py3-none-any.whl (1.0 MB) |████████████████████████████████| 1.0 MB 467 kB/s Requirement already satisfied: setuptools in c:\users\luelue\appdata\local\programs\python\python39\lib\site-packages (from frida<16.0.0,>=15.0.0->frida-tools) (49.2.1) Collecting wcwidth Downloading wcwidth-0.2.5-py2.py3-none-any.whl (30 kB) Using legacy 'setup.py install' for frida-tools, since package 'wheel' is not installed. Using legacy 'setup.py install' for frida, since package 'wheel' is not installed. Installing collected packages: colorama, frida, wcwidth, prompt-toolkit, pygments, frida-tools Running setup.py install for frida ... done Running setup.py install for frida-tools ... done Successfully installed colorama-0.4.4 frida-15.1.8 frida-tools-10.4.1 prompt-toolkit-3.0.21 pygments-2.10.0 wcwidth-0.2.5
然后下载 frida-server: (注意,这个frida-server是安装到安卓端的,并且需要跟 PC端的frida的版本相对应)
https://github.com/frida/frida/releases/download/15.1.8/frida-core-devkit-15.1.8-android-arm64.tar.xz
下载后解压缩, 然后
$ 解压缩,把里面的文件 拿出来,例如叫 frida-server-android
$ unxz frida-server ..xz
$ adb push frida-server-android /data/local/tmp/
$ adb root (这里见我另外一篇文章 挨着本文)
$ cd /data/local/tmp
merlin:/data/local/tmp # su root (这一步特别关键! 否则会server 启动失败)
merlin:/data/local/tmp # chmod 755 frida-server-14.2.13-android-arm64
merlin:/data/local/tmp # ./frida-server-14.2.13-android-arm64 -v (建议首次运行时,一定要输入 -v , verbose 的意思)
总之就是执行上面的文件.
然后在PC端 直接 :
$ frida-ps -U 就可以看到结果
问题3. 如果frida-ps -U 不好用的话,就参考这里:https://github.com/frida/frida/issues/582
1. 在server端(android端),运行时,每次都要 su root 再运行
2. 在server端,ifconfig, 查看当前 android的ip, 然后 ./frida-server-15.1.8-android-arm64 -l 192.168.0.101 -v
3. 保证 client(windows/linux) 跟android在同一个局域网内. 然后 frida-ps --host 192.168.0.101
就可以了。
问题1: 提示: Failed to enumerate processes: unable to connect to remote frida-server: Unexpected lack of content trying to read a line
参考:https://stackoverflow.com/questions/62171745/frida-server-unable-to-connect/66652303#66652303
或者参考: https://github.com/frida/frida/issues/764
解决办法: 执行 frida-server 之前,务必 # su root , (你可以先试着ifconfig , 看看是否有权限,不要相信你安装的adb root )
问题2 unable to access zygote64 while preparing for app launch; try disabling Magisk Hide in case it is active
参考: https://stackoverflow.com/questions/56316329/frida-failed-to-spawn-unable-to-access-zygote64-while-preparing-for-app-launc
1. magisk -> settings -> Magisk -> MagiskHide , 要关掉. 否则会引起:
2. 无论你是否在magisk 中安装了 magisk adb root, 在进入到adb shell 之后, 执行 frida-server之前,都需要手动切换成root: $ su root
之后再执行 frida-server -v
在我的机器上, frida-ps -U的结果如下:
$ frida-ps -U PID Name ----- --------------------------------------------------- 14312 adbd 412 aee_aed 413 aee_aed64 414 aee_aedv 415 aee_aedv64 9175 android.ext.services 8444 [email protected] 766 [email protected] 576 [email protected] 577 [email protected] 578 [email protected] 579 [email protected] 580 [email protected] 581 [email protected] 582 [email protected] 583 [email protected] .... 还有好多
使用: 绕过android https ( ssl 的验证)
假设,我们通过安卓逆向, 获得了目标app 的源代码, 对应校验证书的代码为:
package com.<target>.utilslibrary.retrofit; import android.content.Context; import java.io.BufferedInputStream; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import okhttp3.at; public class a { public static void a(Context paramContext, at paramat) { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); BufferedInputStream bufferedInputStream = new BufferedInputStream(paramContext.getAssets().open("certs/cert.crt")); Certificate certificate = certificateFactory.generateCertificate(bufferedInputStream); bufferedInputStream.close(); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("ca", certificate); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); SSLContext sSLContext = SSLContext.getInstance("TLS"); sSLContext.init(null, trustManagerFactory.getTrustManagers(), null); paramat.a(sSLContext.getSocketFactory(), new b(certificate)); } }
创建一个脚本
import frida, sys, time # 该方法仅仅用于调试 def on_message(message, data): print("=== in on_message") print(message) print(data) # 这段是核心代码,多行javascript. jscode = """ Java.perform(function () { // 这里用的是class 的全名(package + class) var target_class = Java.use('com.target.utilslibrary.retrofit.a'); // 这里的 target_class.a 就是我们需要绕过的方法 var the_method = target_class.a; // 这里是对方法进行实现 the_method.implementation = function (p1, p2) { // 该方法的实现中,没有任何内容.也就是说, 不做任何SSL证书的校验 }; }); """ device = frida.get_usb_device() # 根据android package名字来唤醒对应的app pid = device.spawn(["com.target.wallets"]) // 修改成你的目标app package device.resume(pid) # 进程停止1秒钟.让该APP启动 time.sleep(1) script = device.attach(pid).create_script(jscode) script.on('message', on_message) print('==== script start ...') script.load() sys.stdin.read()