You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Frida重定向已运行应用的Socket流量?其实现原理是什么?

用Frida修改Socket目标IP/端口的实现方法及原理

一、具体实现步骤

要修改Socket的目标地址,核心思路是Hook进程中负责建立Socket连接的函数,在函数执行时篡改传入的目标IP和端口参数。不同平台的目标函数略有差异,以下是常见场景的实现:

1. Linux/Android平台(Hook libc的connect函数)

大多数原生应用会调用libc的connect函数发起Socket连接,我们可以直接拦截这个函数并修改参数:

// frida脚本:替换Socket连接目标
Interceptor.attach(Module.findExportByName("libc.so", "connect"), {
    onEnter: function(args) {
        // args[0] = socket文件描述符,args[1] = sockaddr结构体指针,args[2] = 结构体长度
        const sockaddrPtr = args[1];
        const family = sockaddrPtr.readUShort(); // 地址族,AF_INET=2,AF_INET6=10

        // 处理IPv4连接
        if (family === 2) {
            // 读取原始目标信息
            const originalPortNet = sockaddrPtr.add(2).readUShort();
            const originalPort = (originalPortNet >> 8) | (originalPortNet << 8); // 网络字节序转主机序
            const originalIpInt = sockaddrPtr.add(4).readUInt32();
            const originalIp = [
                (originalIpInt >> 0) & 0xff,
                (originalIpInt >> 8) & 0xff,
                (originalIpInt >> 16) & 0xff,
                (originalIpInt >> 24) & 0xff
            ].join('.');
            console.log(`Original connection: ${originalIp}:${originalPort}`);

            // 替换为你的目标IP和端口
            const targetIp = "192.168.1.100"; // 你的本地IP
            const targetPort = 8080; // 你的监听端口

            // 将IP转为网络字节序的整数
            const ipParts = targetIp.split('.').map(Number);
            const newIpInt = (ipParts[3] << 24) | (ipParts[2] << 16) | (ipParts[1] << 8) | ipParts[0];
            sockaddrPtr.add(4).writeUInt32(newIpInt);

            // 将端口转为网络字节序(主机序转大端)
            const newPortNet = (targetPort << 8) | (targetPort >> 8);
            sockaddrPtr.add(2).writeUShort(newPortNet);

            console.log(`Redirected to: ${targetIp}:${targetPort}`);
        }

        // 如需处理IPv6,可添加family === 10的分支逻辑
    }
});

2. 运行脚本

将上述代码保存为redirect-socket.js,然后用Frida注入目标进程:

# 连接USB设备上的应用
frida -U -f com.your.target.app -l redirect-socket.js --no-pause

3. 特殊场景处理

如果应用使用了封装的网络库(比如Android的OkHttp、iOS的NSURLSession),可能需要Hook这些库的高层方法,而非底层的connect函数。例如Hook OkHttp的RealCall.connect方法,或者直接拦截DNS解析结果,从源头修改目标地址。

二、Frida实现深度介入的原理

Frida之所以能轻松篡改进程的Socket行为,核心依赖以下几个技术:

  • 动态函数插桩(Dynamic Instrumentation):Frida通过底层调试接口(Linux/Android用ptrace,Windows用远程线程注入,iOS用越狱环境的动态库注入)将一个JavaScript Agent注入目标进程。这个Agent可以找到任意函数的内存地址,然后修改函数入口处的指令,插入跳转逻辑——让程序执行到目标函数时,先进入我们的钩子函数,再继续执行原函数。

  • 直接操作进程内存:Frida提供了完整的内存读写API,允许我们直接访问和修改进程中的任意内存区域。比如上面的脚本中,我们直接读写sockaddr结构体的内存,替换其中的IP和端口值,这种直接篡改内存的能力是实现需求的关键。

  • 跨平台兼容性:Frida针对不同操作系统封装了统一的API,不管是Android、iOS还是Windows,你都可以用几乎相同的逻辑编写Hook脚本,无需关心底层系统的差异。

  • 无侵入式修改:整个过程不需要修改目标应用的代码或重新编译,完全在运行时动态修改程序行为,这也是Frida这类动态插桩工具的核心优势。

内容的提问来源于stack exchange,提问作者Makik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:10:28