Frida
进程与端口:
- 默认端口:27042(Frida Server 通信端口),可能被修改为其他端口(如6666、9999)。
- 进程名:
- 典型进程:frida-server、frida-helper(Android)、frida-agent(嵌入式模式)。
- 可能伪装为普通进程名(如 com.android.settings)。
 
- 典型进程:
文件痕迹:
- 二进制文件:
- 常见路径:/data/local/tmp/frida-server、/data/local/tmp/re.frida.server。
- 嵌入式模式:应用内集成 frida-gadget.so(路径如/data/app/<包名>/lib/arm64/libfrida-gadget.so)。
 
- 常见路径:
- 动态库:
- 加载 libfrida.so、libfrida-gumjs.so或libagent.so。
- 可能被重命名(如 libhello.so)以绕过静态检测。
 
- 加载 
行为特征:
- 代码注入:
- 使用 ptrace或LD_PRELOAD注入代码,劫持关键函数(如open、fopen)。
- 修改内存页权限(mprotect或mmap)以动态执行代码。
 
- 使用 
- 内存特征:
- 内存中存在字符串 frida-gadget、frida:rpc、gum-js-loop、FridaScriptEngine。
- 函数指针表(如 GOT/PLT)被篡改,指向 Frida 的代理代码。
 
- 内存中存在字符串 
- Hook 检测:
- 函数完整性校验:
- 检查关键函数(如 ptrace、open)的前几条指令是否被修改(如JMP指令)。
- 对比函数代码的哈希值(如 .text段的 SHA256)与预期是否一致。
 
- 检查关键函数(如 
- 内存映射异常:
- 检测内存中是否存在可写且可执行的页(rwx权限),常见于 Frida 的代码注入。
 
- 检测内存中是否存在可写且可执行的页(
- Inline Hook 检测:
- 扫描内存中 FAR JUMP(远跳转指令)或trampoline代码片段。
 
- 扫描内存中 
 
- 函数完整性校验:
检测方法:
- 
静态检测: - 扫描 APK 或二进制文件中的 frida相关字符串、库文件或端口配置。
- 检查 AndroidManifest.xml中是否声明可疑权限(如ptrace、注入)。
 
- 扫描 APK 或二进制文件中的 
- 
动态检测: - 进程与线程扫描:
- 遍历 /proc/<pid>/cmdline和/proc/<pid>/status,查找frida相关进程或线程名。
- 检测异常线程(如 pool-frida、gmain)。
 
- 遍历 
- 内存映射分析:
- 检查 /proc/self/maps或/proc/<pid>/maps中是否存在frida、gadget或匿名可执行内存段。
 
- 检查 
- 主动探测:
- 尝试连接默认端口(127.0.0.1:27042),若返回{"type":"error"}则可能存在 Frida。
- 调用 frida_get_uid()或frida_enumerate_devices()等未公开函数,若未崩溃则可能未注入。
 
- 尝试连接默认端口(
 
- 进程与线程扫描:
- 
Hook 防御: - 反 Hook 技术:
- 使用 syscall直接调用系统函数(绕过libc的 Hook)。
- 在敏感函数入口插入 SIGTRAP或INT3指令,触发断点异常。
 
- 使用 
- 完整性校验:
- 使用 dl_iterate_phdr()遍历已加载模块,检查是否有未签名的库(如libfrida)。
- 实时校验关键函数代码(如 memcmp对比.text段内容)。
 
- 使用 
 
- 反 Hook 技术:
- 
对抗隐藏技术: - 检测重命名进程:
- 监控进程的父进程和子进程关系(Frida 可能由 adb或shell启动)。
 
- 监控进程的父进程和子进程关系(Frida 可能由 
- 检测端口复用:
- 使用 netstat或/proc/net/tcp分析本地端口通信模式(Frida 通信流量有固定特征)。
 
- 使用 
 
- 检测重命名进程:
Root
- 核心用途:获取 Android 系统的最高权限(root)。
- 特征:
- 文件系统痕迹:
- 存在 su二进制文件(路径如/system/bin/su,/system/xbin/su)。
- Root 管理应用(如 SuperSU、Magisk 等)的安装痕迹。
 
- 存在 
- 系统属性:
- ro.build.tags可能包含- test-keys(非官方系统签名)。
- ro.debuggable=1(系统允许调试)。
 
- 行为特征:
- /system分区被挂载为可写(正常应为只读)。
- SELinux 状态为 Permissive或关闭。
 
- 检测方法:
- 检查 su命令是否存在或尝试执行su -v。
- 验证系统分区的哈希或只读属性(如 mount | grep /system)。
- 使用 SafetyNet API(已废弃)或Play Integrity API(Google 官方检测)。
 
- 检查 
 
- 文件系统痕迹:
Xposed 框架
- 核心用途:通过加载模块在系统层面 Hook 应用和系统方法。
- 特征:
- 文件痕迹:
- 安装 Xposed 管理应用(如 Xposed Installer)。
- 存在 Xposed 库文件(如 libxposed_art.so)。
 
- 安装 Xposed 管理应用(如 
- 运行时特征:
- 应用进程加载 Xposed 模块(如 XposedBridge.jar)。
- 系统类(如 java.lang.ClassLoader)被修改。
 
- 应用进程加载 Xposed 模块(如 
- 检测方法:
- 检查 XposedHelper类或de.robv.android.xposed.XposedBridge是否存在。
- 遍历已安装应用列表,寻找 Xposed 模块包名(如 de.robv.android.xposed.installer)。
- 监控方法调用栈中是否包含 Xposed 相关调用(如 XposedBridge.handleHookedMethod)。
 
- 检查 
 
- 文件痕迹:
8poll
应用模拟器 root 环境下会跳出 toast 警告并自动退出

尝试 hook toast
包名 com.miniclip.eightballpool
Java.perform(function() {
    var Toast = Java.use("android.widget.Toast");
 
    Toast.makeText.overload('android.content.Context', 'java.lang.CharSequence', 'int').implementation = function(context: any, text: any, duration: any) {
        console.log("[!] Toast.makeText called with text: " + text);
 
        var stackTrace = Java.use("java.lang.Exception").$new().getStackTrace();
        for (var i = 0; i < stackTrace.length; i++) {
            console.log("Stack Trace: " + stackTrace[i].toString());
        }
 
        return this.makeText(context, text, duration);
    };
 
    Toast.show.implementation = function() {
        console.log("[!] Toast.show called");
 
        var stackTrace = Java.use("java.lang.Exception").$new().getStackTrace();
        for (var i = 0; i < stackTrace.length; i++) {
            console.log("Stack Trace: " + stackTrace[i].toString());
        }
 
        // 调用原始 show 方法
        return this.show();
    };
});
 从堆栈追踪来看,InjectedActivity 类中的 showToast 方法在 handleExitToast 中被调用。
因此,这个 Toast 是通过 InjectedActivity 类中的 handleExitToast 方法间接调用的。如果你想要更深入地分析 Toast 被调用的具体逻辑,应该查看 InjectedActivity 中 showToast 和 handleExitToast 方法的实现。
runtime.loading.InjectedActivity.showPopup 加载了 libloader
通过库可以跟踪到 io.adjoe.protection.DeviceUtils 调用了可疑的检测 emulator 的方法

应该是通过 org.json.JSONObject 这个 Mozilla 的库来传递设备当前的信息。然后通过读取 JSON 来判断异常情况。
可以 hook 结果看看,然后看看能不能改变值绕过去
试一下 toString() 方法:
竟然 hook 不到,我研究一下整个调用逻辑链看看,是不是我搞错了(还没到这步就挂了)