我们自己写一个简单的app,java层调用so 方法返回的字符串打印输出,java层和c代码如下
public class TestUtil { static { System.loadLibrary("security"); } public static native String getSecretPro(int adam); }
#调用jni方法 LogUtil.e("adam",TestUtil.getSecretPro(23));
#C方法返回字符串 JNIEXPORT jstring JNICALL Java_com_adam_ndktest_TestUtil_getSecretPro (JNIEnv *env, jclass jobj, jint val){ return (*env)->NewStringUTF(env,"eveve"); }
打包生成apk,安装到手机
把libsecurity.so文件拖入ida分析,
由上图可知,Java_com_adam_ndktest_TestUtil_getSecretPro方法的偏移地址是0x630,字符串便宜地址是0x64f,那么我们用基址+偏移地址就是函数的绝对地址了,frida获取so的基地址方法如下:
var soAddr=Module.findBaseAddress("libsecurity.so");
Java_com_adam_ndktest_TestUtil_getSecretPro地址是soAddr+0x630:
var proAddr=soAddr.add(0x630 );
我们要直接hook返回值的话就是soAddr+0x64f地址对应的字符串 ,然后通过Memory.readUtf8String方法读取,更改返回值的话需要用到JNIEnv api的newStringUtf方法,完整的代码如下:
Java.perform(function () { // Memory.readUtf8String var mru8s = function(addr) {return Memory.readUtf8String(addr);}; var soAddr=Module.findBaseAddress("libsecurity.so"); console.log("soAddr:"+soAddr); var proAddr=soAddr.add(0x630); console.log("proAddr:"+proAddr); Interceptor.attach(proAddr, { onEnter: function (args) { console.log("-----华丽的分割线-----"); }, onLeave: function(retval){ var staddr=soAddr.add(0x64f); console.log(staddr); var nat=new NativePointer(staddr); console.log("nat:"+nat); console.log("str:"+mru8s(staddr)); //读取返回的字符串 //替换返回字符串 var env = Java.vm.getEnv(); var jstring = env.newStringUtf("lixiaopeng"); retval.replace(ptr(jstring)); send("retval:"+retval); } }); });
本文为Adamin90原创文章,转载无需和我联系,但请注明来自http://www.lixiaopeng.top
你的糖罐呢:wink~
2019-11-12 15:49:59 回复