mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
96 lines
2.7 KiB
Lua
96 lines
2.7 KiB
Lua
-- oracle_call_test.lua -- minimal proof that the firmware's challenge pipeline
|
|
-- can be invoked directly from the debugger (no TCP connection).
|
|
--
|
|
-- Calls 0x3F5A9620(1) (dwt_prf's allocator/init, Ghidra 0x07EB52C4)
|
|
-- at frame 1000 and stops at the synthetic return address.
|
|
local machine = manager.machine
|
|
local cpu = machine.devices[':maincpu']
|
|
local dbg = machine.debugger
|
|
local space = cpu.spaces['program']
|
|
if not dbg then machine:exit(); return end
|
|
dbg.visible_cpu = cpu
|
|
|
|
local ARG = 0x01800000
|
|
local STACK = 0x01840000
|
|
local RET = 0x018c0000
|
|
local IE = 0x200000
|
|
local INIT = 0x3F5A9620
|
|
|
|
local f = 0
|
|
local started = false
|
|
local saved = {}
|
|
|
|
local function state(name)
|
|
local r = cpu.state[name]
|
|
return r and r.value or nil
|
|
end
|
|
|
|
local function push(v)
|
|
local sp = state('SP') - 0x20
|
|
space:write_u32(sp, v)
|
|
cpu.state['SP'].value = sp
|
|
end
|
|
|
|
local function setup_call(target, args)
|
|
saved.pc = state('PC')
|
|
saved.sp = state('SP')
|
|
saved.a14 = state('A14')
|
|
saved.st = state('ST')
|
|
print(string.format("TEST setup target=%08X pc=%08X sp=%08X a14=%08X st=%08X",
|
|
target, saved.pc, saved.sp, saved.a14, saved.st))
|
|
cpu.state['SP'].value = STACK
|
|
if #args > 0 then
|
|
local a = ARG
|
|
for i = 1, #args do
|
|
space:write_u32(a, args[i])
|
|
a = a + 0x20
|
|
end
|
|
push(saved.a14)
|
|
cpu.state['A14'].value = ARG + #args * 0x20
|
|
end
|
|
push(RET)
|
|
cpu.state['PC'].value = target
|
|
cpu.state['ST'].value = saved.st & ~IE
|
|
dbg:command('bclear')
|
|
dbg:command(string.format('bpset %X', RET))
|
|
dbg.execution_state = 'run'
|
|
end
|
|
|
|
emu.register_frame_done(function()
|
|
f = f + 1
|
|
if f == 1000 and not started then
|
|
started = true
|
|
print(string.format("TEST frame=%d @1C0200=%08X", f, space:read_u32(0x1c0200)))
|
|
setup_call(INIT, { 1 })
|
|
return
|
|
end
|
|
if started and saved.pc then
|
|
local es = dbg.execution_state
|
|
if es == 'stop' then
|
|
local pc = state('PC')
|
|
print(string.format("TEST stop frame=%d pc=%08X savedpc=%08X", f, pc, saved.pc))
|
|
print(string.format("TEST @1C0200=%08X @1C0220=%08X @1C0240=%08X @1C0260=%08X",
|
|
space:read_u32(0x1c0200), space:read_u32(0x1c0220),
|
|
space:read_u32(0x1c0240), space:read_u32(0x1c0260)))
|
|
-- dump 16 bytes at the key pointer if it looks sane
|
|
local kp = space:read_u32(0x1c0260)
|
|
if kp ~= 0 then
|
|
local t = {}
|
|
for i = 0, 15 do
|
|
t[#t + 1] = string.format("%02X", space:read_u8(kp + i * 8))
|
|
end
|
|
print("TEST key[0..15]=" .. table.concat(t, " "))
|
|
end
|
|
dbg:command('bclear')
|
|
cpu.state['PC'].value = saved.pc
|
|
cpu.state['SP'].value = saved.sp
|
|
cpu.state['A14'].value = saved.a14
|
|
cpu.state['ST'].value = saved.st
|
|
print("TEST restoring and exiting")
|
|
machine:exit()
|
|
end
|
|
end
|
|
end, "vt1200-oracle-call-test")
|
|
|
|
dbg.execution_state = 'run'
|