#!/usr/bin/env python3 # Minimal RFB 3.8 client (security None, Raw encoding, 32bpp) -> PPM. Usage: vncshot.py HOST PORT OUT.ppm import socket, struct, sys h, p, out = sys.argv[1], int(sys.argv[2]), sys.argv[3] s = socket.create_connection((h, p), 10) def rx(n): b = b'' while len(b) < n: c = s.recv(n - len(b)) if not c: raise SystemExit('eof') b += c return b ver = rx(12); s.sendall(b'RFB 003.008\n') n = rx(1)[0]; types = rx(n) if 1 not in types: raise SystemExit('no None auth: %r' % types) s.sendall(b'\x01'); assert struct.unpack('>I', rx(4))[0] == 0 s.sendall(b'\x01') w, hh = struct.unpack('>HH', rx(4)); rx(16); name = rx(struct.unpack('>I', rx(4))[0]) s.sendall(struct.pack('>BxxxBBBBHHHBBBxxx', 0, 32, 24, 0, 1, 255, 255, 255, 16, 8, 0)) s.sendall(struct.pack('>BxHi', 2, 1, 0)) s.sendall(struct.pack('>BBHHHH', 3, 0, 0, 0, w, hh)) img = bytearray(w * hh * 3) got = 0 while got < w * hh: t = rx(1)[0] if t != 0: raise SystemExit('msg %d' % t) rx(1); nr = struct.unpack('>H', rx(2))[0] for _ in range(nr): x, y, rw, rh, enc = struct.unpack('>HHHHi', rx(12)) px = rx(rw * rh * 4) for j in range(rh): for i in range(rw): v = px[(j * rw + i) * 4:(j * rw + i) * 4 + 4] o = ((y + j) * w + x + i) * 3 img[o:o + 3] = bytes((v[2], v[1], v[0])) got += rw * rh open(out, 'wb').write(b'P6 %d %d 255\n' % (w, hh) + img) print('server', ver.strip().decode(), 'name', name.decode(), 'size %dx%d' % (w, hh))