Hook_Libart
libart.so
: 在 Android 5.0(Lollipop)及更高版本中,libart.so
是 Android 运行时(ART,Android Runtime)的核心组件,它取代了之前的 Dalvik 虚拟机。可以在 libart.so
里找到 JNI 相关的实现。
PS:在高于安卓10的系统里,so的路径是/apex/com.android.runtime/lib64/libart.so,低于10的则在system/lib64/libart.so
函数名称 | 参数 | 描述 | 返回值 |
---|---|---|---|
RegisterNatives |
JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods |
反注册类的本地方法。类将返回到链接或注册了本地方法函数前的状态。该函数不应在本地代码中使用。相反,它可以为某些程序提供一种重新加载和重新链接本地库的途径。 | 成功时返回0;失败时返回负数 |
GetStringUTFChars |
JNIEnv*env, jstring string, jboolean *isCopy |
通过JNIEnv接口指针调用,它将一个代表着Java虚拟机中的字符串jstring引用,转换成为一个UTF-8形式的C字符串 | - |
NewStringUTF |
JNIEnv *env, const char *bytes |
以字节为单位返回字符串的 UTF-8 长度 | 返回字符串的长度 |
FindClass |
JNIEnv *env, const char *name |
通过对象获取这个类。该函数比较简单,唯一注意的是对象不能为NULL,否则获取的class肯定返回也为NULL。 | - |
GetMethodID |
JNIEnv *env, jclass clazz, const char *name, const char *sig |
返回类或接口实例(非静态)方法的方法 ID。方法可在某个 clazz 的超类中定义,也可从 clazz 继承。GetMethodID() 可使未初始化的类初始化。 | 方法ID,如果找不到指定的方法,则为NULL |
GetStaticMethodID |
JNIEnv *env, jclass clazz, const char *name, const char *sig |
获取类对象的静态方法ID | 属性ID对象。如果操作失败,则返回NULL |
GetFieldID |
JNIEnv *env, jclass clazz, const char *name, const char *sig |
回Java类(非静态)域的属性ID。该域由其名称及签名指定。访问器函数的Get<type>Field 及 Set<type>Field 系列使用域 ID 检索对象域。GetFieldID() 不能用于获取数组的长度域。应使用GetArrayLength()。 |
- |
GetStaticFieldID |
JNIEnv *env,jclass clazz, const char *name, const char *sig |
获取类的静态域ID方法 | - |
Call<type>Method , Call<type>MethodA , Call<type>MethodV |
JNIEnv *env, jobject obj, jmethodID methodID, .../jvalue *args/va_list args |
这三个操作的方法用于从本地方法调用Java 实例方法。它们的差别仅在于向其所调用的方法传递参数时所用的机制。 | NativeType,具体的返回值取决于调用的类型 |
主要用得多的是hook_RegisterNatives.js:hook打印动态注册的函数
1 | ~ frida -U -f com.zj.wuaipojie -l .\hook_RegisterNatives.js |
hook_GetStringUTFChars
这个的坑点在于:有两个GetStringUTFChars地址,选择第一个就好(默认就变成hook第二个了),不行就通过上面的name.indexOf(“b1EE”) == -1过滤,或者下面添加break退出循环
1 | function hook_GetStringUTFChars() { |
运行实例:
1 | ~ frida -U wuaipojie -l .\hook_GetStringUTFChars.js |
Hook_Libc
libc.so
: 这是一个标准的 C 语言库,用于提供基本的系统调用和功能,如文件操作、字符串处理、内存分配等。在Android系统中,libc
是最基础的库之一。
hook_kill
1 | function replaceKILL() { |
1 | ~ frida -U wuaipojie -l .\hook_kill.js |
hook_pthread_create
下面反调试,应该是反调试的代码在pthread_create新建的线程中实现
下面只是进行输出,没有进行一些修改操作
1 | function hook_pthread_create(){ |
1 | ~ frida -U wuaipojie -l .\hook_libc.js |
hook_str_cmp
1 | function hook_strcmp() { |
1 | ~ frida -U wuaipojie -l .\hook_libc.js |
Hook_Libdl
libdl.so
是一个处理动态链接和加载的标准库,它提供了dlopen
、dlclose
、dlsym
等函数,用于在运行时动态地加载和使用共享库
别 | 函数名称 | 参数 | 描述 |
---|---|---|---|
动态链接库操作 | dlopen | const char *filename, int flag |
打开动态链接库文件 |
dlsym | void *handle, const char *symbol |
从动态链接库中获取符号地址 |
Hook_dlsym
获取jni静态注册方法地址
1 | function hook_dlsym() { |
1 | ~ frida -U wuaipojie -l .\hook_libdl.js |
Hook_Linker
Linker是Android系统动态库so的加载器/链接器,通过android源码分析 init 和 init_array 是在 callConstructor 中被调用的
hookInit和hookInitArray
frida的CModule是一个极其强大的模块,本文将使用CModule来完成init_array的信息输出
简单来说,就是借助CModule对soinfo结构体进行解析
经过对比分析历代soinfo结构体的定义,可以确定从Android 8 ~ 14,结构体中init_array的位置都很稳定
于是通过下面的头文件中提取必要的内容,在CModule中定义一个soinfo结构体,这样frida就能自动完成相关偏移的处理
http://aosp.app/android-14.0.0_r1/xref/bionic/libc/include/link.h
http://aosp.app/android-14.0.0_r1/xref/bionic/libc/kernel/uapi/asm-generic/int-ll64.h
http://aosp.app/android-14.0.0_r1/xref/bionic/libc/kernel/uapi/linux/elf.h
http://aosp.app/android-14.0.0_r1/xref/bionic/linker/linker_soinfo.h
接着定义一个函数,接受一个soinfo指针参数和一个callback函数,优雅地输出init_array信息
核心代码:
1 | function hook_call_constructors() { |
1 | ~ frida -U -f com.zj.wuaipojie -l .\hook_init.js |
frida_rpc
在 Frida 中,RPC(Remote Procedure Calls)是一种机制,允许你在 Frida 脚本和应用程序之间进行远程调用。通过 RPC,你可以在 Frida 脚本中定义函数,并在目标应用程序中调用这些函数,实现脚本和目标应用程序之间的交互。
下面是获取文字和图片url的js
1 | function get_url(){ |
先安装下面的库,frida-tools装过就不用装了,最好里面的frida版本跟server要对应上
1 | pip install frida-tools uvicorn fastapi requests |
uvicorn:uvicorn 是一个基于 ASGI(Asynchronous Server Gateway Interface)的 Web 服务器,用于运行基于 Python 的异步 Web 应用程序。它是一个轻量级、高性能的服务器,常用于部署和运行基于 ASGI 的 Web 框架,如 FastAPI。
fastapi:FastAPI 是一个现代、快速(高性能)、易于使用的 Python Web 框架,用于构建 Web API。它基于 ASGI 并利用 Python 类型提示(Type Hints)和异步特性,提供了强大的自动化文档生成、输入验证、序列化、依赖注入等功能。FastAPI 具有出色的性能和开发效率,被广泛应用于构建高性能的 Web 后端服务。
requests:requests 是一个流行的 Python HTTP 库,用于发送 HTTP 请求和处理响应。它简化了与 Web 服务进行交互的过程,提供了简洁的 API,支持常见的 HTTP 方法(GET、POST、PUT 等),并且可以方便地处理请求头、请求参数、Cookies 等内容。requests 是一个非常实用的工具,适用于各种 Web 开发场景。