前言
在进行 Android 测试时会发现现在大多数 APP 都进行了加固,其中就包括 frida 防护。不能使用 frida,对 APP 渗透测试而言可以说是缺了灵魂。所以绕过 Frida 防护是我们必不可少的一步。
Frida 绕过的各种姿势
1. 使用去特征的 server
https://github.com/hluwa/strongR-frida-android/
2. 修改默认端口
 ./data/local/tmp/frida-* -l 0.0.0.0:800
 adb forward tcp:27042 tcp:800
 frida -R package_name -l hook.js
3. VA + Gadget
利用 VirtualApp 自带的延时注入功能,注入 frida-gadget,具体实现可看我 github。
 
github: https://github.com/jussi-sky/VirtualApp
3.1 引入 gadget.so(更改so名称,可绕过部分检测)

3.2 加载 gadget

package io.virtualapp;
import com.lody.virtual.helper.utils.VLog;
public class FridaGadget {
    private static final String TAG = FridaGadget.class.getSimpleName();
    static {
        try {
            System.loadLibrary("ijkplayer");
        } catch (Throwable e) {
            VLog.e(TAG, VLog.getStackTraceString(e));
        }
    }
    public static void init() {
        VLog.d(TAG, "Init Frida Gadget", new Object[0]);
    }
}
3.3 重写 AppComponentDelegate,控制 gadget 加载时机

package io.virtualapp;
import android.app.Application;
import android.content.Context;
import com.lody.virtual.client.VClient;
import com.lody.virtual.client.core.AppCallback;
import com.lody.virtual.helper.utils.VLog;
import com.scorpion.IHook.XposedBridge;
import com.scorpion.IHook.callbacks.XC_LoadPackage;
import com.scorpion.reverse.dingding.DingTalk;
import com.swift.sandhook.xposedcompat.utils.ProcessUtils;
public class AppComponentDelegate implements AppCallback {
    private static final String TAG = "AppComponentDelegate";
    boolean isMainProcess = false;
    public Application mApplication;
    Context mContext;
    public AppComponentDelegate(Context context) {
        this.mContext = context;
    }
    public boolean isMainProcess() {
        return this.isMainProcess;
    }
    public void setMainProcess(boolean mainProcess) {
        this.isMainProcess = mainProcess;
        boolean z = this.isMainProcess;
    }
    @Override // com.lody.virtual.client.core.AppCallback
    public void beforeStartApplication(String packageName, String processName, Context context) {
    }
    @Override // com.lody.virtual.client.core.AppCallback
    public void beforeApplicationCreate(String packageName, String processName, Application application) {
    }
    @Override // com.lody.virtual.client.core.AppCallback
    public void afterApplicationCreate(String packageName, String processName, Application application) {
        FridaGadget.init();
        
        // 多进程应用使用 processName 控制只注入主进程,否则可能会出错
        if (processName.equals("com.ford.cnevapp.debug")) {
            FridaGadget.init(); 
        }
        if (packageName.equals("com.alibaba.android.rimet")) {
            VLog.d("VA-", "开始 hook 丁丁打卡", new Object[0]);
            DingTalk.hook(VClient.get().getClassLoader());
        }
    }
    private XC_LoadPackage.LoadPackageParam getLoadPackageParam(Application application) {
        XC_LoadPackage.LoadPackageParam packageParam = new XC_LoadPackage.LoadPackageParam(XposedBridge.sLoadedPackageCallbacks);
        if (application != null) {
            if (packageParam.packageName == null) {
                packageParam.packageName = application.getPackageName();
            }
            if (packageParam.processName == null) {
                packageParam.processName = ProcessUtils.getProcessName(application);
            }
            if (packageParam.classLoader == null) {
                packageParam.classLoader = application.getClassLoader();
            }
            if (packageParam.appInfo == null) {
                packageParam.appInfo = application.getApplicationInfo();
            }
        }
        return packageParam;
    }
}
3.4 最后确认主 Activity 的 AppComponentDelegate 的是否指向的是我们重写的,如果不是删除原对应的 import

3.5 配置自定义 gadget 属性

{
  "interaction": {
    "type": "listen",
    "address": "127.0.0.1",
    "port": 26000,
    "on_port_conflict": "fail",
    "on_load": "resume"
  }
}
4. riru + gadget
利用  Magisk 的 riru 模块,在 APP Fork 时注入 frida-gadget,具体实现可看我 github。
github: https://github.com/jussi-sky/Riru-FridaGadget