38 lines
1.5 KiB
Python
38 lines
1.5 KiB
Python
#!/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))
|