Skip to content

裸 TCP socketRead0 hook ​

📥 抓取不走 SSL 的裸 TCP 接收数据。逻辑与 socketWrite0 对称,方向反转。

📎 源码在线查看:script.js(socketRead0)

实现 ​

javascript
Java.use("java.net.SocketInputStream").socketRead0
  .overload('java.io.FileDescriptor', '[B', 'int', 'int', 'int').implementation =
function (fd, bytearry, offset, byteCount, timeout) {
  var result = this.socketRead0(fd, bytearry, offset, byteCount, timeout);
  var message = {};
  message["function"] = "HTTP_recv";
  message["ssl_session_id"] = "";
  // 收数据时 src 是对端, dst 是本端(与 send 相反)
  message["src_addr"] = ntohl(ipToNumber(
      (this.socket.value.getRemoteSocketAddress().toString().split(":")[0]).split("/").pop()));
  message["src_port"] = parseInt(this.socket.value.getRemoteSocketAddress().toString().split(":").pop());
  message["dst_addr"] = ntohl(ipToNumber(
      (this.socket.value.getLocalAddress().toString().split(":")[0]).split("/").pop()));
  message["dst_port"] = parseInt(this.socket.value.getLocalPort());
  message["stack"] = Java.use("android.util.Log").getStackTraceString(
                     Java.use("java.lang.Throwable").$new()).toString();
  if (result > 0) {
    var ptr = Memory.alloc(result);
    for (var i = 0; i < result; ++i)
      ptr.add(i).writeU8(bytearry[offset + i] & 0xFF);
    send(message, ptr.readByteArray(result))
  }
  return result;
}

与 socketWrite0 的对称差异 ​

维度socketWrite0 (send)socketRead0 (recv)
src本端 local对端 remote
dst对端 remote本端 local
数据长度byteCount(请求量)result(实际读到的量)
send 条件总是 send仅 result > 0 时 send

仅 result > 0 才 send ​

javascript
if (result > 0) {
  var ptr = Memory.alloc(result);
  ...
  send(message, ptr.readByteArray(result))
}

socketRead0 返回值 = 实际读到的字节数。返回 0 或负数(连接关闭 / 超时 / 出错)时不 send,避免发空包或垃圾。

方向反转 ​

收数据时,数据是从对端流入本端,所以:

  • src = 对端(getRemoteSocketAddress)
  • dst = 本端(getLocalAddress)

与 socketWrite0(发:src=本端,dst=对端)正好相反。

相关文档 ​

基于 VitePress 构建 · 教学用途