先hook一下dlopen,也就是android_dlopen_ext
为什么要Hook dlopen呢?
因为App的Frida检测代码一般都在so层实现,这些检测代码会在对应的so加载时初始化
Frida进程会被杀死,同时手机也会卡死,而且也加载了特征so
这是为什么呢?
我们的反制措施为Hook Clone函数
Clone函数为Linux创建线程的底层调用,Hook这个函数我们可以知道每个线程的详细信息,例如:谁创建的,线程函数在哪,什么时候创建的
这样我们就可以定位到反调试线程,然后分析它,干掉它
为什么要在var real_func = args[3].add(96).readPointer(); 读取?
我们需要了解一下 pthread_internal_t 结构体也就是pthread_t
这是 Android Bionic 库中用来管理线程的内部结构:
那么什么时候会创建这个结构体呢?肯定是线程被创建的时候,也就是pthread_create函数
安卓平台上总共有三种线程:
1. Java 线程:Android 虚拟机线程,具有运行 Java 代码的 Runtime
2. Native 线程(只能执行 C/C++):纯粹的 Linux 线程
3. Native 线程(还能执行 Java):既能执行 C/C++ 代码,也能执行 Java 代码
java层:Thread.start()
nativeCreate为JNI方法,对应C++层的Thread_nativeCreate
JNI方法映射
展开后,nativeCreate 映射到 Thread_nativeCreate 函数。
Thread_nativeCreate
CreateNativeThread
- 创建 ART 虚拟机的 Thread 对象
- 关联 Java 和 Native 的 Thread 对象(双向引用)
- 创建 JNI 环境,使线程能够调用 Java 代码
- 调用 pthread_create 创建真正的操作系统线程
Thread::CreateCallback
- 线程启动后先初始化 ART虚拟机环境,通过反射调用 Java 层的 run() 方法执行完毕后进行资源清理
pthread_create在CreateNativeThread时被调用
pthread_create` 会先得到一个`pthread_internal_t`结构体
pthread_create会先得到一个pthread_internal_t结构体
这个结构体为核心数据结构,包含了线程的所有信息
pthread_create是pthread库中的函数,通过syscall再调用到clone来请求内核创建线程
Linux创建进程采用fork()和exec()
- fork: 采用复制当前进程的方式来创建子进程,此时子进程与父进程的区别仅在于pid, ppid以及资源统计量(比如挂起的信号)
- exec:读取可执行文件并载入地址空间执行;一般称之为exec函数族,有一系列exec开头的函数,比如execl, execve等
fork过程复制资源包括代码段,数据段,堆,栈。fork调用者所在进程便是父进程,新创建的进程便是子进程;在fork调用结束,从内核返回两次,一次继续执行父进程,一次进入执行子进程。
进程创建
- Linux进程创建: 通过fork()系统调用创建进程
- Linux用户级线程创建:通过pthread库中的pthread_create()创建线程
- Linux内核线程创建: 通过kthread_create()
Linux线程,也并非”轻量级进程”,在Linux看来线程是一种进程间共享资源的方式,线程可看做是跟其他进程共享资源的进程。
fork, vfork, clone根据不同参数调用do_fork
- pthread_create: flags参数为 CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND
- fork: flags参数为 SIGCHLD
- vfork: flags参数为 CLONE_VFORK, CLONE_VM, SIGCHLD
Fork流程图
进程/线程创建的方法fork(),pthread_create(),最终在linux都是调用do_fork方法。 当然还有vfork其实也是一样的, 通过系统调用到sys_vfork,然后再调用do_fork方法,该方法 现在很少使用,所以下图省略该方法。

fork执行流程:
1. 用户空间调用fork()方法;
2. 经过syscall陷入内核空间, 内核根据系统调用号找到相应的sys_fork系统调用;
3. sys_fork()过程会在调用do_fork(), 该方法参数有一个flags很重要, 代表的是父子进程之间需要共享的资源; 对于进程创建flags=SIGCHLD, 即当子进程退出时向父进程发送SIGCHLD信号;
4. do_fork(),会进行一些check过程,之后便是进入核心方法copy_process.
flags参数
进程与线程最大的区别在于资源是否共享,线程间共享的资源主要包括内存地址空间,文件系统,已打开文件,信号等信息, 如下图蓝色部分的flags便是线程创建过程所必需的参数。

fork采用Copy on Write机制,父子进程共用同一块内存,只有当父进程或者子进程执行写操作时会拷贝一份新内存。 另外,创建进程也是有可能失败,比如进程个数达到系统上限(32768)或者系统可用内存不足。

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2025-12-11 16:22
被A0tem编辑
,原因: