简述
获取对象的方法
frida获取对象有2中, 1种是从内存中获取(程序自己创建的), 还有一种就是我们自己去new对象, 当然推荐第一种, 因为我们手动new对象只是调用其构造方法,如果是复杂的构造方法, 我们获取器参数也就特别复杂, 而且有些成员属性在程序的运行中被改变了, 这样会导致错误的结果。
从内存中获取对象api
var result = null;
Java.choose("com.xx.xx.xx.xx",{ // xx代表类名
// 匹配到该对象要执行的函数
onMatch: function(instance){
result = instance.function();
},
// 搜索完毕后要执行的函数
onComplete: function(){
}
});
简单测试手动调用
https://www.52pojie.cn/thread-1128884-1-1.html
我们以上面frida hookjava的实例, 我们要实现主动调用testFrida方法
- 新建一个testFrida.js, 写入如下代码
function call_fridajava(){
var result = null;
Java.perform(function(){
Java.choose("com.example.testfrida.MainActivity",{ // xx代表类名
// 匹配到该对象要执行的函数
onMatch: function(instance){
result = instance.testFrida();
},
// 搜索完毕后要执行的函数
onComplete: function(){
}
});
});
return result;
}
手动调用
# 1, 手机端frida-server
# 2, adb连接
# 3, 端口转发 27042, 27043
# 4, 运行下面的命令, 注入js
frida -U testfrida -l d:\app\frida\testFrida.js
# call_fridajava() // 调用方法
测试rpc调用
设置导出函数, 上面的代码下面加入 rpc.exports
注意: 导出函数的key必须是消息callfridajava --> 如果你写成callFridaJava 会导致方法找不到
function call_fridajava(){
var result = null;
Java.perform(function(){
Java.choose("com.example.testfrida.MainActivity",{ // xx代表类名
// 匹配到该对象要执行的函数
onMatch: function(instance){
result = instance.testFrida();
},
// 搜索完毕后要执行的函数
onComplete: function(){
}
});
});
console.log("--------------------");
console.log(result);
return result;
}
rpc.exports = {
callfridajava: call_fridajava
}
添加主函数(socket连接, 最好使用http, 方便入门)
# -*- coding: utf-8 -*-
import codecs
import frida
import socket
if __name__ == '__main__':
#附加到目标进程
# session = frida.get_usb_device().attach(u'testfrida')
process = frida.get_remote_device().attach('testfrida')
#读取JS脚本 如果找不到就写全路径
with codecs.open('./testFrida.js', 'r', 'utf-8') as f:
source = f.read()
script = process.create_script(source)
script.load()
#调用导出的函数
rpc = script.exports
rpc.callfridajava()
# 构建web服务器 start
HOST, PORT = '', 8888
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
print('Serving HTTP on port %s ...' % PORT)
while True:
client_connection, client_address = listen_socket.accept()
request = client_connection.recv(1024)
print(request.decode("utf-8"))
http_response = rpc.callfridajava()
client_connection.sendall(http_response.encode("utf-8"))
client_connection.close()
# 构建web服务器 end
process.detach()
运行主函数,打开socket客户端连接工具
https://www.onlinedown.net/soft/55038.htm socket工具下载
python ./testFridaMain.py
由于是socket, 并且代码中发送一次, 就会断一次, 因此我们改成http的
rpchttp服务调用
我们先学习这个简单的web框架
https://www.jianshu.com/p/6452596c4edb
并安装好环境
# -*- coding: utf-8 -*-
import codecs
import frida
import socket
from flask import Flask
app = Flask(__name__)
@app.route('/hi')
def hi():
return 'Hello World'
@app.route('/frida')
def callfrida():
return rpc.callfridajava()
if __name__ == '__main__':
#附加到目标进程
# session = frida.get_usb_device().attach(u'testfrida')
print(frida.get_remote_device)
process = frida.get_remote_device().attach('testfrida')
#读取JS脚本 如果找不到就写全路径
with codecs.open('C:/Users/xdb/Desktop/testFrida.js', 'r', 'utf-8') as f:
source = f.read()
script = process.create_script(source)
script.load()
#调用导出的函数
rpc = script.exports
rpc.callfridajava()
# 构建flask服务器 start
app.run(host='127.0.0.1',port=5000)
# 构建web服务器 end
process.detach()
如果有多个方法, 以及参数,我们可以通过扩展Flask的请求,获取请求参数, 然后参入到rpc的方法中。