Files
vt1200/harness/mame/overflow.lua
T

46 lines
1.8 KiB
Lua

-- VT1200: demonstrate the pcfReadBitmaps n*4 integer overflow in-emulator.
--
-- We jump straight into the arithmetic block with a crafted PCF_CharInfo:
-- a9 = fake pCS, pCS->nChars at a9+0x270
-- a13 = fake arg blk, n (32-bit pcfReadInt32 result) at a13+0x20
-- PC = 3f984e70
-- A breakpoint after 'sll 0x2,a11' (3f985060) prints the resulting size and
-- quits, so we never enter fosAlloc with a bogus heap.
--
-- <mame> vt1200 -rompath harness/mame/roms -video none -sound none -nothrottle \
-- -debug -debugger none -debuglog \
-- -autoboot_script harness/mame/overflow.lua -autoboot_delay 0
local function hex(v) return string.format("%08X", v) end
local machine = manager.machine
local cpu = machine.devices[':maincpu']
local dbg = machine.debugger
local prog = cpu.spaces['program']
if not dbg then
print("ERROR: debugger not enabled; pass -debug")
machine:exit()
return
end
-- n defaults to 0x40000001: n*4 wraps mod 2^32 to 4, but the following loop
-- still writes n CARD32 entries -- a heap overflow. Override with OVF_N
-- (decimal) to run a control case.
local n = tonumber(os.getenv("OVF_N") or "1073741825")
cpu.state['SP'].value = 0x00080000
cpu.state['A9'].value = 0x00040000 -- fake pCS
cpu.state['A13'].value = 0x00060000 -- fake arg block
prog:write_u32(0x00040270, 0) -- pCS->nChars = 0
prog:write_u32(0x00060020, n) -- n
cpu.state['PC'].value = 0x3f984e70 -- pcfReadBitmaps arithmetic block
print(string.format("setup: n=%s (n*4 should wrap to 00000004)", hex(n)))
-- 3f985060 is the instruction right after '3f985050 sll 0x2,a11'.
dbg:command("bpset 3f985060,,{ printf \"RESULT n=%08X a11_fosAlloc_arg=%08X nChars=%08X\\n\", d@00060020, a11, d@00040270 ; quit }")
dbg.visible_cpu = cpu
dbg.execution_state = 'run'