Frida小试

@lzeroyuee  November 11, 2020

简介

Frida 官网

Frida 文档

Frida是一个动态代码检测工具包(Hook框架),可运行于Windows、macOS,、GNU/Linux,、iOS,、Android和QNX

Frida分为两部分:

  1. frida CLI运行于本机上的交互工具
  2. 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来监控,如下:

1.png

这里使用了通配符*,Hook了recvrecvfrom两个函数,并且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]);
}

然后重新加载一遍,打印出了自定义格式的信息

2.png

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)

参考

Frida官方手册 - JavaScript API(篇二)


添加新评论