Skip to content

SSL_write hook ​

📤 抓 HTTPS 请求明文(本端 → 服务端)的核心 hook。

📎 源码在线查看:script.js#L304-L340(SSL_write hook)

SSL_write 原型 ​

c
int SSL_write(SSL *ssl, const void *buf, int num);
// 把 buf 里的明文加密后发到 SSL 连接,返回写入字节数

hook 实现 ​

javascript
Interceptor.attach(addresses["SSL_write"], {
  onEnter: function (args) {
    var message = getPortsAndAddresses(SSL_get_fd(args[0]), false);
    message["ssl_session_id"] = getSslSessionId(args[0]);
    message["function"] = "SSL_write";
    message["stack"] = SSLstackwrite;  // Conscrypt SSLOutputStream.write 时填入
    send(message, args[1].readByteArray(parseInt(args[2])));
  },
  onLeave: function (retval) {
  }
});

为什么在 onEnter 就 send ​

与 SSL_read 不同,SSL_write 在 onEnter 就 send——因为写入的数据在 args[1] 里已经现成,不需要等返回值。

  • isRead=false:发,src 取本端
  • args[1].readByteArray(parseInt(args[2])):直接读 args[1] 的 args[2] 字节明文
  • parseInt(args[2]):args[2] 是 NativePointer,转成整数长度

onLeave 留空 ​

javascript
onLeave: function (retval) {
}

SSL_write 的返回值(实际写入字节数)对抓包无意义——明文已经在 onEnter 抓到了。

长度处理注意 ​

SSL_write 一次调用可能只写一部分 num 字节(返回值 < num),但 r0capture 在 onEnter 就把请求的 num 字节全 send 了。这意味着:

  • 正常情况:抓到完整的请求明文 ✅
  • 极端情况(写了一半就返回):抓到的可能比实际发送的多(包含未发出的尾部)——但这种情况罕见,且对分析影响小

与 SSL_read 的对比 ​

详见 SSL_read hook。

相关文档 ​

基于 VitePress 构建 · 教学用途