mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
96 lines
5.0 KiB
Plaintext
96 lines
5.0 KiB
Plaintext
Visual injection on the running VT1200 OS -- key numbers
|
|
=========================================================
|
|
ROM md5 b46a3e442ccb86134d2356bd70d22fd2 (unchanged). No driver edits.
|
|
OS path: VT1200_SKIP_LEVEL1=1 (documented divergence), private -nvram_directory,
|
|
rdebug over TCP 771 with the computed challenge (dwt/solve.py chain).
|
|
|
|
1. `jump` is a call and returns; the OS stays alive
|
|
---------------------------------------------------
|
|
dwt/visual/build/ret_test.bin = 30 bytes, linked at bit 01840000h.
|
|
Step1 log: dwt/evidence/visual/step1_ret_test.log
|
|
jump 0x01840000: returned 0x00000000
|
|
after-peek 0x01850000 -> de c0 07 b0 (0xC0DE, 0xB007)
|
|
post-jump opcode 7 -> Done
|
|
second connection at frame 3526: opcode 7 -> Done; markers still de c0 07 b0
|
|
Frame at 3500 (step1_alive_3500.png) is the live Terminal Manager.
|
|
So the loader is a real call: stack/return are intact, and the TCP session is
|
|
usable before and after.
|
|
|
|
2. Static VRAM draw lands, but the OS repaints it
|
|
--------------------------------------------------
|
|
drawal.bin: three word-aligned black 32x32 boxes at (48,48), (256,400),
|
|
(928,752). Client log: dwt/evidence/visual/static_draw_client.log
|
|
after-peek 0x0400C030 (64) -> 00 00 00 00 ff ff ... (the writes are in VRAM)
|
|
jump returned; TCP Done; markers D2A0/B0C0.
|
|
Frames 3420 (before) and 3430 (after) are byte-identical
|
|
(static_before_3420.png / static_after_3430.png; md5 e98b9b4a38 both), and the
|
|
box regions do not change in any of 3420..3600. The OS repaints before the
|
|
next scanout.
|
|
Control (CPU frozen after the same draw): control_spin_box_3480.png shows the
|
|
black box, and the hello-world 256x64 block appears (control_hello_3480.png),
|
|
so the coordinates/renderer mapping are right.
|
|
|
|
3. Resident display-interrupt hook
|
|
----------------------------------
|
|
DI vector: RLONG(0xFFFFFEA0) = 00000DB0h. RAM stub there is 6 bytes:
|
|
80 c0 d0 46 71 3f = JA 3F7146D0h (stock OS display handler)
|
|
install rewrites the 32-bit target only:
|
|
80 c0 90 01 84 01 = JA 01840190h (our entry)
|
|
(both read from dwt/evidence/visual/live/runpc/vt1200-ram-3440.bin; the dump
|
|
itself is not committed -- see di_one_shot_state.log for the same stub read
|
|
through the running system.)
|
|
|
|
(a) draw before the stock handler: handler runs (counter 0x0A,0x62,...), but
|
|
no box ever appears -- the handler repaints after the draw.
|
|
|
|
(b) return-PC trampoline (draw after the handler's `reti`): visible blink.
|
|
Payload `dwt/visual/build/blinkev.bin` (252 bytes; the post-handler
|
|
trampoline with scratch at 01840800h). Two runs:
|
|
run A (blink_resident_client.log), frames 15:
|
|
frame 3450 box region 56.2% lit (black box ON)
|
|
frame 3480 box region 100.0% (box OFF, white body)
|
|
frame 3500 box region 56.2% (box ON again)
|
|
TCP answered at 3450 and at 3500 (post-jump opcode 7 -> Done).
|
|
run B (blink_repeat_client.log), frames live3, 5-frame dumps:
|
|
3440/3450 OFF, 3455..3520 ON (10-frame pairs):
|
|
blink2_off_3450.png, blink2_on_3460.png, blink2_on_3500.png.
|
|
The install returned and its post-jump opcode 7 -> Done, but a new
|
|
connection at 3450 got the challenge then timed out, and by 3470 the
|
|
terminal's IP stack was gone ("No route to host"). So the blink is
|
|
reproducible, TCP survival is flaky.
|
|
LIMIT: only the first trampoline entry draws. The stock handler's full
|
|
path (0x3F579880) stops returning through the patched saved PC; the
|
|
counter sticks at 1 (di_one_shot_state.log). So this is a real but
|
|
short-lived blink, not a durable one. Breakpoint log: hook_breakpoints.log
|
|
(ENTRY 1, RET 1, stock handler 34+).
|
|
|
|
(c) with the settle/IE work, the one-shot post-handler draw persists: frames
|
|
24/25 show the black box at (448..511, 400..463) for 600+ frames, and the
|
|
OS answers TCP at 3500/3600/3700/3800/4000
|
|
(settled_hook_client.log; settled_hook_mame.log). It does not toggle.
|
|
|
|
(d) INT2 hook (stub 0F30h, handler 3F714530h) was tried; at idle the handler
|
|
never takes the trampoline (counter 0), so it is not a blink source here.
|
|
|
|
4. Window
|
|
---------
|
|
Port 6000 is OPEN on 192.168.99.2 (xcheck.log); 6001 is closed. An ordinary
|
|
X client is rejected:
|
|
xdpyinfo -display 192.168.99.2:0 -> "Client is not authorized to access server"
|
|
So a normal X client cannot open a window without the server's auth cookie.
|
|
Injection of a window was NOT attempted: it needs the X server's window
|
|
structures, resource IDs and callbacks; that is a project, not an experiment.
|
|
|
|
Evidence files
|
|
--------------
|
|
step1_ret_test.log, step1_alive_3500.png
|
|
static_draw_client.log, static_before_3420.png, static_after_3430.png
|
|
control_spin_client.log, control_spin_box_3480.png, control_hello_3480.png
|
|
blink_resident_client.log, blink_on_3450(_crop).png, blink_off_3480(_crop).png,
|
|
blink_on_3500.png, blink_mame.log
|
|
blink_repeat_client.log, blink_repeat_mame.log, blink2_off_3450.png,
|
|
blink2_on_3460.png, blink2_on_3500.png, step3_blink_client.log
|
|
settled_hook_client.log, settled_hook_mame.log, posthandler_persist_3600.png
|
|
di_one_shot_state.log, hook_breakpoints.log
|
|
xcheck.log, xcheck_mame.log
|