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

Frida拦截fork后钩子SSL_write时仅生效于子进程,如何同时钩子父子进程的SSL_write?

Frida拦截fork后钩子SSL_write时仅生效于子进程,如何同时钩子父子进程的SSL_write?

兄弟,我懂你遇到的这个坑!之前我也碰过类似的情况——fork之后父子进程是完全独立的执行空间,Frida的hook不会自动在父子进程中都生效,你之前的代码只在子进程里hook了SSL_write,大概率是因为你只在fork完成后的子进程上下文里执行了hook逻辑,而父进程的SSL_write从始至终都没被正确hook上。

给你两个关键点解决这个问题:

  • 父进程的SSL_write要提前hook:在脚本一开始初始化的时候,就把父进程的SSL_write hook好,别等fork发生了再处理,这样父进程的SSL_write从脚本运行开始就会被拦截。
  • 子进程的SSL_write要单独部署hook:fork完成后,子进程是全新的进程空间,虽然会继承父进程的内存,但Frida的hook绑定是和进程上下文关联的,所以需要在子进程的专属上下文里再执行一次hook逻辑。Frida提供了Script.runInChild()API,能帮你在指定的子进程中执行代码,刚好适合这个场景。

话不多说,直接给你调整后的代码,你可以直接用:

首先定义一个通用的hook SSL_write的函数,这样父子进程的hook逻辑可以复用,不用写两遍:

function hookSSLWrite() {
  // 先确保libssl模块已经加载,避免找不到函数
  Module.ensureInitialized("libssl.so");
  const sslWriteAddr = Module.findExportByName("libssl.so", "SSL_write");
  
  if (sslWriteAddr) {
    Interceptor.attach(sslWriteAddr, {
      onEnter: function(args) {
        console.log(`[PID ${Process.id()}] SSL_write 被调用啦,参数fd: ${args[0]}`);
        // 这里可以加你自己的业务逻辑,比如打印参数、修改返回值之类的
      },
      onLeave: function(retval) {
        console.log(`[PID ${Process.id()}] SSL_write 返回值: ${retval.toInt32()}`);
      }
    });
    console.log(`[PID ${Process.id()}] 成功hook SSL_write`);
  } else {
    console.log(`[PID ${Process.id()}] 没找到SSL_write函数,可能模块没加载?`);
  }
}

然后是主脚本部分:

// 脚本一启动,先把父进程的SSL_write给hook了
hookSSLWrite();

// 拦截fork函数
Interceptor.attach(Module.findExportByName("libc.so", "fork"), {
  onEnter: function(args) {
    try {
      const callerModule = Process.getModuleByAddress(this.returnAddress);
      console.log(`[*] fork被调用啦,调用者模块: ${callerModule.name},地址: ${this.returnAddress}`);
      console.log(`[*] 模块路径: ${callerModule.path}`);
    } catch (err) {
      console.log(`[!] 解析调用模块出错啦: ${this.returnAddress}, 错误信息: ${err}`);
    }
  },
  onLeave: function(retval) {
    const childPid = retval.toInt32();
    console.log(`[*] fork执行完成,子进程PID: ${childPid}`);

    // 分情况处理:父进程上下文和子进程上下文
    if (childPid > 0) {
      // 这里是父进程的上下文,用runInChild在子进程中执行hook
      Script.runInChild(childPid, { timeout: 0 }, function() {
        hookSSLWrite();
      });
    } else if (childPid === 0) {
      // 这里是子进程的上下文,直接执行hook
      hookSSLWrite();
    }
  }
});

为什么这样能行?

  1. 脚本启动时就调用hookSSLWrite(),父进程的SSL_write直接被hook,后续父进程的所有SSL_write调用都会被拦截。
  2. fork完成后,父进程上下文里用Script.runInChild()把hook逻辑注入到子进程中,子进程的SSL_write也会被hook上;同时考虑到有些情况下Frida会在子进程中触发onLeave(childPid为0的情况),这里也做了兼容,确保子进程的hook万无一失。

另外提醒你一句:如果你的目标程序是延迟加载libssl.so的(比如用到的时候才加载),那hookSSLWrite里的Module.ensureInitialized("libssl.so")一定要加上,确保能找到SSL_write的地址,不然可能会出现找不到函数的情况。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:23:07