hook技术的实际使用(面对经过混淆的APK) hook获取函数及返回值 以hook工具frida举例,hook的难点主要在于逆向代码,需要知道APK包名以及所要hook的类,之后就能使用Javause()来调用这个类。
frida主要能获取java类中的函数的参数值以及返回值,还有在类中定义的变量
举一个函数作为例子
1 2 3 4 5 class d { public static int dA (int a,int b) { return a+b; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Java.perform(function ( ) { try { console .log("star hook!" ); var classf = Java.use("com.a.b.c.d" ); classf.dA.implementation = function (p1,p2 ) { console .log("--------------------------------" ); console .log("function a hook" ); console .log(JSON .stringify(p1)); console .log(JSON .stringify(p2)); var result=classf.dA(p1,p2); console .log("--------------------------------" ); return result; }; }catch (e){ console .log("ERROR!" ); console .log(e); } });
像上面这个js程序,就能够打印出dA这个函数的参数以及返回值了。像这里的com.a.b.c.d就是经过混淆后的包名和类名,在实际hook中,以apk中的包名和类名为准,而不是以源码为准。
当然还需要一个python程序来调用这个js脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import fridaimport osimport sysreload(sys) sys.setdefaultencoding('utf-8' ) os.system("adb forward tcp:27042 tcp:27042" ) os.system("adb forward tcp:27043 tcp:27043" ) output = os.popen('adb shell ps |grep testapk' ) info = output.read() output.close() print(info) pid=0 for line in info.splitlines(): if line.__contains__("system" ): item = line.split(" " ) for i in item[1 :]: if (len(i)>1 ): print(i) pid=int(i) break rdev = frida.get_remote_device() session = rdev.attach(pid) with open("test.js" ) as f://test.js是实际hook手机程序的js脚本文件名 src = f.read() script = session.create_script(src.decode("utf-8" )) def on_message (message, data) : print(message) script.on("message" ,on_message) script.load()
hook的函数没有运行 在实际hook中,可能hook的是通信过程中的加密或解密函数,像我们这么写的python脚本运行几秒就会结束,在这点时间内如果加密或解密函数没有运行,那就白跑了,什么数据都抓不到。
第一种方法:
在python脚本底部增加
这样在python脚本等待输入的时候,只要hook的函数有运行到,那就会打印出参数和返回值
第二种方法:
用RPC远程调用函数,RPC可以不管目标函数是否有调用,从而强行去调用它
在js脚本中可以这么写
1 2 3 4 5 6 rpc.exports = { myfunc: function (a,b ) { Java.perform(function ( ) { });
在python中可以在 script.load()
之后添加 script.exports.myfunc(a,b)
从而调用这个函数
其它 frida编写js脚本的时候还有一些需要注意的点,比如java中私有函数和开放函数的时候返回值就不一样,前者是 return this.dA(p1,p2);
后者是return classf.dA(p1,p2);
在类中的变量可以直接用class.value来调用,就跟调用函数一样。
遗留问题:目前还是不知道怎么打印出函数内的局部变量
参考 https://www.freebuf.com/articles/system/190565.html 一篇文章带你领悟Frida的精髓(基于安卓8.1)
https://mabin004.github.io/2018/02/08/frida%E5%AF%BC%E5%87%BA%E5%87%BD%E6%95%B0%E4%BB%BB%E6%84%8F%E8%B0%83%E7%94%A8/ frida导出函数任意调用
https://blog.csdn.net/jiangwei0910410003/article/details/80372118 Android逆向之旅—Hook神器家族的Frida工具使用详解
评论加载中