Frida脚本
Frida脚本就是 利用Frida动静插桩框架,
应用Frida导出的 Api和办法,对 内存空间里的对象办法 进行 监控、批改和替换
的一段代码
Frida的Api是用 JavaScript实现的,
所以能够充分利用 JavaScript的匿名函数的劣势 以及 大量的Hook钩子函数 和 回调函数的 Api
-
1.在手机上应用Frida-Server运行起来
-
查看以后运行的App
frida-ps -U
-
-
2.Hook根底
import frida import sys # 获取手机设施 rdev = frida.get_remote_device() # 通过attach模式注入app session = rdev.attach("com.zdwh.wwdz") scr = """ function main(){ console.log('Frida script loads success.'); // Java.perform 将脚本的内容注入到Java运行库中 Java.perform(function () { // Java.user() 传入须要Hook的办法所在的类的类名(字符串类型) // 为Java类动静获取一个JavaScript Wrapper,艰深的了解为一个JavaScript对象 let b = Java.use("com.zdwh.wwdz.wwdznet.l.b"); // implementation 示意实现了b类的a办法,"=" 前面跟着匿名函数, // 通过this.a()从新执行原办法,前后能够console.log()输入解决前后的参数值 b.a.implementation = function(){ var result = this.a(); console.log(result); return result; } }); } setTimeout(main, 0); // 等同于setImmediate 立刻执行 """ script = session.create_script(scr) script.load() sys.stdin.read()
-
3.Java层被动调用
强制调用一个办法去执行 Java中包含静态方法、实例办法 1. 静态方法,间接应用Java.use() 找到类间接调用(static 润饰的办法) 2. 实例办法, 间接应用Java.choose() 在Java的堆中找到类的实例去调用办法
-
静态方法的被动调用
Java.perform(function () { let b = Java.use("com.zdwh.wwdz.wwdznet.l.b"); b.a(); });
-
实例办法的被动调用
Java.perform(function () { Java.choose('com.zdwh.wwdz.wwdznet.l.b', { onMatch: function(instance){ console.log('找到实例:', instance); instance.a(); }, onComplete: function(){ console.log('实现实例办法的调用'); } }); });
-
-
4.重载传参,以及输入Map类型数据
能够overload Java的类型参数,或者自定义的Java类型
Java.perform(function () { var b = Java.use("b.j.a.a.c.a"); b.a.overload("java.util.Map", "java.lang.String").implementation = function(map, str){ var Map = Java.use('java.util.HashMap'); var map_x = Java.cast(map, Map); send(map_x.toString()); console.log(str) return this.a(map,str); } });
-
5.RPC调用
参考:https://bbs.pediy.com/thread-…
应用frida hook时必须通过手机操作能力调到办法, 应用上面的形式能够被动调js export到处的native本地办法取得后果
- jadx或者jeb反编译工具定位到native办法
- 手机端启动frida-server
-
编写脚本
// 被执行js脚本 var result; function encrypt(str_url) { Java.perform(function fn() { console.log("begin"); Java.choose("com.mingning179.networkapi.util.JavaNdk", { onMatch: function (x) { console.log("find instance :" + x); console.log("result of fun(string) encrypt:" + str_url); result = x.encryptSrc(Java.use("java.lang.String").$new(str_url)); }, onComplete: function () { console.log("end"); } }) }); return result; } function decrypt(str_data) { Java.perform(function fn() { console.log("begin"); Java.choose("com.mingning179.networkapi.util.JavaNdk", { onMatch: function (x) { console.log("find instance :" + x); console.log("result of fun(string) decrypt:" + str_data); result = x.decryptSrc(Java.use("java.lang.String").$new(str_data)); }, onComplete: function () { console.log("end"); } }) }); return result; } rpc.exports = { decrypt: decrypt, encrypt: encrypt, };
import frida import json from flask import Flask, jsonify, request def on_message(message, data): if message['type'] == 'send': print("[*] {0}".format(message['payload'])) else: print(message) js = open('test.js', 'r', encoding='utf8').read() # session = frida.get_usb_device().attach('me.ele') session = frida.get_usb_device().attach('com.wjmt.app') script = session.create_script(js) script.on('message', on_message) script.load() app = Flask(__name__) @app.route('/decrypt', methods=['POST']) # data解密 def decrypt_class(): data = request.get_data() json_data = json.loads(data.decode("utf-8")) postdata = json_data.get("data") res = script.exports.decrypt(postdata) #调用Javascript导出的办法 return res @app.route('/encrypt', methods=['POST']) # url加密 def encrypt_class(): data = request.get_data() json_data = json.loads(data.decode("utf-8")) postdata = json_data.get("data") print(postdata) res = script.exports.encrypt(postdata) return res if __name__ == '__main__': app.run()
发表回复