Skip to content

hook SSL_read 详解 ​

👀 script.js hook Native SSL_read,捕获 App 收到的 TLS 明文。

📎 源码在线查看:script.js#L277-L303(SSL_read hook)

函数原型 ​

c
int SSL_read(SSL *ssl, void *buf, int num);
// 返回实际读取字节数

hook 实现 ​

javascript
Interceptor.attach(SSL_read_addr, {
    onEnter: function (args) {
        this.ssl = args[0];
        this.buf = args[1];
        this.num = args[2].toInt32();
    },
    onLeave: function (retval) {
        var read = retval.toInt32();
        if (read > 0) {
            var fd = SSL_get_fd(this.ssl);
            var addrs = getPortsAndAddresses(fd);
            // 注意 read 方向:服务端 → 客户端
            send(
                { "type": "SSL_read", 
                  "src_addr": addrs.dst_addr,  // 对端是源
                  "dst_addr": addrs.src_addr,  // 本端是目的
                  ... },
                this.buf.readByteArray(read)
            );
        }
    }
});

方向处理 ​

read 时,数据从对端流入本端,所以 pcap 包的 src/dst 要对调(服务端→客户端),与 write 相反。否则 pcap 里 read 包方向会错。

buf 是什么 ​

SSL_read 返回后,buf 里是已解密的明文(解密由 SSL_read 内部完成)。hook 在解密后拿到明文。

onLeave 读 buf 的原因 ​

read 返回前 buf 内容未定(还没解密填充)。必须在 onLeave、确认 read > 0 后才读。

read 可能返回 0 或负 ​

retval含义
> 0实际读到的字节数
0EOF,连接关闭
< 0出错

只有 > 0 时才有明文可抓。

分块 ​

大响应被分多次 read,r0capture 各抓一次,pcap 里是多个包。需重组见 TCP 分段。

相关文档 ​

基于 VitePress 构建 · 教学用途