简介
Frida是一个动态代码检测工具包(Hook框架),可运行于Windows、macOS,、GNU/Linux,、iOS,、Android和QNX
Frida分为两部分:
- frida CLI运行于本机上的交互工具
- Frida-Server支持远程Hook,运行于目标机上,下载地址:frida ,需根据目标机平台选择相应的版本
安装
前置环境:python 3.x,使用pip进行安装
pip install frida
pip install frida-tools
与Frida-Server交互
Frida Server:监听192.168.122.134,默认监听端口为27042
frida-server-14.0.7-windows-x86_64.exe -l 192.168.122.134
本机使用frida-ps -H 192.168.122.134
可以查看目标机上的进程,例如:
frida-ps -H 192.168.122.134
PID Name
---- --------------------------------------
2216 Everything x64.exe
2200 HipsTray.exe
2812 SearchProtocolHost.exe
988 cmd.exe
2232 conhost.exe
2000 dwm.exe
2008 explorer.exe
1020 frida-server-14.0.7-windows-x86_64.exe
2360 reader_sl.exe
1912 taskhost.exe
2168 vm3dservice.exe
2188 vmtoolsd.exe
Frida
Frida有6个工具,分别为:
Frida CLI 交互工具
frida-ps 显示进程列表
frida-trace 动态跟踪函数调用
frida-discover 可以用来查找程序内部函数
frida-ls-devices 列出附加设备的命令行工具
frida-kill 终止进程的命令行工具
frida-trace
例子:利用frida-trace监控recv
函数调用
在目标机上开启python,本地使用frida-ps
查看进程列表获取python的PID,目标机使用urllib.urlopen
打开连接,本机使用frida-trace -i "recv*" -H 192.168.122.134 -p PID
来监控,如下:
这里使用了通配符*
,Hook了recv
和recvfrom
两个函数,并且frida-trace
会在当前目录下生成__handlers__\WS2_32.dll\recv.js
和__handlers__\WS2_32.dll\recvfrom.js
来完成Hook
以下是recv.js
代码,定义了进出recv
函数时的执行动作
{
// args - 函数参数数组
onEnter(log, args, state) {
log('recv()');
},
// retval - NativePointer对象
onLeave(log, retval, state) {
}
}
将代码改一下,例如:
onEnter(log, args, state) {
log("recv() -> \n\ts = " + args[0].toInt32() + "\n\tbuf = " + args[1] +
"\n\tlen = " + args[2].toInt32() + "\n\tflags = " + args[3]);
}
然后重新加载一遍,打印出了自定义格式的信息
python API支持
Frida提供了python支持,但核心的Hook必须使用JavaScript,除此之外,对于目标为windows平台,目前好像只能使用python对本机进程进行Hook
# -*- coding: utf-8 -*-
import frida
import sys
def on_message(message, data):
print("[on_message] message:", message, "data:", data)
class MyHook(object):
def __init__(self, target_process, on_message_func = on_message):
self.__session = frida.attach(target_process)
self.__on_message_func = on_message_func
def hook(self, script):
self.__script = self.__session.create_script(script)
self.__script.on("message", self.__on_message_func)
self.__script.load()
print("Hooking...")
sys.stdin.read()
self.__session.detach()
# 监控CreateFileW
script = """
Interceptor.attach(Module.findExportByName("Kernel32.dll", "CreateFileW"), {
onEnter: function(args) {
if (args[0].isNull()) return;
var path = args[0].readUtf16String();
console.log("CreateFileW: " + path);
}
});
"""
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage example.py <target>")
else:
try:
target = int(sys.argv[1])
except ValueError as e:
target = sys.argv[1]
myhook = MyHook(target)
myhook.hook(script)