首页
社区
课程
招聘
[原创]Overt安全风控检测工具深度解析
发表于: 2025-8-2 01:01 6745

[原创]Overt安全风控检测工具深度解析

2025-8-2 01:01
6745

在移动互联网时代,设备安全检测是风控体系中的重要一环。掌握前沿风控技术是每个安全人员的重要的必修课程之一。Overt 项目致力于收集并集成当前公开的检测技术于一身,构建了一个全面、高效、安全的Android设备安全检测体系。

本文将从技术原理、架构设计、模块实现等多个维度,深入解析Overt项目的核心技术和实现细节,为安全从业者提供一份全面的技术参考。通过详细分析JVM获取、ClassLoader遍历、Linker解析、SSL证书验证、TEE检测等关键技术难点,帮助读者理解当前的Android设备安全检测技术,所以赶快来领取顶级攻防游戏的入场券吧。

Overt采用分层架构设计,确保核心检测逻辑的安全性和性能:

Root检测是Android设备安全检测的核心环节,通过检测系统中是否存在Root权限获取工具来判断设备是否已被Root。传统的Root检测往往容易被绕过,因此需要采用更底层、更隐蔽的检测方式。

1.1 自定义Syscall实现

1.2 自定义文件操作实现

1.3 Root文件检测实现

技术优势:

技术难点解析:

在Android Native库的__attribute__((constructor))初始化阶段,Java层尚未完全启动,此时获取JVM实例和Context对象面临巨大挑战。

2.1 JVM获取机制

2.2 跨线程JNI环境管理

关键技术点:

2.3 Context创建机制

技术难点解析:

Android的ClassLoader体系复杂,包括BootClassLoader、PathClassLoader、DexClassLoader等,需要深度遍历所有ClassLoader来检测异常类加载。

3.1 标准API遍历方式

3.2 ART内部API遍历方式

技术难点解析:

Android的动态链接器(linker)管理所有加载的共享库,通过遍历linker内部数据结构可以检测异常库加载和Hook行为。

4.1 Linker内部结构解析

4.2 库遍历机制

4.3 库完整性校验

技术难点解析:

SSL证书检测是验证网络通信安全性的重要手段,本项目通过 mbedtls 库实现完整的TLS握手和证书验证流程。

5.1 自定义HTTPS客户端

5.2 证书指纹验证

5.3 mbedtls静态库编译

技术难点解析:

TEE(Trusted Execution Environment)是Android设备的重要安全特性,它提供了一个与主操作系统隔离的安全执行环境。TEE检测能够从硬件层面验证设备的安全状态,通过解析Android KeyStore Attestation证书来获取设备的可信启动状态、安全级别等关键信息。

TEE检测基于Android KeyStore的Attestation功能,通过生成的密钥对,获取包含设备安全状态的证书链,然后使用纯C++实现解析证书中的TEE扩展信息,避免依赖Java三方库,提高安全性和性能。

6.1 获取TEE证书(JNI桥接)

6.2 C++ ASN.1解析器实现

6.3 TEE扩展解析

6.4 RootOfTrust信息解析

6.5 主解析函数

技术优势:

技术难点解析:

ASN.1复杂性:需要实现ASN.1 DER编码解析,包括标签、长度、值的解析

证书结构:理解X.509证书和TEE扩展的复杂结构,包括TBSCertificate、扩展序列等

OID匹配:正确解析和匹配TEE attestation扩展OID(1.3.6.1.4.1.11129.2.1.17)

Keymaster标签:理解Keymaster标签格式,正确解析RootOfTrust序列

内存安全:确保ASN.1解析过程中的边界检查,防止缓冲区溢出

Overt采用线程池机制实现异步任务调度,支持CPU核心绑定、优先级提升和智能任务管理。通过zThreadPool实现所有检测任务的并发执行,提高检测效率。

7.1 线程池初始化

7.2 CPU核心绑定与优先级提升

7.3 周期性任务管理

技术优势:

技术难点解析:

为了实现更高的防护能力,Overt 自实现了非标准的 string、vector、map 等基础 api,并通过config.h中的宏替换机制实现了标准API与非标API之间的无缝切换,这是一种编译时切换策略。

8.1 宏控制机制

8.2 宏映射机制

8.3 自定义API实现特点

技术优势:

技术难点解析:

侧信道检测通过比较不同系统调用的执行时间来判断是否存在调试工具或Hook框架。当系统被Hook时,系统调用的执行时间会显著增加。

实现原理:

检测应用签名信息,验证应用是否被重新签名或篡改。

检测Frida等调试工具注入的进程,分析进程状态和内存映射。

检测调试工具常用的端口监听,如Frida默认端口27042。

检测系统时间篡改、启动时间异常等。

检测系统日志中的可疑记录,如Zygisk痕迹。

扫描本地网络中的设备,检测同一网络中的其他Overt设备。

其实是否选择开源还是纠结了挺长时间的,因为最开始是打算开源的,但写着写着就突然理解了为什么例如 NativeTest、hunter、momo 等检测项目为什么选择闭源,确实倾注了很多心血。每一个技术细节的打磨,每一次检测逻辑的优化,从单一功能到完整的检测体系,每一个功能都来之不易。希望本项目能为其它同学提供有价值的技术参考,无论选择开源还是闭源,最重要的是保持对技术的热爱和对安全的执着,这才是行业发展的真正动力。

1bfK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6D9P5s2A6Q4x3X3c8B7K9h3q4F1k6r3q4F1i4K6u0r3e0%4k6W2M7Y4b7`.

[原创]自动化采集Android系统级设备指纹对抗&如何四两拨千斤?

[原创]Android风控详细解读以及对照工具

[原创]KernelSU检测之“时间侧信道攻击”

珍惜 hunter

472K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6y4j5X3g2V1i4K6u0V1g2p5I4e0i4K6u0r3L8h3u0W2k6s2c8D9M7H3`.`.

017K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6$3N6X3t1J5x3o6j5H3i4K6u0r3d9$3g2&6b7i4c8@1k6i4y4@1j5i4c8A6L8$3^5`.

444K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6$3N6X3t1J5x3o6j5H3i4K6u0r3h3s2m8G2M7$3g2V1c8r3g2@1k6h3y4@1L8%4t1`.

012K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6T1P5i4S2A6j5h3!0J5N6h3&6Q4x3V1k6d9N6i4u0#2

5adK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6S2j5K6y4K6M7K6m8J5i4K6u0r3L8$3u0X3N6i4y4Z5k6h3q4V1k6i4u0Q4x3X3g2Z5

┌─────────────────────────────────────┐
│            Java层 (UI层)             │
│  ├── MainActivity                   │
│  │  └── onCardInfoUpdated (静态回调) │
│  ├── InfoCardContainer              │
│  ├── InfoCard                       │
│  └── MainApplication                │
│     └── System.loadLibrary("overt")  │
├─────────────────────────────────────┤
│            JNI桥接层                 │
│  ├── native-lib.cpp                 │
│  │  ├── init_ (constructor)         │
│  │  └── JNI_OnLoad                  │
│  └── zManager (设备信息管理中心)      │
│     ├── round_tasks (周期性任务)     │
│     └── notice_java (通知Java层)     │
├─────────────────────────────────────┤
│          Native C++层               │
│  ├── 检测模块 (z*Info.cpp)           │
│  │  ├── zRootStateInfo              │
│  │  ├── zTeeInfo                     │
│  │  ├── zClassLoaderInfo             │
│  │  ├── zLinkerInfo                  │
│  │  ├── zPackageInfo                 │
│  │  ├── zSystemSettingInfo            │
│  │  ├── zSystemPropInfo              │
│  │  ├── zSignatureInfo               │
│  │  ├── zPortInfo                    │
│  │  ├── zTimeInfo                    │
│  │  ├── zSslInfo                     │
│  │  ├── zLocalNetworkInfo            │
│  │  ├── zLogcatInfo                  │
│  │  ├── zSideChannelInfo             │
│  │  └── zProcInfo                    │
│  ├── 核心工具类 (zcore模块)          │
│  │  ├── zJavaVm (JVM管理)            │
│  │  │  └── getEnv (跨线程JNI环境)    │
│  │  ├── zLinker (动态链接器)         │
│  │  │  ├── find_lib                  │
│  │  │  ├── get_libpath_list           │
│  │  │  └── check_lib_crc             │
│  │  ├── zClassLoader (类加载器)       │
│  │  │  ├── traverseClassLoader        │
│  │  │  ├── checkGlobalRef             │
│  │  │  └── checkWeakGlobalRef         │
│  │  ├── zHttps (HTTPS客户端)          │
│  │  │  ├── performRequest              │
│  │  │  └── verifyCertificatePinning    │
│  │  ├── zTee (TEE检测)               │
│  │  │  └── parse_tee_certificate      │
│  │  ├── zFile (文件操作)              │
│  │  ├── zElf (ELF解析)               │
│  │  ├── zJson (JSON处理)             │
│  │  ├── zCrc32 (CRC校验)             │
│  │  ├── zThreadPool (线程池)         │
│  │  └── zLog (日志记录)               │
│  └── 基础库层 (zlibc/zstd模块)       │
│     ├── syscall.h (自定义系统调用)    │
│     ├── zLibc (自定义libc函数)        │
│     ├── zStdString (自定义string)     │
│     ├── zStdVector (自定义vector)     │
│     └── zStdMap (自定义map)           │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│            Java层 (UI层)             │
│  ├── MainActivity                   │
│  │  └── onCardInfoUpdated (静态回调) │
│  ├── InfoCardContainer              │
│  ├── InfoCard                       │
│  └── MainApplication                │
│     └── System.loadLibrary("overt")  │
├─────────────────────────────────────┤
│            JNI桥接层                 │
│  ├── native-lib.cpp                 │
│  │  ├── init_ (constructor)         │
│  │  └── JNI_OnLoad                  │
│  └── zManager (设备信息管理中心)      │
│     ├── round_tasks (周期性任务)     │
│     └── notice_java (通知Java层)     │
├─────────────────────────────────────┤
│          Native C++层               │
│  ├── 检测模块 (z*Info.cpp)           │
│  │  ├── zRootStateInfo              │
│  │  ├── zTeeInfo                     │
│  │  ├── zClassLoaderInfo             │
│  │  ├── zLinkerInfo                  │
│  │  ├── zPackageInfo                 │
│  │  ├── zSystemSettingInfo            │
│  │  ├── zSystemPropInfo              │
│  │  ├── zSignatureInfo               │
│  │  ├── zPortInfo                    │
│  │  ├── zTimeInfo                    │
│  │  ├── zSslInfo                     │
│  │  ├── zLocalNetworkInfo            │
│  │  ├── zLogcatInfo                  │
│  │  ├── zSideChannelInfo             │
│  │  └── zProcInfo                    │
│  ├── 核心工具类 (zcore模块)          │
│  │  ├── zJavaVm (JVM管理)            │
│  │  │  └── getEnv (跨线程JNI环境)    │
│  │  ├── zLinker (动态链接器)         │
│  │  │  ├── find_lib                  │
│  │  │  ├── get_libpath_list           │
│  │  │  └── check_lib_crc             │
│  │  ├── zClassLoader (类加载器)       │
│  │  │  ├── traverseClassLoader        │
│  │  │  ├── checkGlobalRef             │
│  │  │  └── checkWeakGlobalRef         │
│  │  ├── zHttps (HTTPS客户端)          │
│  │  │  ├── performRequest              │
│  │  │  └── verifyCertificatePinning    │
│  │  ├── zTee (TEE检测)               │
│  │  │  └── parse_tee_certificate      │
│  │  ├── zFile (文件操作)              │
│  │  ├── zElf (ELF解析)               │
│  │  ├── zJson (JSON处理)             │
│  │  ├── zCrc32 (CRC校验)             │
│  │  ├── zThreadPool (线程池)         │
│  │  └── zLog (日志记录)               │
│  └── 基础库层 (zlibc/zstd模块)       │
│     ├── syscall.h (自定义系统调用)    │
│     ├── zLibc (自定义libc函数)        │
│     ├── zStdString (自定义string)     │
│     ├── zStdVector (自定义vector)     │
│     └── zStdMap (自定义map)           │
└─────────────────────────────────────┘
// syscall.h - 自定义系统调用封装
#define __asm_syscall(...) \
    __asm__ __volatile__("svc #0" \
        : "=r"(x0) : __VA_ARGS__ : "memory", "cc")
 
// ARM64系统调用内联函数
__attribute__((always_inline))
static inline long __syscall4(long n, long a, long b, long c, long d) {
    register long x8 __asm__("x8") = n;
    register long x0 __asm__("x0") = a;
    register long x1 __asm__("x1") = b;
    register long x2 __asm__("x2") = c;
    register long x3 __asm__("x3") = d;
    __asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3));
    return x0;
}
 
// 系统调用号定义 (Linux ARM64)
#define SYS_openat      56
#define SYS_stat        4
#define SYS_access      21
#define SYS_readlink    89
#define SYS_newfstatat  79
// syscall.h - 自定义系统调用封装
#define __asm_syscall(...) \
    __asm__ __volatile__("svc #0" \
        : "=r"(x0) : __VA_ARGS__ : "memory", "cc")
 
// ARM64系统调用内联函数
__attribute__((always_inline))
static inline long __syscall4(long n, long a, long b, long c, long d) {
    register long x8 __asm__("x8") = n;
    register long x0 __asm__("x0") = a;
    register long x1 __asm__("x1") = b;
    register long x2 __asm__("x2") = c;
    register long x3 __asm__("x3") = d;
    __asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3));
    return x0;
}
 
// 系统调用号定义 (Linux ARM64)
#define SYS_openat      56
#define SYS_stat        4
#define SYS_access      21
#define SYS_readlink    89
#define SYS_newfstatat  79
// nonstd_libc.cpp - 自定义文件操作函数
int nonstd_open(const char *pathname, int flags, ...) {
    LOGE("nonstd_open called: pathname='%s', flags=0x%x", pathname ? pathname : "NULL", flags);
     
    if (!pathname) {
        LOGV("open: NULL pathname");
        return -1;
    }
     
    mode_t mode = 0;
    if (flags & O_CREAT) {
        va_list args;
        va_start(args, flags);
        mode = va_arg(args, mode_t);
        va_end(args);
    }
     
    // 使用 openat 系统调用,AT_FDCWD 表示相对于当前工作目录
    int fd = (int)__syscall4(SYS_openat, AT_FDCWD, (long)pathname, flags, mode);
    LOGV("open: returned fd=%d", fd);
    return fd;
}
 
 
int nonstd_access(const char* __path, int __mode) {
    LOGV("nonstd_access called: path='%s', mode=0x%x", __path ? __path : "NULL", __mode);
 
    if (!__path) {
        LOGV("access: NULL path");
        errno = EFAULT;  // 错误地址
        return -1;
    }
 
    long result = __syscall2(SYS_access, (uintptr_t)__path, (long)__mode);
 
    if (result < 0) {
        errno = -result;
        LOGV("access: failed, errno=%d", errno);
        return -1;
    }
 
    LOGV("access: success");
    return 0;
}
// nonstd_libc.cpp - 自定义文件操作函数
int nonstd_open(const char *pathname, int flags, ...) {
    LOGE("nonstd_open called: pathname='%s', flags=0x%x", pathname ? pathname : "NULL", flags);
     
    if (!pathname) {
        LOGV("open: NULL pathname");
        return -1;
    }
     
    mode_t mode = 0;
    if (flags & O_CREAT) {
        va_list args;
        va_start(args, flags);
        mode = va_arg(args, mode_t);
        va_end(args);
    }
     
    // 使用 openat 系统调用,AT_FDCWD 表示相对于当前工作目录
    int fd = (int)__syscall4(SYS_openat, AT_FDCWD, (long)pathname, flags, mode);
    LOGV("open: returned fd=%d", fd);
    return fd;
}
 
 
int nonstd_access(const char* __path, int __mode) {
    LOGV("nonstd_access called: path='%s', mode=0x%x", __path ? __path : "NULL", __mode);
 
    if (!__path) {
        LOGV("access: NULL path");
        errno = EFAULT;  // 错误地址
        return -1;
    }
 
    long result = __syscall2(SYS_access, (uintptr_t)__path, (long)__mode);
 
    if (result < 0) {
        errno = -result;
        LOGV("access: failed, errno=%d", errno);
        return -1;
    }
 
    LOGV("access: success");
    return 0;
}
// zRootStateInfo.cpp - Root文件检测
map<string, map<string, string>> get_root_state_info(){
    LOGD("get_root_file_info called");
    map<string, map<string, string>> info;
 
    // 定义需要检测的Root相关文件路径列表
    const char* paths[] = {
            "/sbin/su",                    // SuperSU
            "/system/bin/su",              // 系统su
            "/system/xbin/su",             // 系统xbin su
            "/data/local/xbin/su",         // 用户空间su
            "/data/local/bin/su",          // 用户空间bin su
            "/system/sd/xbin/su",          // SD卡su
            "/system/bin/failsafe/su",     // 安全模式su
            "/data/local/su",              // 数据分区su
            "/system/xbin/mu",            // Magisk su
            "/system_ext/bin/su",          // 系统扩展su
            "/apex/com.android.runtime/bin/suu", // APEX su
    };
 
    // 遍历检测每个路径
    for (const char* path : paths) {
        LOGI("Checking path: %s", path);
        zFile file(path);
         
        // 检查文件是否存在
        if(file.exists()){
            LOGI("Black file exists: %s", path);
            // 标记为错误级别,说明检测到Root相关文件
            info[path]["risk"] = "error";
            info[path]["explain"] = "black file but exist";
        }
    }
 
    return info;
}
// zRootStateInfo.cpp - Root文件检测
map<string, map<string, string>> get_root_state_info(){
    LOGD("get_root_file_info called");
    map<string, map<string, string>> info;
 
    // 定义需要检测的Root相关文件路径列表
    const char* paths[] = {
            "/sbin/su",                    // SuperSU
            "/system/bin/su",              // 系统su
            "/system/xbin/su",             // 系统xbin su
            "/data/local/xbin/su",         // 用户空间su
            "/data/local/bin/su",          // 用户空间bin su
            "/system/sd/xbin/su",          // SD卡su
            "/system/bin/failsafe/su",     // 安全模式su
            "/data/local/su",              // 数据分区su
            "/system/xbin/mu",            // Magisk su
            "/system_ext/bin/su",          // 系统扩展su
            "/apex/com.android.runtime/bin/suu", // APEX su
    };
 
    // 遍历检测每个路径
    for (const char* path : paths) {
        LOGI("Checking path: %s", path);
        zFile file(path);
         
        // 检查文件是否存在
        if(file.exists()){
            LOGI("Black file exists: %s", path);
            // 标记为错误级别,说明检测到Root相关文件
            info[path]["risk"] = "error";
            info[path]["explain"] = "black file but exist";
        }
    }
 
    return info;
}
// zJavaVm.cpp - JVM获取实现
zJavaVm::zJavaVm() {
    LOGD("Constructor called");
 
    // 通过链接器查找libart.so库
    zElf libart = zLinker::getInstance()->find_lib("libart.so");
 
    // 从libart.so中获取JNI_GetCreatedJavaVMs函数指针
    auto *JNI_GetCreatedJavaVMs  = (jint (*)(JavaVM **, jsize, jsize *))libart.find_symbol("JNI_GetCreatedJavaVMs");
    LOGI("JNI_GetCreatedJavaVMs: %p", JNI_GetCreatedJavaVMs);
    if (JNI_GetCreatedJavaVMs == nullptr) {
        LOGE("GetCreatedJavaVMs not found");
        return;
    }
 
    // 获取已创建的Java虚拟机实例
    JavaVM* vms[10];
    jsize num_vms = 0;
    if (JNI_GetCreatedJavaVMs(vms, 1, &num_vms) != JNI_OK || num_vms == 0) {
        LOGE("GetCreatedJavaVMs failed");
        return;
    }
    LOGI("GetCreatedJavaVMs num_vms %d", num_vms);
 
    // 保存JVM实例指针
    jvm = vms[0];
    LOGI("JVM initialized successfully");
}
// zJavaVm.cpp - JVM获取实现
zJavaVm::zJavaVm() {
    LOGD("Constructor called");
 
    // 通过链接器查找libart.so库
    zElf libart = zLinker::getInstance()->find_lib("libart.so");
 
    // 从libart.so中获取JNI_GetCreatedJavaVMs函数指针
    auto *JNI_GetCreatedJavaVMs  = (jint (*)(JavaVM **, jsize, jsize *))libart.find_symbol("JNI_GetCreatedJavaVMs");
    LOGI("JNI_GetCreatedJavaVMs: %p", JNI_GetCreatedJavaVMs);
    if (JNI_GetCreatedJavaVMs == nullptr) {
        LOGE("GetCreatedJavaVMs not found");
        return;
    }
 
    // 获取已创建的Java虚拟机实例
    JavaVM* vms[10];
    jsize num_vms = 0;
    if (JNI_GetCreatedJavaVMs(vms, 1, &num_vms) != JNI_OK || num_vms == 0) {
        LOGE("GetCreatedJavaVMs failed");
        return;
    }
    LOGI("GetCreatedJavaVMs num_vms %d", num_vms);
 
    // 保存JVM实例指针
    jvm = vms[0];
    LOGI("JVM initialized successfully");
}
// zJavaVm.cpp - 跨线程JNI环境获取
JNIEnv* zJavaVm::getEnv(){
    LOGI("getEnv is called");
    if(jvm == nullptr){
        LOGE("JVM is not initialized");
        return nullptr;
    }
 
    // 获取当前线程ID
    int tid = __syscall0(SYS_gettid);
 
    // 先检查是否已经有当前线程的JNIEnv
    {
        std::lock_guard<std::mutex> lock(env_map_mutex);
        auto it = thread_env_map.find(tid);
        if (it != thread_env_map.end()) {
            LOGI("getEnv: Found existing JNIEnv for thread %p", it->second);
            return it->second;
        }
    }
     
    // 当前线程没有JNIEnv,需要创建新的
    JNIEnv* env = nullptr;
    if (jvm->AttachCurrentThread((JNIEnv **) &env, nullptr) != JNI_OK) {
        LOGE("Failed to attach current thread to JVM");
        return nullptr;
    }
     
    // 将新的JNIEnv添加到映射表中
    {
        std::lock_guard<std::mutex> lock(env_map_mutex);
        thread_env_map[tid] = env;
        LOGI("getEnv: Created new JNIEnv %p for thread %d", env, tid);
    }
     
    return env;
}
// zJavaVm.cpp - 跨线程JNI环境获取
JNIEnv* zJavaVm::getEnv(){
    LOGI("getEnv is called");
    if(jvm == nullptr){
        LOGE("JVM is not initialized");
        return nullptr;
    }
 
    // 获取当前线程ID
    int tid = __syscall0(SYS_gettid);
 
    // 先检查是否已经有当前线程的JNIEnv
    {
        std::lock_guard<std::mutex> lock(env_map_mutex);
        auto it = thread_env_map.find(tid);
        if (it != thread_env_map.end()) {
            LOGI("getEnv: Found existing JNIEnv for thread %p", it->second);
            return it->second;
        }
    }
     
    // 当前线程没有JNIEnv,需要创建新的
    JNIEnv* env = nullptr;
    if (jvm->AttachCurrentThread((JNIEnv **) &env, nullptr) != JNI_OK) {
        LOGE("Failed to attach current thread to JVM");
        return nullptr;
    }
     
    // 将新的JNIEnv添加到映射表中
    {
        std::lock_guard<std::mutex> lock(env_map_mutex);
        thread_env_map[tid] = env;
        LOGI("getEnv: Created new JNIEnv %p for thread %d", env, tid);
    }
     
    return env;
}
jobject createNewContext(JNIEnv* env) {
    LOGD("createNewContext called");
    if (env == nullptr) {
        LOGD("createNewContext: env is null");
        return nullptr;
    }
 
    // 1. 获取 ActivityThread 实例
    jclass clsActivityThread = env->FindClass("android/app/ActivityThread");
    if (clsActivityThread == nullptr) {
        LOGE("Failed to find ActivityThread class");
        return nullptr;
    }
     
    jmethodID m_currentAT = env->GetStaticMethodID(clsActivityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
    if (m_currentAT == nullptr) {
        LOGE("Failed to find currentActivityThread method");
        return nullptr;
    }
     
    jobject at = env->CallStaticObjectMethod(clsActivityThread, m_currentAT);
    if (at == nullptr) {
        LOGE("Failed to get current ActivityThread");
        return nullptr;
    }
 
    // 2. 获取 mBoundApplication 字段
    jfieldID fid_mBoundApp = env->GetFieldID(clsActivityThread, "mBoundApplication", "Landroid/app/ActivityThread$AppBindData;");
    if (fid_mBoundApp == nullptr) {
        LOGE("Failed to find mBoundApplication field");
        env->DeleteLocalRef(at);
        return nullptr;
    }
     
    jobject mBoundApp = env->GetObjectField(at, fid_mBoundApp);
    if (mBoundApp == nullptr) {
        LOGE("Failed to get mBoundApplication");
        env->DeleteLocalRef(at);
        return nullptr;
    }
 
    // 3. 获取 LoadedApk 信息
    jclass clsAppBindData = env->FindClass("android/app/ActivityThread$AppBindData");
    if (clsAppBindData == nullptr) {
        LOGE("Failed to find AppBindData class");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        return nullptr;
    }
     
    jfieldID fid_info = env->GetFieldID(clsAppBindData, "info", "Landroid/app/LoadedApk;");
    if (fid_info == nullptr) {
        LOGE("Failed to find info field");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        return nullptr;
    }
     
    jobject loadedApk = env->GetObjectField(mBoundApp, fid_info);
    if (loadedApk == nullptr) {
        LOGE("Failed to get LoadedApk");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        return nullptr;
    }
 
    // 4. 创建 Application 实例
    jclass clsLoadedApk = env->FindClass("android/app/LoadedApk");
    if (clsLoadedApk == nullptr) {
        LOGE("Failed to find LoadedApk class");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        return nullptr;
    }
     
    jmethodID m_makeApp = env->GetMethodID(clsLoadedApk, "makeApplication", "(ZLandroid/app/Instrumentation;)Landroid/app/Application;");
    if (m_makeApp == nullptr) {
        LOGE("Failed to find makeApplication method");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        return nullptr;
    }
     
    jobject app = env->CallObjectMethod(loadedApk, m_makeApp, JNI_FALSE, nullptr);
    if (app == nullptr) {
        LOGE("Failed to create Application instance");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        return nullptr;
    }
 
    // 5. 获取 Application 的 base context
    jclass clsApp = env->GetObjectClass(app);
    if (clsApp == nullptr) {
        LOGE("Failed to get Application class");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        env->DeleteLocalRef(app);
        return nullptr;
    }
     
    jmethodID m_getBaseContext = env->GetMethodID(clsApp, "getBaseContext", "()Landroid/content/Context;");
    if (m_getBaseContext == nullptr) {
        LOGE("Failed to find getBaseContext method");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        env->DeleteLocalRef(app);
        return nullptr;
    }
     
    jobject context = env->CallObjectMethod(app, m_getBaseContext);
    if (context == nullptr) {
        LOGE("Failed to get base context");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        env->DeleteLocalRef(app);
        return nullptr;
    }
 
    return context;
}
jobject createNewContext(JNIEnv* env) {
    LOGD("createNewContext called");
    if (env == nullptr) {
        LOGD("createNewContext: env is null");
        return nullptr;
    }
 
    // 1. 获取 ActivityThread 实例
    jclass clsActivityThread = env->FindClass("android/app/ActivityThread");
    if (clsActivityThread == nullptr) {
        LOGE("Failed to find ActivityThread class");
        return nullptr;
    }
     
    jmethodID m_currentAT = env->GetStaticMethodID(clsActivityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
    if (m_currentAT == nullptr) {
        LOGE("Failed to find currentActivityThread method");
        return nullptr;
    }
     
    jobject at = env->CallStaticObjectMethod(clsActivityThread, m_currentAT);
    if (at == nullptr) {
        LOGE("Failed to get current ActivityThread");
        return nullptr;
    }
 
    // 2. 获取 mBoundApplication 字段
    jfieldID fid_mBoundApp = env->GetFieldID(clsActivityThread, "mBoundApplication", "Landroid/app/ActivityThread$AppBindData;");
    if (fid_mBoundApp == nullptr) {
        LOGE("Failed to find mBoundApplication field");
        env->DeleteLocalRef(at);
        return nullptr;
    }
     
    jobject mBoundApp = env->GetObjectField(at, fid_mBoundApp);
    if (mBoundApp == nullptr) {
        LOGE("Failed to get mBoundApplication");
        env->DeleteLocalRef(at);
        return nullptr;
    }
 
    // 3. 获取 LoadedApk 信息
    jclass clsAppBindData = env->FindClass("android/app/ActivityThread$AppBindData");
    if (clsAppBindData == nullptr) {
        LOGE("Failed to find AppBindData class");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        return nullptr;
    }
     
    jfieldID fid_info = env->GetFieldID(clsAppBindData, "info", "Landroid/app/LoadedApk;");
    if (fid_info == nullptr) {
        LOGE("Failed to find info field");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        return nullptr;
    }
     
    jobject loadedApk = env->GetObjectField(mBoundApp, fid_info);
    if (loadedApk == nullptr) {
        LOGE("Failed to get LoadedApk");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        return nullptr;
    }
 
    // 4. 创建 Application 实例
    jclass clsLoadedApk = env->FindClass("android/app/LoadedApk");
    if (clsLoadedApk == nullptr) {
        LOGE("Failed to find LoadedApk class");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        return nullptr;
    }
     
    jmethodID m_makeApp = env->GetMethodID(clsLoadedApk, "makeApplication", "(ZLandroid/app/Instrumentation;)Landroid/app/Application;");
    if (m_makeApp == nullptr) {
        LOGE("Failed to find makeApplication method");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        return nullptr;
    }
     
    jobject app = env->CallObjectMethod(loadedApk, m_makeApp, JNI_FALSE, nullptr);
    if (app == nullptr) {
        LOGE("Failed to create Application instance");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        return nullptr;
    }
 
    // 5. 获取 Application 的 base context
    jclass clsApp = env->GetObjectClass(app);
    if (clsApp == nullptr) {
        LOGE("Failed to get Application class");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        env->DeleteLocalRef(app);
        return nullptr;
    }
     
    jmethodID m_getBaseContext = env->GetMethodID(clsApp, "getBaseContext", "()Landroid/content/Context;");
    if (m_getBaseContext == nullptr) {
        LOGE("Failed to find getBaseContext method");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        env->DeleteLocalRef(app);
        return nullptr;
    }
     
    jobject context = env->CallObjectMethod(app, m_getBaseContext);
    if (context == nullptr) {
        LOGE("Failed to get base context");
        env->DeleteLocalRef(at);
        env->DeleteLocalRef(mBoundApp);
        env->DeleteLocalRef(loadedApk);
        env->DeleteLocalRef(app);
        return nullptr;
    }
 
    return context;
}
vector<string> getClassNameList(JNIEnv *env, jobject classloader) {
    LOGD("getClassNameList called");
    vector<string> classNameList = {};
 
    // 获取 classloader 的类
    jclass classloaderClass = env->GetObjectClass(classloader);
 
    // 获取 pathList 字段
    jfieldID pathListFieldID = env->GetFieldID(classloaderClass, "pathList","Ldalvik/system/DexPathList;");
    if (pathListFieldID == nullptr) {
        LOGE("Failed to find field 'pathList' in classloader");
        return classNameList;
    }
 
    jobject pathList = env->GetObjectField(classloader, pathListFieldID);
    if (pathList == nullptr) {
        LOGE("pathList is null");
        return classNameList;
    }
 
    // 获取 dexElements 字段
    jclass dexPathListClass = env->GetObjectClass(pathList);
    jfieldID dexElementsFieldID = env->GetFieldID(dexPathListClass, "dexElements",
                                                  "[Ldalvik/system/DexPathList$Element;");
    if (dexElementsFieldID == nullptr) {
        LOGE("Failed to find field 'dexElements' in DexPathList");
        return classNameList;
    }
 
    jobjectArray dexElements = (jobjectArray) env->GetObjectField(pathList, dexElementsFieldID);
    if (dexElements == nullptr) {
        LOGE("dexElements is null");
        return classNameList;
    }
 
    // 遍历 dexElements 数组
    jint dexElementsLength = env->GetArrayLength(dexElements);
    for (jint i = 0; i < dexElementsLength; i++) {
        jobject dexElement = env->GetObjectArrayElement(dexElements, i);
 
        // 获取 dexFile 字段
        jclass dexElementClass = env->GetObjectClass(dexElement);
        jfieldID dexFileFieldID = env->GetFieldID(dexElementClass, "dexFile",
                                                  "Ldalvik/system/DexFile;");
        if (dexFileFieldID == nullptr) {
            LOGE("Failed to find field 'dexFile' in DexPathList$Element");
            continue;
        }
 
        jobject dexFile = env->GetObjectField(dexElement, dexFileFieldID);
        if (dexFile == nullptr) {
            LOGE("dexFile is null");
            continue;
        }
 
        // 获取 DexFile 的类名列表
        jclass dexFileClass = env->GetObjectClass(dexFile);
        jmethodID entriesMethodID = env->GetMethodID(dexFileClass, "entries", "()Ljava/util/Enumeration;");
        if (entriesMethodID == nullptr) {
            LOGE("Failed to find method 'entries' in DexFile");
            continue;
        }
 
        jobject entries = env->CallObjectMethod(dexFile, entriesMethodID);
        if (entries == nullptr) {
            LOGE("entries is null");
            continue;
        }
 
        // 遍历类名
        jclass enumerationClass = env->FindClass("java/util/Enumeration");
        jmethodID hasMoreElementsMethodID = env->GetMethodID(enumerationClass, "hasMoreElements", "()Z");
        jmethodID nextElementMethodID = env->GetMethodID(enumerationClass, "nextElement","()Ljava/lang/Object;");
        while (env->CallBooleanMethod(entries, hasMoreElementsMethodID)) {
            jstring className = (jstring) env->CallObjectMethod(entries, nextElementMethodID);
            const char *classNameStr = env->GetStringUTFChars(className, nullptr);
            classNameList.push_back(classNameStr);
            env->ReleaseStringUTFChars(className, classNameStr);
            env->DeleteLocalRef(className);
        }
 
        // 清理局部引用
        env->DeleteLocalRef(entries);
        env->DeleteLocalRef(dexFile);
        env->DeleteLocalRef(dexElement);
        env->DeleteLocalRef(dexElementClass);
        env->DeleteLocalRef(dexFileClass);
        env->DeleteLocalRef(enumerationClass);
    }
 
    // 清理局部引用
    env->DeleteLocalRef(dexElements);
    env->DeleteLocalRef(pathList);
    env->DeleteLocalRef(classloaderClass);
 
    return classNameList;
}
vector<string> getClassNameList(JNIEnv *env, jobject classloader) {
    LOGD("getClassNameList called");
    vector<string> classNameList = {};
 
    // 获取 classloader 的类
    jclass classloaderClass = env->GetObjectClass(classloader);
 
    // 获取 pathList 字段
    jfieldID pathListFieldID = env->GetFieldID(classloaderClass, "pathList","Ldalvik/system/DexPathList;");
    if (pathListFieldID == nullptr) {
        LOGE("Failed to find field 'pathList' in classloader");
        return classNameList;
    }
 
    jobject pathList = env->GetObjectField(classloader, pathListFieldID);
    if (pathList == nullptr) {
        LOGE("pathList is null");
        return classNameList;
    }
 
    // 获取 dexElements 字段
    jclass dexPathListClass = env->GetObjectClass(pathList);
    jfieldID dexElementsFieldID = env->GetFieldID(dexPathListClass, "dexElements",
                                                  "[Ldalvik/system/DexPathList$Element;");
    if (dexElementsFieldID == nullptr) {
        LOGE("Failed to find field 'dexElements' in DexPathList");
        return classNameList;
    }
 
    jobjectArray dexElements = (jobjectArray) env->GetObjectField(pathList, dexElementsFieldID);
    if (dexElements == nullptr) {
        LOGE("dexElements is null");
        return classNameList;
    }
 
    // 遍历 dexElements 数组
    jint dexElementsLength = env->GetArrayLength(dexElements);
    for (jint i = 0; i < dexElementsLength; i++) {
        jobject dexElement = env->GetObjectArrayElement(dexElements, i);
 
        // 获取 dexFile 字段
        jclass dexElementClass = env->GetObjectClass(dexElement);
        jfieldID dexFileFieldID = env->GetFieldID(dexElementClass, "dexFile",
                                                  "Ldalvik/system/DexFile;");
        if (dexFileFieldID == nullptr) {
            LOGE("Failed to find field 'dexFile' in DexPathList$Element");
            continue;
        }
 
        jobject dexFile = env->GetObjectField(dexElement, dexFileFieldID);
        if (dexFile == nullptr) {
            LOGE("dexFile is null");
            continue;
        }
 
        // 获取 DexFile 的类名列表
        jclass dexFileClass = env->GetObjectClass(dexFile);
        jmethodID entriesMethodID = env->GetMethodID(dexFileClass, "entries", "()Ljava/util/Enumeration;");
        if (entriesMethodID == nullptr) {
            LOGE("Failed to find method 'entries' in DexFile");
            continue;
        }
 
        jobject entries = env->CallObjectMethod(dexFile, entriesMethodID);
        if (entries == nullptr) {
            LOGE("entries is null");
            continue;
        }
 
        // 遍历类名
        jclass enumerationClass = env->FindClass("java/util/Enumeration");
        jmethodID hasMoreElementsMethodID = env->GetMethodID(enumerationClass, "hasMoreElements", "()Z");
        jmethodID nextElementMethodID = env->GetMethodID(enumerationClass, "nextElement","()Ljava/lang/Object;");
        while (env->CallBooleanMethod(entries, hasMoreElementsMethodID)) {
            jstring className = (jstring) env->CallObjectMethod(entries, nextElementMethodID);
            const char *classNameStr = env->GetStringUTFChars(className, nullptr);
            classNameList.push_back(classNameStr);
            env->ReleaseStringUTFChars(className, classNameStr);
            env->DeleteLocalRef(className);
        }
 
        // 清理局部引用
        env->DeleteLocalRef(entries);
        env->DeleteLocalRef(dexFile);
        env->DeleteLocalRef(dexElement);
        env->DeleteLocalRef(dexElementClass);
        env->DeleteLocalRef(dexFileClass);
        env->DeleteLocalRef(enumerationClass);
    }
 
    // 清理局部引用
    env->DeleteLocalRef(dexElements);
    env->DeleteLocalRef(pathList);
    env->DeleteLocalRef(classloaderClass);
 
    return classNameList;
}
// zClassLoader.cpp - ART内部API遍历实现
class ClassLoaderVisitor : public art::SingleRootVisitor {
public:
    vector<string> classLoaderStringList;  // 类加载器字符串列表
    vector<string> classNameList;          // 类名列表
 
    /**
     * 构造函数
     * @param env JNI环境指针
     * @param classLoader 目标类加载器类型
     */
    ClassLoaderVisitor(JNIEnv *env, jclass classLoader) : env_(env), classLoader_(classLoader) {
        classLoaderStringList = vector<string>();
        classNameList = vector<string>();
    }
 
    /**
     * 访问根对象的回调函数
     * 检查每个根对象是否为类加载器,如果是则收集信息
     */
    void VisitRoot(art::mirror::Object *root, const art::RootInfo &info ATTRIBUTE_UNUSED) final {
        // 创建局部引用
        jobject object = newLocalRef(env_, (jobject) root);
        if (object != nullptr) {
            // 检查对象是否为指定类型的类加载器
            if (env_->IsInstanceOf(object, classLoader_)) {
                // 获取类加载器名称
                string classLoaderName = getClassName((JNIEnv *) env_, object);
                LOGD("ClassLoaderVisitor classLoaderName %s", classLoaderName.c_str());
                 
                // 获取类加载器字符串表示
                string classLoaderString = get_class_loader_string(env_, object);
                LOGD("ClassLoaderVisitor %s", classLoaderString.c_str());
                 
                // 获取该类加载器加载的所有类名
                vector<string> classLoaderClassNameList = getClassNameList((JNIEnv *) env_, object);
 
                // 添加到结果列表
                classLoaderStringList.push_back(classLoaderString);
                classNameList.insert(classNameList.end(), classLoaderClassNameList.begin(), classLoaderClassNameList.end());
 
            }else{
                // 不是目标类型,删除局部引用
                deleteLocalRef(env_, object);
            }
        }
    }
 
private:
    JNIEnv *env_;           // JNI环境指针
    jclass classLoader_;     // 目标类加载器类型
};
 
// 检查全局引用中的类加载器
void zClassLoader::checkGlobalRef(JNIEnv *env, jclass clazz) {
    LOGD("checkGlobalRef called");
    // 从libart.so中获取VisitRoots函数指针
    auto VisitRoots = (void (*)(void *, void *)) zLinker::getInstance()->find_lib("libart.so").find_symbol("_ZN3art9JavaVMExt10VisitRootsEPNS_11RootVisitorE");
 
    if (VisitRoots == nullptr) {
        LOGE("Failed to find method 'VisitRoots' in JavaVMExt");
        return;
    }
     
    // 获取JavaVM指针
    JavaVM *jvm;
    env->GetJavaVM(&jvm);
     
    // 创建访问者并开始遍历
    ClassLoaderVisitor visitor(env, clazz);
    VisitRoots(jvm, &visitor);
 
    // 将访问者收集的结果合并到全局列表
    classLoaderStringList.insert(classLoaderStringList.end(), visitor.classLoaderStringList.begin(), visitor.classLoaderStringList.end());
    classNameList.insert(classNameList.end(), visitor.classNameList.begin(), visitor.classNameList.end());
 
    LOGI("ClassLoaderVisitor classLoaderStringList size %zu", visitor.classLoaderStringList.size());
}
// zClassLoader.cpp - ART内部API遍历实现
class ClassLoaderVisitor : public art::SingleRootVisitor {
public:
    vector<string> classLoaderStringList;  // 类加载器字符串列表
    vector<string> classNameList;          // 类名列表
 
    /**
     * 构造函数
     * @param env JNI环境指针
     * @param classLoader 目标类加载器类型
     */
    ClassLoaderVisitor(JNIEnv *env, jclass classLoader) : env_(env), classLoader_(classLoader) {
        classLoaderStringList = vector<string>();
        classNameList = vector<string>();
    }
 
    /**
     * 访问根对象的回调函数
     * 检查每个根对象是否为类加载器,如果是则收集信息
     */
    void VisitRoot(art::mirror::Object *root, const art::RootInfo &info ATTRIBUTE_UNUSED) final {
        // 创建局部引用
        jobject object = newLocalRef(env_, (jobject) root);
        if (object != nullptr) {
            // 检查对象是否为指定类型的类加载器
            if (env_->IsInstanceOf(object, classLoader_)) {
                // 获取类加载器名称
                string classLoaderName = getClassName((JNIEnv *) env_, object);
                LOGD("ClassLoaderVisitor classLoaderName %s", classLoaderName.c_str());
                 
                // 获取类加载器字符串表示
                string classLoaderString = get_class_loader_string(env_, object);
                LOGD("ClassLoaderVisitor %s", classLoaderString.c_str());
                 
                // 获取该类加载器加载的所有类名
                vector<string> classLoaderClassNameList = getClassNameList((JNIEnv *) env_, object);
 
                // 添加到结果列表
                classLoaderStringList.push_back(classLoaderString);
                classNameList.insert(classNameList.end(), classLoaderClassNameList.begin(), classLoaderClassNameList.end());
 
            }else{
                // 不是目标类型,删除局部引用
                deleteLocalRef(env_, object);
            }
        }
    }
 
private:
    JNIEnv *env_;           // JNI环境指针
    jclass classLoader_;     // 目标类加载器类型
};
 
// 检查全局引用中的类加载器
void zClassLoader::checkGlobalRef(JNIEnv *env, jclass clazz) {
    LOGD("checkGlobalRef called");
    // 从libart.so中获取VisitRoots函数指针
    auto VisitRoots = (void (*)(void *, void *)) zLinker::getInstance()->find_lib("libart.so").find_symbol("_ZN3art9JavaVMExt10VisitRootsEPNS_11RootVisitorE");
 
    if (VisitRoots == nullptr) {
        LOGE("Failed to find method 'VisitRoots' in JavaVMExt");
        return;
    }
     
    // 获取JavaVM指针
    JavaVM *jvm;
    env->GetJavaVM(&jvm);
     
    // 创建访问者并开始遍历
    ClassLoaderVisitor visitor(env, clazz);
    VisitRoots(jvm, &visitor);
 
    // 将访问者收集的结果合并到全局列表
    classLoaderStringList.insert(classLoaderStringList.end(), visitor.classLoaderStringList.begin(), visitor.classLoaderStringList.end());
    classNameList.insert(classNameList.end(), visitor.classNameList.begin(), visitor.classNameList.end());
 
    LOGI("ClassLoaderVisitor classLoaderStringList size %zu", visitor.classLoaderStringList.size());
}
// zLinker.cpp - Linker初始化实现
zLinker::zLinker() {
    LOGD("Constructor called");
     
    // 解析linker64 ELF文件
    this->elf_file_ptr = parse_elf_file("/system/bin/linker64");
    LOGI("linker64 elf_file_ptr %p", this->elf_file_ptr);
 
    // 解析ELF文件结构
    parse_elf_head();
    parse_program_header_table();
    parse_section_table();
 
    // 获取linker64在内存中的基地址
    this->elf_mem_ptr = get_maps_base("linker64");
    LOGI("linker64 elf_mem_ptr %p", this->elf_mem_ptr);
 
    // 获取soinfo链表头指针函数
    soinfo*(*solist_get_head)() = (soinfo*(*)())(this->find_symbol("__dl__Z15solist_get_headv"));
    LOGI("linker64 solist_get_head %p", solist_get_head);
 
    // 获取soinfo链表头
    soinfo_head = solist_get_head();
    LOGI("soinfo_head %p", soinfo_head);
 
    // 获取get_realpath函数指针,用于获取共享库的真实路径
    soinfo_get_realpath = (char*(*)(void*))(this->find_symbol("__dl__ZNK6soinfo12get_realpathEv"));
    LOGI("soinfo_get_realpath %p", soinfo_get_realpath);
}
// zLinker.cpp - Linker初始化实现
zLinker::zLinker() {
    LOGD("Constructor called");
     
    // 解析linker64 ELF文件
    this->elf_file_ptr = parse_elf_file("/system/bin/linker64");
    LOGI("linker64 elf_file_ptr %p", this->elf_file_ptr);
 
    // 解析ELF文件结构
    parse_elf_head();
    parse_program_header_table();
    parse_section_table();
 
    // 获取linker64在内存中的基地址
    this->elf_mem_ptr = get_maps_base("linker64");
    LOGI("linker64 elf_mem_ptr %p", this->elf_mem_ptr);
 
    // 获取soinfo链表头指针函数
    soinfo*(*solist_get_head)() = (soinfo*(*)())(this->find_symbol("__dl__Z15solist_get_headv"));
    LOGI("linker64 solist_get_head %p", solist_get_head);
 
    // 获取soinfo链表头
    soinfo_head = solist_get_head();
    LOGI("soinfo_head %p", soinfo_head);
 
    // 获取get_realpath函数指针,用于获取共享库的真实路径
    soinfo_get_realpath = (char*(*)(void*))(this->find_symbol("__dl__ZNK6soinfo12get_realpathEv"));
    LOGI("soinfo_get_realpath %p", soinfo_get_realpath);
}
vector<string> zLinker::get_libpath_list(){
    LOGD("get_libpath_list called");
    vector<string> libpath_list = vector<string>();
    soinfo* soinfo = soinfo_head;
    while(soinfo->next != nullptr){
        char* real_path = soinfo_get_realpath(soinfo);
        libpath_list.push_back(real_path);
        soinfo = soinfo->next;
    }
    LOGI("get_libpath_list: found %zu libraries", libpath_list.size());
    return libpath_list;
}
vector<string> zLinker::get_libpath_list(){
    LOGD("get_libpath_list called");
    vector<string> libpath_list = vector<string>();
    soinfo* soinfo = soinfo_head;
    while(soinfo->next != nullptr){
        char* real_path = soinfo_get_realpath(soinfo);
        libpath_list.push_back(real_path);
        soinfo = soinfo->next;
    }
    LOGI("get_libpath_list: found %zu libraries", libpath_list.size());
    return libpath_list;
}
// zLinker.cpp - 库完整性CRC校验
bool zLinker::check_lib_crc(const char* so_name){
    LOGD("check_lib_crc called with so_name: %s", so_name);
    LOGI("check_lib_hash so_name: %s", so_name);
     
    // 获取共享库的zElf对象(文件版本)
    zElf elf_lib_file = zLinker::getInstance()->find_lib(so_name);
    LOGI("zElf elf_lib_file = zLinker::getInstance()->find_lib(so_name);");
 
    // 计算文件版本的CRC校验和(ELF头 + 程序头 + 代码段)
    uint64_t elf_lib_file_crc = elf_lib_file.get_elf_header_crc() +
                                elf_lib_file.get_program_header_crc() +
                                elf_lib_file.get_text_segment_crc();
    LOGI("check_lib_hash elf_lib_file: %p crc: %lu", elf_lib_file.elf_file_ptr, elf_lib_file_crc);
 
    // 获取共享库的内存版本zElf对象
    zElf elf_lib_mem = zElf((void*)zLinker::get_maps_base(so_name));
    // 计算内存版本的CRC校验和
    uint64_t elf_lib_mem_crc = elf_lib_mem.get_elf_header_crc() +
                               elf_lib_mem.get_program_header_crc() +
                               elf_lib_mem.get_text_segment_crc();
 
    LOGI("check_lib_hash elf_lib_mem: %p crc: %lu", elf_lib_mem.elf_mem_ptr, elf_lib_mem_crc);
 
    // 比较文件版本和内存版本的CRC校验和
    bool crc_mismatch = elf_lib_file_crc != elf_lib_mem_crc;
    if (crc_mismatch) {
        LOGW("check_lib_crc: CRC mismatch detected for %s", so_name);
    } else {
        LOGI("check_lib_crc: CRC match for %s", so_name);
    }
    return crc_mismatch;
}
// zLinker.cpp - 库完整性CRC校验
bool zLinker::check_lib_crc(const char* so_name){
    LOGD("check_lib_crc called with so_name: %s", so_name);
    LOGI("check_lib_hash so_name: %s", so_name);
     
    // 获取共享库的zElf对象(文件版本)
    zElf elf_lib_file = zLinker::getInstance()->find_lib(so_name);
    LOGI("zElf elf_lib_file = zLinker::getInstance()->find_lib(so_name);");
 
    // 计算文件版本的CRC校验和(ELF头 + 程序头 + 代码段)
    uint64_t elf_lib_file_crc = elf_lib_file.get_elf_header_crc() +
                                elf_lib_file.get_program_header_crc() +
                                elf_lib_file.get_text_segment_crc();
    LOGI("check_lib_hash elf_lib_file: %p crc: %lu", elf_lib_file.elf_file_ptr, elf_lib_file_crc);
 
    // 获取共享库的内存版本zElf对象
    zElf elf_lib_mem = zElf((void*)zLinker::get_maps_base(so_name));
    // 计算内存版本的CRC校验和
    uint64_t elf_lib_mem_crc = elf_lib_mem.get_elf_header_crc() +
                               elf_lib_mem.get_program_header_crc() +
                               elf_lib_mem.get_text_segment_crc();
 
    LOGI("check_lib_hash elf_lib_mem: %p crc: %lu", elf_lib_mem.elf_mem_ptr, elf_lib_mem_crc);
 
    // 比较文件版本和内存版本的CRC校验和
    bool crc_mismatch = elf_lib_file_crc != elf_lib_mem_crc;
    if (crc_mismatch) {
        LOGW("check_lib_crc: CRC mismatch detected for %s", so_name);
    } else {
        LOGI("check_lib_crc: CRC match for %s", so_name);
    }
    return crc_mismatch;
}
// zHttps.cpp - HTTPS请求执行
HttpsResponse zHttps::performRequest(const HttpsRequest& request) {
    HttpsResponse response;
     
    // 使用请求的超时时间,如果没有设置则使用默认超时
    int timeout_seconds = request.timeout_seconds > 0 ? request.timeout_seconds : default_timeout_seconds;
     
    // 为本次请求创建独立的计时器和资源
    RequestTimer timer(timeout_seconds);
    RequestResources resources;
    LOGI("Starting HTTPS request with timeout: %d seconds", timer.timeout_seconds);
     
    // 安全检查:确保只使用HTTPS协议,但允许任意端口
    if (request.url.substr(0, 8) != "https://") {
        response.error_message = "Only HTTPS URLs are supported";
        LOGE("Security Error: Only HTTPS protocol is allowed");
        return response;
    }
 
    // 初始化mbedtls(如果需要)
    if (!initialized) {
        if (!initialize()) {
            response.error_message = "Failed to initialize mbedtls";
            LOGE("Failed to initialize mbedtls");
            return response;
        }
    }
     
    // 确保每次请求都使用干净的状态
    // 这可以防止前一次请求的失败状态影响当前请求
    LOGI("Starting new HTTPS request to %s", request.host.c_str());
     
    // 重置全局SSL状态,确保每次请求都是独立的
    if (initialized) {
        // 重新初始化全局资源以确保干净状态
        cleanup();
        if (!initialize()) {
            response.error_message = "Failed to reinitialize mbedtls";
            LOGE("Failed to reinitialize mbedtls");
            return response;
        }
    }
 
    // 记录本地设置的证书固定信息
    auto it = pinned_certificates.find(request.host);
    if (it != pinned_certificates.end()) {
        response.pinned_certificate = it->second;
    }
 
    char error_buf[0x1000];
    int ret;
 
    // 使用自定义socket连接
    LOGI("Connecting to %s:%d with custom socket...", request.host.c_str(), request.port);
     
    // 检查超时
    if (timer.isTimeout()) {
        response.error_message = "Connection timeout before establishing connection";
        LOGE("Connection timeout before establishing connection");
        return response;
    }
     
    // 记录连接开始时间
    time_t connect_start = time(nullptr);
    LOGI("Connection attempt started at: %ld", connect_start);
     
    // 使用自定义socket连接,带超时控制
    resources.sockfd = connectWithTimeout(request.host, request.port, timeout_seconds);
     
    // 记录连接结束时间
    time_t connect_end = time(nullptr);
    int connect_duration = connect_end - connect_start;
    LOGI("Connection attempt completed in %d seconds", connect_duration);
     
    if (resources.sockfd < 0) {
        response.error_message = "Connection failed with custom socket";
        LOGE("Connection failed after %d seconds with custom socket", connect_duration);
        return response;
    }
     
    // 将socket文件描述符设置到mbedtls网络上下文
    resources.server_fd.fd = resources.sockfd;
     
    // 标记连接建立完成
    timer.markConnection();
     
    // 配置SSL上下文
    mbedtls_ssl_config_init(&resources.conf);
    ret = mbedtls_ssl_config_defaults(&resources.conf,
                                      MBEDTLS_SSL_IS_CLIENT,
                                      MBEDTLS_SSL_TRANSPORT_STREAM,
                                      MBEDTLS_SSL_PRESET_DEFAULT);
     
    // 强制证书验证 - 不允许跳过验证
    mbedtls_ssl_conf_authmode(&resources.conf, MBEDTLS_SSL_VERIFY_REQUIRED);
    mbedtls_ssl_conf_ca_chain(&resources.conf, &cacert, nullptr);
     
    // 设置最小TLS版本为1.2(禁用TLS 1.0和1.1)
    mbedtls_ssl_conf_min_version(&resources.conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
     
    // 执行TLS握手
    ret = mbedtls_ssl_handshake(&resources.ssl);
    if (ret != 0) {
        mbedtls_strerror(ret, error_buf, sizeof(error_buf));
        response.error_message = "TLS handshake failed: " + string(error_buf);
        return response;
    }
     
    // 验证证书
    uint32_t flags = mbedtls_ssl_get_verify_result(&resources.ssl);
    if (flags != 0) {
        response.ssl_verification_passed = false;
    } else {
        response.ssl_verification_passed = true;
    }
     
    // 获取服务器证书并验证证书固定
    const mbedtls_x509_crt* cert = mbedtls_ssl_get_peer_cert(&resources.ssl);
    if (cert) {
        response.certificate = extractCertificateInfo(cert);
        response.certificate_pinning_passed = verifyCertificatePinning(cert, request.host);
    }
     
    // 发送HTTPS请求和读取响应...
     
    return response;
}
// zHttps.cpp - HTTPS请求执行
HttpsResponse zHttps::performRequest(const HttpsRequest& request) {
    HttpsResponse response;
     
    // 使用请求的超时时间,如果没有设置则使用默认超时
    int timeout_seconds = request.timeout_seconds > 0 ? request.timeout_seconds : default_timeout_seconds;
     
    // 为本次请求创建独立的计时器和资源
    RequestTimer timer(timeout_seconds);
    RequestResources resources;
    LOGI("Starting HTTPS request with timeout: %d seconds", timer.timeout_seconds);
     
    // 安全检查:确保只使用HTTPS协议,但允许任意端口
    if (request.url.substr(0, 8) != "https://") {
        response.error_message = "Only HTTPS URLs are supported";
        LOGE("Security Error: Only HTTPS protocol is allowed");
        return response;
    }
 
    // 初始化mbedtls(如果需要)
    if (!initialized) {
        if (!initialize()) {
            response.error_message = "Failed to initialize mbedtls";
            LOGE("Failed to initialize mbedtls");
            return response;
        }
    }
     
    // 确保每次请求都使用干净的状态
    // 这可以防止前一次请求的失败状态影响当前请求
    LOGI("Starting new HTTPS request to %s", request.host.c_str());
     
    // 重置全局SSL状态,确保每次请求都是独立的
    if (initialized) {
        // 重新初始化全局资源以确保干净状态
        cleanup();
        if (!initialize()) {
            response.error_message = "Failed to reinitialize mbedtls";
            LOGE("Failed to reinitialize mbedtls");
            return response;
        }
    }
 
    // 记录本地设置的证书固定信息
    auto it = pinned_certificates.find(request.host);
    if (it != pinned_certificates.end()) {
        response.pinned_certificate = it->second;
    }
 
    char error_buf[0x1000];
    int ret;
 
    // 使用自定义socket连接
    LOGI("Connecting to %s:%d with custom socket...", request.host.c_str(), request.port);
     
    // 检查超时
    if (timer.isTimeout()) {
        response.error_message = "Connection timeout before establishing connection";
        LOGE("Connection timeout before establishing connection");
        return response;
    }
     
    // 记录连接开始时间
    time_t connect_start = time(nullptr);
    LOGI("Connection attempt started at: %ld", connect_start);
     
    // 使用自定义socket连接,带超时控制
    resources.sockfd = connectWithTimeout(request.host, request.port, timeout_seconds);
     
    // 记录连接结束时间
    time_t connect_end = time(nullptr);
    int connect_duration = connect_end - connect_start;
    LOGI("Connection attempt completed in %d seconds", connect_duration);
     
    if (resources.sockfd < 0) {
        response.error_message = "Connection failed with custom socket";
        LOGE("Connection failed after %d seconds with custom socket", connect_duration);
        return response;
    }
     
    // 将socket文件描述符设置到mbedtls网络上下文
    resources.server_fd.fd = resources.sockfd;
     
    // 标记连接建立完成
    timer.markConnection();
     
    // 配置SSL上下文
    mbedtls_ssl_config_init(&resources.conf);
    ret = mbedtls_ssl_config_defaults(&resources.conf,
                                      MBEDTLS_SSL_IS_CLIENT,
                                      MBEDTLS_SSL_TRANSPORT_STREAM,
                                      MBEDTLS_SSL_PRESET_DEFAULT);
     
    // 强制证书验证 - 不允许跳过验证
    mbedtls_ssl_conf_authmode(&resources.conf, MBEDTLS_SSL_VERIFY_REQUIRED);
    mbedtls_ssl_conf_ca_chain(&resources.conf, &cacert, nullptr);
     
    // 设置最小TLS版本为1.2(禁用TLS 1.0和1.1)
    mbedtls_ssl_conf_min_version(&resources.conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
     
    // 执行TLS握手
    ret = mbedtls_ssl_handshake(&resources.ssl);
    if (ret != 0) {
        mbedtls_strerror(ret, error_buf, sizeof(error_buf));
        response.error_message = "TLS handshake failed: " + string(error_buf);
        return response;
    }
     
    // 验证证书
    uint32_t flags = mbedtls_ssl_get_verify_result(&resources.ssl);
    if (flags != 0) {
        response.ssl_verification_passed = false;
    } else {
        response.ssl_verification_passed = true;
    }
     
    // 获取服务器证书并验证证书固定
    const mbedtls_x509_crt* cert = mbedtls_ssl_get_peer_cert(&resources.ssl);
    if (cert) {
        response.certificate = extractCertificateInfo(cert);
        response.certificate_pinning_passed = verifyCertificatePinning(cert, request.host);
    }
     
    // 发送HTTPS请求和读取响应...
     
    return response;
}
bool zHttps::verifyCertificatePinning(const mbedtls_x509_crt* cert, const string& hostname) {
    LOGD("verifyCertificatePinning called for hostname: %s", hostname.c_str());
    auto it = pinned_certificates.find(hostname);
    if (it == pinned_certificates.end()) {
        LOGI("No pinned certificate for hostname: %s, skipping pinning check.", hostname.c_str());
        return true; // 没有固定证书时跳过验证
    }
 
    const CertificateInfo& pinned = it->second;
    bool serial_match = (pinned.serial_number == extractCertificateInfo(cert).serial_number);
    bool fingerprint_match = (pinned.fingerprint_sha256 == extractCertificateInfo(cert).fingerprint_sha256);
     
    // 只有当期望的subject不为空时才验证subject
    bool subject_match = true;
    if (!pinned.subject.empty()) {
        subject_match = (pinned.subject == extractCertificateInfo(cert).subject);
    }
 
    if (!serial_match || !fingerprint_match || !subject_match) {
        LOGW("Certificate pinning verification failed for %s", hostname.c_str());
        LOGD("serial_match %d fingerprint_match %d subject_match %d ", serial_match, fingerprint_match, subject_match);
         
        // 输出详细信息用于调试
        if (!serial_match) {
            LOGD("Expected serial: %s, Got: %s",
                 pinned.serial_number.c_str(),
                 extractCertificateInfo(cert).serial_number.c_str());
        }
        if (!fingerprint_match) {
            LOGD("Expected fingerprint: %s, Got: %s",
                 pinned.fingerprint_sha256.c_str(),
                 extractCertificateInfo(cert).fingerprint_sha256.c_str());
        }
        if (!subject_match && !pinned.subject.empty()) {
            LOGD("Expected subject: %s, Got: %s",
                 pinned.subject.c_str(),
                 extractCertificateInfo(cert).subject.c_str());
        }
         
        return false;
    }
    LOGI("Certificate pinning verification passed for %s", hostname.c_str());
    return true;
}
bool zHttps::verifyCertificatePinning(const mbedtls_x509_crt* cert, const string& hostname) {
    LOGD("verifyCertificatePinning called for hostname: %s", hostname.c_str());
    auto it = pinned_certificates.find(hostname);
    if (it == pinned_certificates.end()) {
        LOGI("No pinned certificate for hostname: %s, skipping pinning check.", hostname.c_str());
        return true; // 没有固定证书时跳过验证
    }
 
    const CertificateInfo& pinned = it->second;
    bool serial_match = (pinned.serial_number == extractCertificateInfo(cert).serial_number);
    bool fingerprint_match = (pinned.fingerprint_sha256 == extractCertificateInfo(cert).fingerprint_sha256);
     
    // 只有当期望的subject不为空时才验证subject
    bool subject_match = true;
    if (!pinned.subject.empty()) {
        subject_match = (pinned.subject == extractCertificateInfo(cert).subject);
    }
 
    if (!serial_match || !fingerprint_match || !subject_match) {
        LOGW("Certificate pinning verification failed for %s", hostname.c_str());
        LOGD("serial_match %d fingerprint_match %d subject_match %d ", serial_match, fingerprint_match, subject_match);
         
        // 输出详细信息用于调试
        if (!serial_match) {
            LOGD("Expected serial: %s, Got: %s",
                 pinned.serial_number.c_str(),
                 extractCertificateInfo(cert).serial_number.c_str());
        }
        if (!fingerprint_match) {
            LOGD("Expected fingerprint: %s, Got: %s",
                 pinned.fingerprint_sha256.c_str(),
                 extractCertificateInfo(cert).fingerprint_sha256.c_str());
        }
        if (!subject_match && !pinned.subject.empty()) {
            LOGD("Expected subject: %s, Got: %s",

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-11-8 01:13 被简单的简单编辑 ,原因: 更新部分内容
收藏
免费 112
支持
分享
最新回复 (62)
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2025-8-2 01:34
0
雪    币: 3036
活跃值: (3889)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
深夜发帖
2025-8-2 03:28
0
雪    币: 498
活跃值: (5371)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
牛逼克拉斯
2025-8-2 10:01
0
雪    币: 1907
活跃值: (1519)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
cy
2025-8-2 11:04
0
雪    币: 290
活跃值: (1024)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Yangser cy
CY
2025-8-2 21:48
1
雪    币: 105
活跃值: (2277)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
6666
2025-8-3 01:44
0
雪    币: 42
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
可以私聊吗
2025-8-3 22:16
0
雪    币: 260
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
1
2025-8-4 00:24
0
雪    币: 0
活跃值: (115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
O
2025-8-4 02:28
0
雪    币: 2790
活跃值: (5496)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
感谢分享
2025-8-4 08:33
0
雪    币: 396
活跃值: (2983)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
感谢分享
2025-8-4 09:07
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
6
2025-8-4 09:52
0
雪    币: 343
活跃值: (1756)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
6666
2025-8-4 10:13
0
雪    币: 150
活跃值: (1867)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
1111111111111111111
2025-8-4 10:24
0
雪    币: 912
活跃值: (2010)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
666
2025-8-4 11:48
0
雪    币: 1495
活跃值: (3698)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
17
666
2025-8-4 12:05
0
雪    币: 84
活跃值: (3408)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
66
2025-8-4 14:41
0
雪    币: 102
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
学习
2025-8-4 15:37
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
666
2025-8-4 16:29
0
雪    币: 1495
活跃值: (3698)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
21
老铁有成品吗,我在本机编译运行,直接闪退了
2025-8-4 16:40
0
雪    币: 3673
活跃值: (5807)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
感谢分享
2025-8-4 16:42
0
雪    币: 38
活跃值: (1339)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
6666
2025-8-4 17:12
0
雪    币: 11
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
666
2025-8-4 17:50
0
雪    币: 146
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
mark
2025-8-5 01:26
0
游客
登录 | 注册 方可回帖
返回