安卓抓包方案

抓包环境搭建

详见 👉 http://xn--z4q5h38stwcs83anlqrw4b.xn--6qq986b3xl/?post=49 # 抓包环境搭建

正向防抓包方案

对抗方案

APP中常用HTTP请求库 HttpUrlConnectionVolleyOkHttpRetrofit等,HTTP协议是TCP协议的应用层服务,所以先分析一下TCP部分的调用链

分析TCP调用流程

TCP Java层

  1. 获取Socket的 InputStreamOutputStream的类
// 获取Socket的InputStream、OutputStream的类
Socket socket = new Socket("192.168.1.99", 5100);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
Log.d(TAG, "InputStream class:" + inputStream.getClass());
Log.d(TAG, "OutputStream class:" + outputStream.getClass());
  1. 运行结果为
InputStream class:class java.net.SocketInputStream
OutputStream class:class java.net.SocketOutputStream
  1. 跟踪代码

    • SocketInputStream.class
    // 1.调用 read(byte[] b)
    public int read(byte[] b) throws IOException {
        return this.read(b, 0, b.length);
    }
    
    // 2.调用 this.read
    public int read(byte[] b, int off, int length) throws IOException {
        return this.read(b, off, length, this.impl.getTimeout());
    }
    
    // 3.调用 read(byte[] b, int off, int length, int timeout)
    int read(byte[] b, int off, int length, int timeout) throws IOException {
        if (this.eof) {
            return -1;
        } else if (this.impl.isConnectionReset()) {
            throw new SocketException("Connection reset");
        } else if (length > 0 && off >= 0 && length <= b.length - off) {
            FileDescriptor fd = this.impl.acquireFD();
            label99: {
                int var7;
                try {
                    // socketRead
                    int n = this.socketRead(fd, b, off, length, timeout);
                    if (n <= 0) {
                        break label99;
                    }
                    var7 = n;
                } catch (ConnectionResetException var11) {
                    this.impl.setConnectionReset();
                    break label99;
                } finally {
                    this.impl.releaseFD();
                }
                return var7;
            }
            if (this.impl.isClosedOrPending()) {
                throw new SocketException("Socket closed");
            } else if (this.impl.isConnectionReset()) {
                throw new SocketException("Connection reset");
            } else {
                this.eof = true;
                return -1;
            }
        } else if (length == 0) {
            return 0;
        } else {
            throw new ArrayIndexOutOfBoundsException("length == " + length + " off == " + off + " buffer length == " + b.length);
        }
    }
    
    // 4.调用 socketRead(FileDescriptor fd, byte[] b, int off, int len, int timeout)
    private int socketRead(FileDescriptor fd, byte[] b, int off, int len, int timeout) throws IOException {
        return this.socketRead0(fd, b, off, len, timeout);
    }
    
    // native socketRead0(FileDescriptor var1, byte[] var2, int var3, int var4, int var5)
    private native int socketRead0(FileDescriptor var1, byte[] var2, int var3, int var4, int var5) throws IOException;
    • SocketOutputStream
    // 1.调用 write(byte[] b)
    public void write(byte[] b) throws IOException {
        this.socketWrite(b, 0, b.length);
    }
    
    // 2.调用 socketWrite(byte[] b, int off, int len)
    private void socketWrite(byte[] b, int off, int len) throws IOException {
        if (len > 0 && off >= 0 && len <= b.length - off) {
            FileDescriptor fd = this.impl.acquireFD();
            try {
                // socketWrite0
                this.socketWrite0(fd, b, off, len);
            } catch (SocketException var9) {
                if (this.impl.isClosedOrPending()) {
                    throw new SocketException("Socket closed");
                }
                throw var9;
            } finally {
                this.impl.releaseFD();
            }
        } else if (len != 0) {
            throw new ArrayIndexOutOfBoundsException("len == " + len + " off == " + off + " buffer length == " + b.length);
        }
    }
    
    // native socketWrite0(FileDescriptor var1, byte[] var2, int var3, int var4)
    private native void socketWrite0(FileDescriptor var1, byte[] var2, int var3, int var4) throws IOException;
  2. TCP Java层native代码为

    SocketInputStream:
    	socketRead0(FileDescriptor var1, byte[] var2, int var3, int var4, int var5)
    SocketOutputStream:
    	socketWrite0(FileDescriptor var1, byte[] var2, int var3, int var4)

TCP Native层

  • socketRead0recvfrom

代码地址 http://androidxref.com/8.1.0_r33/search?q=&defs=&refs=SocketInputStream_socketRead0&path=&hist=&project=libcore

nread = NET_Read(fd, bufP, len);

代码地址 http://androidxref.com/8.1.0_r33/xref/bionic/libc/bionic/recv.cpp#32

ssize_t recv(int socket, void *buf, size_t len, int flags) {
  return recvfrom(socket, buf, len, flags, NULL, 0);
}
  • socketWrite0sendto

代码地址 http://androidxref.com/8.1.0_r33/search?q=&defs=&refs=SocketOutputStream_socketWrite0&path=&hist=&project=libcore

// 调用 NET_Send
int n = NET_Send(fd, bufP + loff, llen, 0);

代码地址 http://androidxref.com/8.1.0_r33/xref/bionic/libc/bionic/send.cpp#31

ssize_t send(int socket, const void* buf, size_t len, int flags) __overloadable {
  return sendto(socket, buf, len, flags, NULL, 0);
}

分析SSL调用流程


安卓抓包方案
https://元气码农少女酱.我爱你/68c2d9659e91/
作者
元气码农少女酱
发布于
2023年5月2日
许可协议