安卓逆向_24 ( 二 ) --- frida 学习记录

 

转载:看雪论坛 堂前燕 :https://bbs.pediy.com/thread-252319.htm

apk 和 Python脚本 链接:https://pan.baidu.com/s/1KX1fY16NgaYB1FnCrpu0lQ    提取码:t38k 

 

上次记录了下xposed hook java层的学习,这次记录下frida

例子是在上次写的apk上稍加改动,添加几个简单的native方法;

 

 

MainActivity

 

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button bt=(Button)findViewById(R.id.bt1);bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {HookGoal h=new HookGoal(0);h.editnum(1);Log.i("jni str",h.strtest("abcdefg"));DiyClass[] array={new DiyClass(1),new DiyClass(2)};Log.i("jni array","jni调用前 参数数组 成员0: "+array[0].getData()+" 成员1: "+array[1].getData());DiyClass[] myarray=h.arraytest(array);Log.i("jni array","jni调用后 返回新数组 成员0: "+myarray[0].getData()+" 成员1: "+myarray[1].getData());h.show();TextView t=(TextView)findViewById(R.id.sample_text);//t.setText("ooo");t.setText(h.sayhello());//Log.i("jni ","");Toast.makeText(MainActivity.this,"HOOKGOAL",Toast.LENGTH_LONG).show();}});}
}

 

 

类文件

 

abstract class person {public int age = 0;public void eat(String food) {}
}public class HookGoal {static {System.loadLibrary("native-lib");}private static String TAG = "HookGoal:";private  int hookGoalNumber;public HookGoal(int number) {hookGoalNumber = number;Log.i(TAG, "HookGoal hookGoalNumber:" + hookGoalNumber);}public void func0() {Log.i(TAG, "welcome");}private void func1() {new person() {@Overridepublic void eat(String food) {Log.i(TAG, "eat " + food);}}.eat("apple");}private static void func2(String s) {Log.i(TAG, "func2 " + s);}private void func3(DiyClass[] arry) {for (int i = 0; i < arry.length; i++)Log.i(TAG, "DiyClass[" + i + "].getData:" + arry[i].getData());}private class InnerClass {private int innerNumber;public InnerClass(String s) {innerNumber = 0;Log.i(TAG, "InnerClass 构造函数 " + s);Log.i(TAG, "InnerClass innerNumber:" + innerNumber);}private void innerFunc(String s) {Log.i(TAG, "InnerClass innerFunc " + s);}}public native String sayhello();public native String strtest(String s);public native DiyClass[] arraytest(DiyClass[] array);public native void editnum(int n);public void show() {Log.i(TAG,"hookGoalNumber:"+hookGoalNumber);func1();func2("私有静态方法");DiyClass[] arry = {new DiyClass(0), new DiyClass(0), new DiyClass(0)};func3(arry);InnerClass inner = new InnerClass("私有内部类");inner.innerFunc("内部类方法调用");}}public class DiyClass{private int data;public DiyClass(int data){this.data=data;}public int getData() {return data;}public void setData(int data) {this.data = data;}
}

 

 

native方法,动态注册

 

int add(int a,int b){return a+b;
}static jstring say(JNIEnv *env, jobject) {LOGI("native 函数say()返回字符串my jni hhh");string hello = "my jni hhh";return env->NewStringUTF(hello.c_str());
}
static jstring mystr(JNIEnv *env, jobject,jstring s) {char buf[256];env->GetStringUTFRegion(s,0,env->GetStringLength(s),buf);LOGI("GetStringUTFRegion 截取jstring保存到本地buf中:%s",buf);const char* ptr_c=env->GetStringUTFChars(s,NULL);LOGI("GetStringUTFChars 返回const char* 类型:%s",ptr_c);env->ReleaseStringUTFChars(s,ptr_c);const jchar *wc=env->GetStringChars(s, NULL);LOGI("GetStringChars 返回const jchar* 类型");env->ReleaseStringChars(s,wc);jstring js=env->NewStringUTF(buf);
/*  jstring NewStringUTF(const char* bytes)   返回jstring类型访问java.lang.String对应的JNI类型jstring时,不能像访问基本数据类型一样直接使用,因为它在Java是一个引用类型,所以在本地代码中只能通过GetStringUTFChars这样的JNI函数来访问字符串的内容*/LOGI("NewStringUTF(buf) 返回jstring类型:%s",env->GetStringUTFChars(js,NULL));return env->NewString(wc,env->GetStringLength(s));
}
static void edit(JNIEnv *env, jobject obj,jint n) {jint x=add(n,n);LOGI("edit()内调用了add(),原参数:%d",n);jclass clazz=env->GetObjectClass(obj);jfieldID numberid=env->GetFieldID(clazz,"hookGoalNumber","I");env->SetIntField(obj,numberid,x);LOGI("edit()内设置hookGoalNumber字段为:%d",x);}
static jobjectArray myarray(JNIEnv *env, jobject obj,jobjectArray array){jclass diyclass=env->FindClass("com/example/goal/DiyClass");jmethodID initid=env->GetMethodID(diyclass,"<init>","(I)V");jmethodID getdataid=env->GetMethodID(diyclass,"getData","()I");jobject a=env->GetObjectArrayElement(array,0);jobject a1=env->GetObjectArrayElement(array,1);jint d=env->CallIntMethod(a,getdataid);jint d1=env->CallIntMethod(a1,getdataid);jobject diy=env->NewObject(diyclass,initid,d);jobject diy2=env->NewObject(diyclass,initid,d1);jobjectArray myarray=env->NewObjectArray(2,diyclass,0);env->SetObjectArrayElement(myarray,0,diy2);env->SetObjectArrayElement(myarray,1,diy);LOGI("myarray()使用array参数,返回交换元素位置的新数组");return myarray;
//    return env->NewObjectArray(2,diyclass,diy2);}static const char *className = "com/example/goal/HookGoal";static JNINativeMethod gJni_Methods_table[] = {{"editnum", "(I)V", (void*)edit},{"sayhello", "()Ljava/lang/String;",(void*)say},{"strtest", "(Ljava/lang/String;)Ljava/lang/String;",(void*)mystr},{"arraytest","([Lcom/example/goal/DiyClass;)[Lcom/example/goal/DiyClass;",(void*)myarray}};static int jniRegisterNativeMethods(JNIEnv* env, const char* className,const JNINativeMethod* gMethods, int numMethods)
{jclass clazz;clazz = (env)->FindClass( className);if (clazz == NULL) {return -1;}int result = 0;if ((env)->RegisterNatives(clazz, gJni_Methods_table, numMethods) < 0) {result = -1;}(env)->DeleteLocalRef(clazz);return result;
}jint JNI_OnLoad(JavaVM* vm, void* reserved){JNIEnv* env = NULL;jint result = -1;if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {return result;}jniRegisterNativeMethods(env, className, gJni_Methods_table, sizeof(gJni_Methods_table) / sizeof(JNINativeMethod));return JNI_VERSION_1_4;
}

 

 

开始 frida hook

 

首先是 java 层 hook

setImmediate(function () {Java.perform(function () {console.log("start");//java层hookvar hookgoal = Java.use("com.example.goal.HookGoal");var clazz = Java.use("java.lang.Class");var obj = Java.use("java.lang.Object");var Exception = Java.use("java.lang.Exception");var str = Java.use("java.lang.String");//hook 构造方法hookgoal.$init.overload("int").implementation = function (number) {send("HookGoal构造函数的参数number:" + number);send("HookGoal构造函数的参数修改为666");return this.$init(666);};//hook 静态变量TAGvar reflectField = Java.cast(hookgoal.class, clazz).getDeclaredField("TAG");reflectField.setAccessible(true);reflectField.set("java.lang.String", "frida hooking");send("修改HookGoal的静态变量TAG为:frida hooking");//实例化对象way1var newhg = hookgoal.$new(0);send("new HookGoal instance newhg: " + newhg);// 实例化对象way2var newhg1 = hookgoal.$new.overload("int").call(hookgoal, 0);send("new HookGoal instance newhg1: " + newhg1);//hook匿名内部类,修改参数var nminner = Java.use("com.example.goal.HookGoal$1");nminner.eat.overload("java.lang.String").implementation = function (s) {var arg = arguments[0];send("eat参数获取 way1:" + arg);send("eat参数获取 way2:" + s);//修改参数return this.eat("is hooking");};var diy = Java.use("com.example.goal.DiyClass");hookgoal.func2.implementation = function (s) {//func2为静态方法var arg = arguments[0];send("func2()参数获取:" + s);//调用成员方法func0()在静态方法内只能通过创建的实例访问newhg.func0();send("func2()内调用func0()  通过创建实例newhg调用");newhg1.func0();send("func2()内调用func0()  通过创建实例newhg1调用");//修改实例的hookGoalNumber值,前面hook构造函数时已经将值改为666//修改字段值 通过反射得到字段,//var num1 = Java.cast(newhg1.getClass(), clazz).getDeclaredField("hookGoalNumber");var num1 = Java.cast(hookgoal.class, clazz).getDeclaredField("hookGoalNumber");num1.setAccessible(true);send("实例newhg1的hookGoalNumber:" + num1.get(newhg1));num1.setInt(newhg1, 777);send("修改实例newhg1的hookGoalNumber:" + num1.get(newhg1));send("实例newhg的hookGoalNumber:" + num1.get(newhg));// 反射调用方法var func = hookgoal.class.getDeclaredMethod("func0", null);send("func0:" + func);//var funcs = hookgoal.class.getDeclaredMethods();//for(var i=0;i<funcs.length;i++)//    send(""+i+" "+funcs[i]);//invoke(instance,args)调用成员方法func.invoke(newhg1, null);send("func2()内调用func0()  way2 通过反射调用");//调用DiyClass内的getData()var d = diy.$new(666);var x = d.getData();send("func2()内调用DiyClass下的getData() 通过创建实例d调用 返回:" + x);//修改func2的参数return this.func2("is hooking");};//修改func3参数hookgoal.func3.implementation = function (array) {//在成员方法func3内调用func0()this.func0();send("func3()内调用func0()  way2 成员方法中直接调用其他成员方法");//修改数组参数send("func3参数:" + array);var a = Java.array("com.example.goal.DiyClass", [diy.$new(111), diy.$new(222), diy.$new(333)]);send("func3参数修改:" + a);return this.func3(a);};var inner = Java.use("com.example.goal.HookGoal$InnerClass");//hook内部类inner.$init.overload("com.example.goal.HookGoal", "java.lang.String").implementation = function (clas, arg) {send("innerClass构造函数的参数:" + arg);return this.$init(clas, "frida is hooking");};//hook 内部类方法inner.innerFunc.implementation = function (s) {send("frida hook 前innerFunc()的参数:" + arguments[0]);var num = inner.class.getDeclaredField("innerNumber");num.setAccessible(true);//内部类成员方法中修改成员属性,way1 通过this.xxx.value 访问、修改send("通过this.innerNumber.value获取值:" + this.innerNumber.value);this.innerNumber.value = 1;send("通过this.innerNumber.value设置值后:" + this.innerNumber.value);//way2 先通过反射得到字段,send("反射方式 innerNumber修改前:" + num.get(this));num.setInt(this, 2);send("反射方式 innerNumber修改后:" + num.get(this));return this.innerFunc("frida is hooking");};

 

 

native 层 hook

 //so层hook//导出函数//var exports = Module.enumerateExportsSync("libnative-lib.so");//for(var i=0;i<exports.length;i++){//    send("name:"+exports[i].name+"  address:"+exports[i].address);// }//遍历模块找基址Process.enumerateModules({onMatch: function (exp) {if (exp.name == 'libnative-lib.so') {send('enumerateModules find');send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);send(exp);return 'stop';}},onComplete: function () {send('enumerateModules stop');}});//通过模块名直接查找基址var soAddr = Module.findBaseAddress("libnative-lib.so");send("soAddr:" + soAddr);//   hook导出函数 通过函数名send("findExportByName add():" + Module.findExportByName("libnative-lib.so", "_Z3addii"));//send("findExportByName edit():"+Module.findExportByName("libnative-lib.so", "_ZL4editP7_JNIEnvP8_jobjecti"))// Interceptor.attach(Module.findExportByName("xxx.so", "xxxx"), {//     onEnter: function (args) {//         send("open(" + Memory.readCString(args[0]) + "," + args[1] + ")");//     },//     onLeave: function (retval) {////     }// });//say(JNIEnv *env, jobject)//edit(JNIEnv *env, jobject,int)//mystr(JNIEnv *env, jobject,jstring s)//myarray(JNIEnv *env, jobject obj, jobjectArray array)// arm64-v8a 下地址//var fadd = 0xED7C;//var fsay=0xF12C;//var fedit=0xF04C;//var fmystr=0xF328;//var fmyarray=0xF4DC;//下面为x86模拟器中地址偏移  arm真机下thumb指令下地址+1var fadd = 0x8AD0;var fsay = 0x8FA0;var fedit = 0x8E70;var fmystr = 0x9200;var fmyarray = 0x9420;//armeabi-v7a//var fadd = 0x839C;var faddptr = new NativePointer(soAddr).add(fadd);//得到内存地址send("函数add() faddptr:" + faddptr);//调用add(5,6)var funadd = new NativeFunction(faddptr, "int", ['int', 'int']);var t = funadd(5, 6);send("调用native 方法fun():" + t);Interceptor.attach(faddptr, {onEnter: function (args) {send("onEnter add()");x = args[0];y = args[1];args[0] = ptr(x * 2);args[1] = ptr(y * 2);send("hook add()修改参数为原来的两倍 args[0]:" + args[0].toInt32() + "  args[1]:" + args[1].toInt32());},onLeave: function (retval) {send("onLeave  add()");//retval.replace(678);//send("add()修改返回值为:"+retval.toInt32())}});var fsayptr = new NativePointer(soAddr).add(fsay);Interceptor.attach(fsayptr, {onEnter: function (args) {send("onEnter say()");},onLeave: function (retval) {send("onLeave say()");//jstring类型无法直接输出显示,可以类型转换到java.lang.Stringvar s = Java.cast(retval, str);send("say() 原返回值:" + s);//调用env下的方法,构造jstring类型var env = Java.vm.getEnv();var jstring = env.newStringUtf("frida hook native");retval.replace(ptr(jstring));send("修改say()返回值:" + Java.cast(jstring, str));}});var feditptr = new NativePointer(soAddr).add(fedit);Interceptor.attach(feditptr, {onEnter: function (args) {send("onEnter edit()");send("edit() env:" + args[0] + "  jobject:" + args[1] + " jint:" + args[2].toInt32());//参数修改使用new NativePointer(s)  简写ptr(s)args[2] = ptr(4);send("hook edit() 修改后的参数jint:" + args[2]);},onLeave: function (retval) {send("onLeave edit()");}});var fmystrptr = new NativePointer(soAddr).add(fmystr);send("fmystrptr:" + fmystrptr);Interceptor.attach(fmystrptr, {onEnter: function (args) {send("onEnter mystr()");send("mystr() env:" + args[0] + "  jobject:" + args[1] + " jstring:" + args[2]);var s = Java.cast(args[2], str);send("mystr() jstring参数:" + s);//send("mystr:"+Memory.readUtf16String(args[2],7));//send("mystr:"+Memory.readUtf8String(args[2],7));},onLeave: function (retval) {send("onLeave mystr()");var env = Java.vm.getEnv();var jstring = env.newStringUtf("frida hook native");send("修改返回值jstring:" + jstring);retval.replace(ptr(jstring));}});// Java.choose("com.example.goal.DiyClass",{//     onMatch:function(instance){//         send("DiyClass instance:"+instance);//     },//     onComplete:function(){////     }//// });var fmyarrayptr = ptr(soAddr).add(fmyarray);//var fmyarrayptr = new NativePointer(soAddr).add(fmyarray);send("fmyarrayptr:" + fmyarrayptr);//var argptr;Interceptor.attach(fmyarrayptr, {onEnter: function (args) {send("onEnter myarray()");send("mystr() env:" + args[0] + "  jobject:" + args[1] + " jobjectArray:" + args[2]);send("jobjectArray参数:" + args[2].toString());//可以在onEnter中通过this.xxx保存变量 在onLeave中通过this.xxx读取this.argptr = args[2]//jstring 不同于wchar_t* (jchar*) 与 char*//send("mystr:"+Memory.readUtf16String(args[2],7));//send("mystr:"+Memory.readUtf8String(args[2],7));},onLeave: function (retval) {send("onLeave myarray()");send("argptr:" + this.argptr);var env = Java.vm.getEnv();var cla = env.findClass("com/example/goal/DiyClass");send("clazz:" + cla);var initid = env.getMethodId(cla, "<init>", "(I)V");send("initid:" + initid);var setid = env.getMethodId(cla, "setData", "(I)V");send("setid:" + setid);var getid = env.getMethodId(cla, "getData", "()I");send("getid:" + getid);//frida 中env 方法参考frida-java/lib/env.js  本人能力有限,有些方法确实搞不懂//调用env中的allocObject()方法创建对象,未初始化,var obj1 = env.allocObject(cla);send("obj1:" + obj1);var obj2 = env.allocObject(cla);send("obj2:" + obj2);var rtarray = env.newObjectArray(2, cla, ptr(0));send("env.newObjectArray:" + rtarray);//获取DiyClass类中public void setData(int data)方法var nvmethod = env.nonvirtualVaMethod("void", ["int"]);//NativeType CallNonvirtual<type>Method(JNIEnv *env, jobject obj,jclass clazz, jmethodID methodID, ...);//设置obj1中data值nvmethod(env, obj1, cla, setid, 11);//设置obj2中data值nvmethod(env, obj2, cla, setid, 22);send("env.nonvirtualVaMethod(JNIEnv,jobject,jclass,jmethodid,args):" + nvmethod);//设置数组中的元素env.setObjectArrayElement(rtarray, 0, obj1);env.setObjectArrayElement(rtarray, 1, obj2);send("env.newObjectArray:" + rtarray);send("原retval:" + retval);retval.replace(ptr(rtarray));send("修改后retval:" + retval);// //堆中分配空间// var memo=Memory.alloc(4);// //写入数据// Memory.writeInt(memo,0x40302010);// // 读取数据// console.log(hexdump(memo, {//         offset: 0,//         length: 64,//         header: true,//         ansi: true// }));}});});
});

 

 

写好的 js 放到 python 执行

import frida, sysdef on_message(message, data):if message['type'] == 'send':print("[*] {0}".format(message['payload']))else:print(message)jscode = """
<js代码放到这里>"""
# 启动时hook   //在测试时出现了问题
# devices=frida.get_usb_device()
# pid=devices.spawn(['com.example.goal'])   #以挂起方式创建进程 真机报错frida.PermissionDeniedError: unable to access  process
#找到原因了,我的是Android8.0 使用了Magisk,默认开启了Magisk Hide选项与zygote64冲突。
#解决方法:Magisk   -->设置-->Magisk下 去掉勾选Magisk Hide #模拟器报错Failed to spawn: the connection is closed
# session=devices.attach(pid)
# devices.resume(pid)    #创建完脚本, 恢复进程运行
# script=session.create_script(jscode)# 命令行frida -U -f com.example.goal --no-pause -l <hook.js># 运行中hook
process = frida.get_usb_device().attach('com.example.goal')
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running test')
script.load()
sys.stdin.read()

也可以使用 frida 命令行 打开 .js  (打印使用 console.log() )

frida -U <进程名或pid> -l <js文件>

 

代码中涉及到的一些点大部分给出了注释,当然你只能这里看到一丢丢的 frida 方法的使用,更多的方法还要请参考官方文档、源代码···

例如native层会用到大量frida JavaScript API 的Memory 操作,

frida中的env方法与jni开发中的方法并不完全相同,请参考源码frida-java/lib/env.js,

代码中涉及到的地址偏移请根据实际情况修改

 

 

hook 前 log 输出

4513-4513/com.example.goal I/frida hooking: HookGoal hookGoalNumber:0
4513-4513/com.example.goal I/jni test: edit()内调用了add(),原参数:1
4513-4513/com.example.goal I/jni test: edit()内设置hookGoalNumber字段为:2
4513-4513/com.example.goal I/jni test: GetStringUTFRegion 截取jstring保存到本地buf中:abcdefg
4513-4513/com.example.goal I/jni test: GetStringUTFChars 返回const char* 类型:abcdefg
4513-4513/com.example.goal I/jni test: GetStringChars 返回const jchar* 类型
4513-4513/com.example.goal I/jni str: abcdefg
4513-4513/com.example.goal I/jni array: jni调用前 参数数组 成员0: 1 成员1: 2
4513-4513/com.example.goal I/jni test: myarray()使用array参数,返回交换元素位置的新数组
4513-4513/com.example.goal I/jni array: jni调用后 返回新数组 成员0: 2 成员1: 1
4513-4513/com.example.goal I/frida hooking: hookGoalNumber:2
4513-4513/com.example.goal I/frida hooking: eat apple
4513-4513/com.example.goal I/frida hooking: func2 私有静态方法
4513-4513/com.example.goal I/frida hooking: DiyClass[0].getData:0
4513-4513/com.example.goal I/frida hooking: DiyClass[1].getData:0
4513-4513/com.example.goal I/frida hooking: DiyClass[2].getData:0
4513-4513/com.example.goal I/frida hooking: InnerClass 构造函数 私有内部类
4513-4513/com.example.goal I/frida hooking: InnerClass innerNumber:0
4513-4513/com.example.goal I/frida hooking: InnerClass innerFunc 内部类方法调用
4513-4513/com.example.goal I/jni test: native 函数say()返回字符串my jni hhh

 

hoo k后 log 输出

4513-4513/com.example.goal I/frida hooking: HookGoal hookGoalNumber:666
4513-4513/com.example.goal I/jni test: edit()内调用了add(),原参数:4
4513-4513/com.example.goal I/jni test: edit()内设置hookGoalNumber字段为:16
4513-4513/com.example.goal I/jni test: GetStringUTFRegion 截取jstring保存到本地buf中:abcdefg
4513-4513/com.example.goal I/jni test: GetStringUTFChars 返回const char* 类型:abcdefg
4513-4513/com.example.goal I/jni test: GetStringChars 返回const jchar* 类型
4513-4513/com.example.goal I/jni str: frida hook native
4513-4513/com.example.goal I/jni array: jni调用前 参数数组 成员0: 1 成员1: 2
4513-4513/com.example.goal I/jni test: myarray()使用array参数,返回交换元素位置的新数组
4513-4513/com.example.goal I/jni array: jni调用后 返回新数组 成员0: 11 成员1: 22
4513-4513/com.example.goal I/frida hooking: hookGoalNumber:16
4513-4513/com.example.goal I/frida hooking: eat is hooking
4513-4513/com.example.goal I/frida hooking: welcome
4513-4513/com.example.goal I/frida hooking: welcome
4513-4513/com.example.goal I/frida hooking: welcome
4513-4513/com.example.goal I/frida hooking: func2 is hooking
4513-4513/com.example.goal I/frida hooking: welcome
4513-4513/com.example.goal I/frida hooking: DiyClass[0].getData:111
4513-4513/com.example.goal I/frida hooking: DiyClass[1].getData:222
4513-4513/com.example.goal I/frida hooking: DiyClass[2].getData:333
4513-4513/com.example.goal I/frida hooking: InnerClass 构造函数 frida is hooking
4513-4513/com.example.goal I/frida hooking: InnerClass innerNumber:0
4513-4513/com.example.goal I/frida hooking: InnerClass innerFunc frida is hooking
4513-4513/com.example.goal I/jni test: native 函数say()返回字符串my jni hhh

 

 

hook 脚本的输出

[*] Running test
start
[*] 修改HookGoal的静态变量TAG为:frida hooking
[*] HookGoal构造函数的参数number:0
[*] HookGoal构造函数的参数修改为666
[*] new HookGoal instance newhg: com.example.goal.HookGoal@4a854cb4
[*] HookGoal构造函数的参数number:0
[*] HookGoal构造函数的参数修改为666
[*] new HookGoal instance newhg1: com.example.goal.HookGoal@4a854f70
[*] enumerateModules find
[*] libnative-lib.so|0x7d0b0000|221184|/data/app-lib/com.example.goal-1/libnative-lib.so
[*] {'name': 'libnative-lib.so', 'base': '0x7d0b0000', 'size': 221184, 'path': '/data/app-lib/com.example.goal-1/libnative-lib.so'}
[*] enumerateModules stop
[*] soAddr:0x7d0b0000
[*] 函数add() nativeptr:0x7d0b8ad0
[*] 调用native 方法fun():11
[*] findExportByName add():0x7d0b8ad0
[*] fmystrptr:0x7d0b9200
[*] fmyarrayptr:0x7d0b9420
[*] HookGoal构造函数的参数number:0
[*] HookGoal构造函数的参数修改为666
[*] onEnter edit()
[*] edit() env:0xb83a6e50  jobject:0xf7c00025 jint:1
[*] hook edit() 修改后的参数jint:0x4
[*] onEnter add()
[*] hook add()修改参数为原来的两倍 args[0]:8  args[1]:8
[*] onLeave  add()
[*] onLeave edit()
[*] onEnter mystr()
[*] mystr() env:0xb83a6e50  jobject:0xf7d00025 jstring:0x3d300029
[*] mystr() jstring参数:abcdefg
[*] onLeave mystr()
[*] 修改返回值jstring:0xc5b00035
[*] onEnter myarray()
[*] mystr() env:0xb83a6e50  jobject:0xf8000025 jobjectArray:0x3d600029
[*] jobjectArray参数:0x3d600029
[*] onLeave myarray()
[*] argptr:0x3d600029
[*] clazz:0x26800045
[*] initid:0x881d1ea8
[*] setid:0x881d1f20
[*] getid:0x881d1ee8
[*] obj1:0x1e000049
[*] obj2:0x1e00004d
[*] env.newObjectArray:0x1dc00051
[*] env.nonvirtualVaMethod(JNIEnv,jobject,jclass,jmethodid,args):0xb4d88bb0
[*] env.newObjectArray:0x1dc00051
[*] 原retval:0x2f900041
[*] 修改后retval:0x1dc00051
[*] eat参数获取 way1:apple
[*] eat参数获取 way2:apple
[*] func2()参数获取:私有静态方法
[*] func2()内调用func0()  通过创建实例newhg调用
[*] func2()内调用func0()  通过创建实例newhg1调用
[*] 实例newhg1的hookGoalNumber:666
[*] 修改实例newhg1的hookGoalNumber:777
[*] 实例newhg的hookGoalNumber:666
[*] func0:public void com.example.goal.HookGoal.func0()
[*] func2()内调用func0()  way2 通过反射调用
[*] func2()内调用DiyClass下的getData() 通过创建实例d调用 返回:666
[*] func3()内调用func0()  way2 成员方法中直接调用其他成员方法
[*] func3参数:com.example.goal.DiyClass@4a8596b4,com.example.goal.DiyClass@4a8596bc,com.example.goal.DiyClass@4a8596c4
[*] func3参数修改:com.example.goal.DiyClass@4a859a08,com.example.goal.DiyClass@4a859a78,com.example.goal.DiyClass@4a859ae8
[*] innerClass构造函数的参数:私有内部类
[*] frida hook 前innerFunc()的参数:内部类方法调用
[*] 通过this.innerNumber.value获取值:0
[*] 通过this.innerNumber.value设置值后:1
[*] 反射方式 innerNumber修改前:1
[*] 反射方式 innerNumber修改后:2
[*] onEnter say()
[*] onLeave say()
[*] say() 原返回值:my jni hhh
[*] 修改say()返回值:frida hook native

frida功能十分强大,在这里我作为初学者简单的记录了下学习经历,当然这仅仅是一些常规操作,是基础,日后的学习应该是在实战中,实践出真知。

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下

我在学习的过程之中也遇到了各种各样的坑,困惑过,苦恼过。解决问题绝对是一种很棒的学习方式,

希望各位能够提出自己的问题,大家一起交流,共同成长!

同时文中难免会有错误,欢迎各位坛友指出,不胜感激!

(打好基础,改日实战一番!)

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态 | DeepMind 首次披露旗下专利申请情况

来源&#xff1a;AI科技评论摘要&#xff1a;作为一家顶尖的人工智能研究公司&#xff0c;DeepMind 近年来申请了一堆国际专利&#xff0c;但是具体到专利内容和申请数量就不得而知了。近日&#xff0c;DeepMind首次披露了一系列国际专利&#xff0c;这些专利涉及了现代机器学习…

JavaScript获取URL参数

文件1&#xff1a;realwall.js (function(window){var urltool {getUrlParameterByKey : function(url,key){var result "",start,parameterStr,len,paras,i;parameterStr url.split("?");if(parameterStr.length > 1){parameterStr parameterStr[…

Frida Android hook

From&#xff1a;https://eternalsakura13.com/2020/07/04/frida/ 开发环境配置 ( IDE 智能提示 frida )&#xff1a; 下载 nodejs&#xff1a; https://nodejs.org/zh-cn/download/npm install types/frida-gum 见过的较好的frida笔记&#xff1a; https://kevinspider.gith…

寒武纪宣布完成B轮融资 整体估值达25亿美元

来源&#xff1a;网易智能摘要&#xff1a;6月20日&#xff0c;芯片领域公司寒武纪宣布完成数亿美元的B轮融资&#xff0c;由中国国有资本风险投资基金、国新启迪、国投创业、国新资本联合领投。中金资本、中信证券投资&金石投资、TCL资本、中科院科技成果转化基金跟投。原…

安卓模拟器 Genymotion 安装

Form&#xff1a;https://www.runoob.com/w3cnote/android-tutorial-genymotion-install.html Linux (Ubuntu) 下的 Android 模拟器&#xff1a;Genymotion&#xff1a;https://blog.csdn.net/qq_25978793/article/details/49923579 Android 模拟器 Genymotion 安装使用教程详解…

辩论届人机大战:IBM新AI完胜人类冠军!

来源&#xff1a;智东西导语&#xff1a;6月18日&#xff0c;IBM的AI系统Project Debater首次与人类进行现场公开辩论。Project Debater能够理解对方观点&#xff0c;并有针对性地做出清晰的反驳&#xff0c;最终成功战胜人类辩手。6月19日消息&#xff0c;美国时间6月18日&…

没有人能阻止程序员将电脑上的一切搬到网页上

操作系统模拟&#xff08;OS Simulator&#xff09; Web QQ Q版的界面&#xff0c;看起来大体上是模拟Mac OS而不是Windows&#xff0c;不过那些桌面Widget又是Windows的展品。也算是取各家所长。使用他的唯一理由可能就是在没有QQ的电脑上用QQ吧 Windows 3.1 Windows 95(感谢大…

一篇文章带你领悟 Frida 的精髓(基于安卓8.1)

转载&#xff08;一篇文章带你领悟Frida的精髓&#xff08;基于安卓8.1&#xff09;&#xff09;&#xff1a;https://www.freebuf.com/articles/system/190565.html 《Frida操作手册》&#xff1a;https://github.com/hookmaster/frida-all-in-one Frida github 地址&#x…

神经元之间是如何形成“社交网络”的

来源&#xff1a;中科院神经科学研究院摘要&#xff1a;我们的大脑中存在着亿万个神经元&#xff0c;在神经科学领域有一个非常重要的问题&#xff0c;就是一个神经元是如何在这亿万个神经元中选择与某一些神经元形成突触联系的。演讲者&#xff1a;中国科学院神经科学研究所徐…

WinForm 图片变灰方法

最近公司项目用到文件树&#xff0c;对于工程文件中不存在的文件&#xff0c;要给予灰色显示&#xff0c;如何让图片成灰色&#xff0c;在网上找了个效率较高的方法&#xff0c;很方便调用&#xff0c;故记录。 1 public Bitmap ExColorDepth(Image image) 2 { 3 …

《 FRIDA系列文章 》

转载&#xff1a;《FRIDA系列文章》github 地址&#xff1a;https://github.com/r0ysue/AndroidSecurityStudy 由 Frida 提供的很棒的 项目、库和工具的精选列表&#xff1a;https://github.com/dweinstein/awesome-frida 《Frida操作手册》&#xff1a;https://github.com/h…

毕马威:2018全球科技创新报告(附PDF下载)

来源&#xff1a;走向智能论坛摘要&#xff1a;日前&#xff0c;毕马威发布《2018全球科技创新报告》&#xff0c;报告显示&#xff0c;我们如今正处在一个科技创新爆发的时代&#xff0c;人工智能、机器人和物联网必将会影响全球的商业&#xff0c;那些不主动去抓住未来趋势的…

GWT(Google Web Tookit) Eclipse Plugin的zip下载地址(同时提供GWT Designer下载地址)

按照Eclipse Help->Install new software->....(这里是官方安装文档&#xff1a;http://code.google.com/intl/zh-CN/eclipse/docs/install-eclipse-3.6.html) 的方法安装失败&#xff0c;界面始终显示Pedding状态&#xff0c;很长时间都没反映&#xff0c;无奈之下&…

《卫报》长文解读机器的崛起:人类越来越无法掌控它们

来源&#xff1a;网易智能摘要&#xff1a;技术正开始以智能和不可预知的方式运作&#xff0c;连它的创造者都无法捉摸。正当机器越来越多地改变全球事件时&#xff0c;我们该如何重新控制它们呢&#xff1f;《卫报》网站今日撰文详述了机器的崛起。技术正开始以智能和不可预知…

Android 逆向分析大全

转载&#xff1a;Android 逆向分析大全&#xff1a;https://www.jianshu.com/p/a12d04fc748f 1. 概述 1.1 分析步骤 通用逆向分析步骤 1. 了解该模块正向编程相关方法2. 使用apktool解密apk&#xff0c;得到资源、jni模块等文件3. 从apk提取出dex文件&#xff0c;使用dex2jar转…

美国智库报告:自动驾驶对社会、经济与劳动力的影响

来源&#xff1a;资本实验室在过去几年中&#xff0c;从政府到企业&#xff0c;自动驾驶的开发和应用已经成为新的投入重点。自动驾驶汽车在道路安全、生产率、燃料消耗和自然环保等方面的预期进步也充分吸引了公众的想象力和注意力。SAFE&#xff08;Securing America’s Futu…

jQuery源码研究01

为了研究方便&#xff0c;我自己定义的jQuery对象改为xQuery,意思是扩展 jQuery. 首先jQuery整体的结构&#xff1a; 1 (function(window,undefined)2 {3 var xQuery (function(){});4 ....5 window.xQuery window.$ xQuery;6 })(window); 为什么jQuery要使用这样的结构呢&a…

一篇文章带你搞懂 DEX 文件的结构

From&#xff1a;https://blog.csdn.net/sinat_18268881/article/details/55832757 Dex文件格式详解&#xff1a;https://www.jianshu.com/p/f7f0a712ddfe dex文件解析(第三篇)&#xff1a;https://blog.csdn.net/tabactivity/article/details/78950379 深入理解DEX文件格式…

Google AI 研发医疗新模型,预测死亡率比医院高出10%

&#xfeff;&#xfeff;编译 | 姗姗出品 | 人工智能头条&#xff08;公众号ID&#xff1a;AI_Thinker&#xff09;摘要&#xff1a;Google 开发了一种新型算法——读取了这名女性的175,639个数据点——并对死亡风险进行了评估&#xff0c;结果为 19.9%。几天后这位女士去世了…

【Q】【poj 1144】【poj 1523】

割点问题 题目类型相同&#xff0c;于是放到一起写。套了个版就可以了。 贴出版吧&#xff0c;方便查找。 void dfs(int k, int fa){ int j, i, son 0; vis[k] 1; PreOrder[k] BackOrder[k] dfn ; for(i 0; i < adj[k].size(); i ){ j adj[k][i]; …