由于工作一直会遇到frida来执行各种Hook,现在梳理整个frida的相关使用场景。由于安装的资料以及文档网上已经特别多了,本系列教程忽略相关安装步骤。
编写Native程序
#include <jni.h>
#include <string>
#include <iostream>
#include <string>
extern "C" {
void *create_stdstr(char *data, int size) {
std::string *s = new std::string();
(*s).assign(data, size);
return s;
}
JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
return env->NewStringUTF(static_cast<const char *>(create_stdstr("abcd", 3)));
}
}
明确Hook目标
- hook stringFromJNI:需要打印方法返回值
- hook stringFromJNI:需要修改方法返回值
- hook create_stdstr:需要打印方法参数
- hook create_stdstr:需要修改方法参数
- hook create_stdstr:需要打印方法返回值
编写JS代码
function jstring2Str(jstring) {
var ret;
Java.perform(function () {
var String = Java.use("java.lang.String");
ret = Java.cast(jstring, String);
});
return ret;
}
Interceptor.attach(Module.findExportByName("libnative-lib.so", "Java_com_example_myapplication_MainActivity_stringFromJNI"), {
onEnter: function (args) {
console.log("stringFromJNI onEnter...");
},
onLeave: function (retval) {
console.log("stringFromJNI onLeave...");
//step1: 获取返回值
console.log("stringFromJNI 函数返回old值:", jstring2Str(retval));
//step2: 修改返回值
var env = Java.vm.getEnv();
var jstring = env.newStringUtf("new hello");
retval.replace(ptr(jstring));
console.log("stringFromJNI 函数返回new值:", jstring2Str(retval));
}
});
Interceptor.attach(Module.findExportByName("libnative-lib.so", "create_stdstr"), {
onEnter: function (args) {
console.log("create_stdstr onEnter...");
//step3: 打印参数
console.log("create_stdstr 参数一:", args[0].readUtf8String());
console.log("create_stdstr 参数二:", args[1].toInt32());
//step4: 修改参数
args[1] = ptr(2);
this.buf = Memory.alloc(1024);
Memory.writeUtf8String(this.buf, "hello");
args[0] = this.buf;
},
onLeave: function (aretval) {
console.log("create_stdstr onLeave...");
//step5: 获取返回值
console.log("create_stdstr 函数返回值:", aretval.readUtf8String());
}
});
frida调用
启动frida进行hook。
现在可以直观的看到frida调用Native方法调用成功。