版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
Frida 反汇编
Frida 提供了反汇编 API,主要用于对目标进程的代码进行动态分析,例如:
-
获取函数的机器代码并将其反汇编为汇编指令。
-
分析内存中的指令流。
这些功能在 Frida 的 Instruction 类中实现,基于 Capstone 实现的反汇编功能。
https://frida.re/docs/javascript-api/#instruction
比如,可以通过 Instruction.parse 方法反汇编指定地址的汇编信息
[Remote::AndroidExample]-> Instruction.parse(ptr("0x7e7acdb9a0"));
{
"address": "0x7e7acdb9a0",
"groups": [],
"mnemonic": "sub",
"next": "0x7e7acdb9a4",
"opStr": "sp, sp, #0x10",
"operands": [
{
"type": "reg",
"value": "sp"
},
{
"type": "reg",
"value": "sp"
},
{
"type": "imm",
"value": "16"
}
],
"regsRead": [],
"regsWritten": [],
"size": 4
}
Android 示例代码
定义一个 native 函数 add,计算 1+ 1 + 1 并返回结果。
把 add 函数动态注册到 com.cyrus.example.frida.disassemble.FridaDisassembleActivity#add。
#include <jni.h>
#include <android/log.h>
#define LOG_TAG "FridaDisassemble"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
// 实现 add 方法:计算 1 + 1 + 1
jint native_add(JNIEnv *env, jobject obj) {
return 1 + 1 + 1;
}
// 定义 JNI 方法映射
static const JNINativeMethod methods[] = {
{"add", "()I", (void *)native_add} // 方法名, 方法签名, C++函数指针
};
// 动态注册 JNI 方法
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
// 获取 Java 类
jclass clazz = env->FindClass("com/cyrus/example/frida/disassemble/FridaDisassembleActivity");
if (clazz == nullptr) {
LOGD("[-] Failed to find class FridaDisassembleActivity");
return JNI_ERR;
}
// 注册 native 方法
if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
LOGD("[-] Failed to register native methods");
return JNI_ERR;
}
LOGD("[+] Successfully registered native methods");
return JNI_VERSION_1_6;
}
在 kotlin 层调用 add 函数并 toast 结果。
// 调用 native 方法
val result = add()
// 显示 Toast
Toast.makeText(this, "add() returned: $result", Toast.LENGTH_LONG).show()
当点击按钮可以看到返回结果 3。
接下来通过 Frida 实现:
-
找到 add 函数动态注册的地址
-
反汇编 add 函数机器码
-
patch add 函数汇编指令修改返回结果
JNI 方法地址跟踪
1. 启动 Frida Server
# 启用超级管理员
adb root
# 进入命令行
adb shell
# 启动frida-server,并指定端口
/data/local/tmp/fs -l 0.0.0.0:1234
# 端口转发到本地
adb forward tcp:1234 tcp:1234
Frida 的详细使用参考这篇文章: