Download Game! Currently 95 players. Last logged in:JosimSarmangothFonkensembleUrsa

Blitzer's Blog >> 72577

Back to blogs index
Posted: 19 Sep 2026 12:54 [ permalink ]
Loistavaa, ettC$ downgreidaus tehosi aVNC:n kanssa!
"Debug portin" (ohjausrajapinnan) lisC$C$minen on tC$ydellinen tapa eriyttC$C$
logiikka toisistaan. Proxy sC$ilyy tyhmC$nC$ "putkena ja piirtC$jC$nC$", ja
mikC$ tahansa muu ohjelma (mesh-agentti, bash-skripti, tai curl) voi
lC$hettC$C$ sille komentoja.
Rakennetaan proxyn sisC$C$n kevyt asynkroninen TCP- tai HTTP-palvelin.
Laitetaan se kuuntelemaan porttia 15942. Yksinkertaisuuden vuoksi tehdC$C$n
siitC$ kevyt JSON/TCP -socket tai asyncio.start_server -pohjainen
komentokanava.
KC$ytetC$C$n suoraa TCP-socketia JSON-payloadilla. Se on salamannopea ja voit
testata sitC$ helposti netcatilla (nc).
VNC Proxyn pC$ivitys: Debug-portti ja TC$htC$in-injektio
TC$ssC$ on tC$ydellinen koodi. Se sisC$ltC$C$ aiemmin kC$sitellyn kC$ttelyn,
pakettianalyysin, ja nyt uutena ominaisuutena API Serverin portissa 15942
sekC$ inject_visual_marker -metodin.
Huom: Voit pC$ivittC$C$ vncproxy.py:n suoraan shadow_sed -skriptillC$si tai
copy-pastella.
[GEM-EDITBOT-START]
TARGET FILE "/tmp/vncproxy.py"
REPLACE LINE 1 WITH BLOCK
import asyncio
import struct
import json

LISTEN_HOST = '0.0.0.0'
LISTEN_PORT = 5942
UPSTREAM_HOST = '127.0.0.1'
UPSTREAM_PORT = 5900
API_PORT = 15942

class VNCProxy:
    def __init__(self):
        # Tallennetaan aktiiviset VNC-asiakkaat (client_writer), jotta API 
        # voi lC$hettC$C$ niille piirtokomentoja, vaikka viesti tulee
ulkopuolelta.
        self.active_clients = []

    async def start(self):
        vnc_server = await asyncio.start_server(self.handle_client,
LISTEN_HOST, LISTEN_PORT)
        api_server = await asyncio.start_server(self.handle_api_command,
LISTEN_HOST, API_PORT)
        
        print(f"[*] VNC Proxy kuuntelee {LISTEN_HOST}:{LISTEN_PORT}")
        print(f"[*] API / Debug portti kuuntelee {LISTEN_HOST}:{API_PORT}")
        
        async with vnc_server, api_server:
            await asyncio.gather(
                vnc_server.serve_forever(),
                api_server.serve_forever()
            )

    async def handle_api_command(self, reader, writer):
        """ KC$sittelee porttiin 15942 tulevat JSON-komennot """
        addr = writer.get_extra_info('peername')
        try:
            data = await reader.read(1024)
            if not data:
                return
            
            payload = json.loads(data.decode('utf-8').strip())
            cmd = payload.get("command")
            
            if cmd == "draw_marker":
                x = payload.get("x", 0)
                y = payload.get("y", 0)
                size = payload.get("size", 20)
                
                print(f"[API] PyyntC6 piirtC$C$ tC$htC$in X:{x} Y:{y}
Size:{size}")
                
                # LC$hetetC$C$n piirtokomento kaikille kytketyille
VNC-asiakkaille
                for client_writer in self.active_clients:
                    try:
                        await self.inject_visual_marker(client_writer, x, y,
size)
                    except Exception as e:
                        print(f"[API] Piirtovirhe clientille: {e}")
            
            writer.write(b'{"status": "ok"}
')
            await writer.drain()
            
        except json.JSONDecodeError:
            writer.write(b'{"status": "error", "message": "Invalid JSON"}
')
            await writer.drain()
        except Exception as e:
            print(f"[API] Virhe: {e}")
        finally:
            writer.close()

    async def inject_visual_marker(self, client_writer, x, y, size=20):
        """ PiirtC$C$ punaisen laatikon VNC-asiakkaan ruudulle injektoimalla
FramebufferUpdate viestin """
        start_x = max(0, x - size // 2)
        start_y = max(0, y - size // 2)
        
        # Punainen pikseli (BGRX) - TC$mC$ voi vaatia hienosC$C$tC6C$ riippuen
kC$ttelyn PixelFormatista
        # YleensC$ VNC oletus on 32-bit BGRX
        red_pixel = struct.pack('BBBB', 0, 0, 255, 255)
        pixel_count = size * size
        pixel_data = red_pixel * pixel_count

        # Viestityyppi 0 (FramebufferUpdate), padding, 1 suorakulmio
        header = struct.pack('>BxH', 0, 1)
        # Suorakulmio: X, Y, W, H, Encoding (0 = Raw)
        rect_header = struct.pack('>HHHHI', start_x, start_y, size, size, 0)

        payload = header + rect_header + pixel_data
        
        # Injektoidaan asiakkaalle menevC$C$n putkeen
        client_writer.write(payload)
        await client_writer.drain()

    async def handle_client(self, client_reader, client_writer):
        print(f"[+] Uusi VNC-asiakas yhdistetty")
        self.active_clients.append(client_writer)
        
        try:
            target_reader, target_writer = await asyncio.open_connection(UPSTRE
AM_HOST, UPSTREAM_PORT)
        except Exception as e:
            print(f"[-] Ei yhteyttC$ VNC-palvelimeen: {e}")
            self.active_clients.remove(client_writer)
            client_writer.close()
            return

        try:
            await self.handle_handshake(client_reader, client_writer,
target_reader, target_writer)
            print("[*] KC$ttely onnistui, siirrytC$C$n pakettianalyysiin...")
        except Exception as e:
            print(f"[-] KC$ttely epC$onnistui: {e}")
            self.active_clients.remove(client_writer)
            client_writer.close()
            target_writer.close()
            return

        task1 = asyncio.create_task(self.server_to_client(target_reader,
client_writer))
        task2 = asyncio.create_task(self.client_to_server(client_reader,
target_writer))
        
        await asyncio.gather(task1, task2)
        
        # Siivous, kun yhteys katkeaa
        if client_writer in self.active_clients: