Files
vt1200/dwt/evidence/visual/summary.txt
T

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