From 1a673e9bdf6a1a579961474a10c70da0d1486912 Mon Sep 17 00:00:00 2001 From: Gahaku Date: Wed, 1 Mar 2023 17:38:41 +0900 Subject: [PATCH 1/2] Fixed out-of-range memory accesses --- .../BizHawk/Utility/Memory.lua | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua b/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua index 2599db3..a2ffa1a 100644 --- a/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua +++ b/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua @@ -1,17 +1,38 @@ Memory = {} -Memory.read_u32_be = memory.read_u32_be -Memory.read_u32_le = memory.read_u32_le -Memory.read_s32_be = memory.read_s32_be -Memory.read_s32_le = memory.read_s32_le -Memory.read_u16_be = memory.read_u16_be -Memory.read_u16_le = memory.read_u16_le -Memory.read_s16_be = memory.read_s16_be -Memory.read_s16_le = memory.read_s16_le -Memory.read_u8 = memory.read_u8 -Memory.read_s8 = memory.read_s8 -Memory.read_bytes_as_array = memory.read_bytes_as_array -Memory.read_bytes_as_dict = memory.read_bytes_as_dict +-- Memory reads outside the range will cause performance problems, +-- so in such cases, no reads are performed and 0 is returned. +local function to_checked_read(func, size) + return function(addr, dom) + if addr < 0 or addr + size > 0x100000000 then + return 0 + end + return func(addr, dom) + end +end + +Memory.read_u32_be = to_checked_read(memory.read_u32_be, 4) +Memory.read_u32_le = to_checked_read(memory.read_u32_le, 4) +Memory.read_s32_be = to_checked_read(memory.read_s32_be, 4) +Memory.read_s32_le = to_checked_read(memory.read_s32_le, 4) +Memory.read_u16_be = to_checked_read(memory.read_u16_be, 2) +Memory.read_u16_le = to_checked_read(memory.read_u16_le, 2) +Memory.read_s16_be = to_checked_read(memory.read_s16_be, 2) +Memory.read_s16_le = to_checked_read(memory.read_s16_le, 2) +Memory.read_u8 = to_checked_read(memory.read_u8, 1) +Memory.read_s8 = to_checked_read(memory.read_s8, 1) +Memory.read_bytes_as_array = function(addr, length, dom) + if addr < 0 or addr + length > 0x100000000 then + return {} + end + return memory.read_bytes_as_array(addr, length, dom) +end +Memory.read_bytes_as_dict = function(addr, length, dom) + if addr < 0 or addr + length > 0x100000000 then + return {} + end + return memory.read_bytes_as_dict(addr, length, dom) +end function Memory:read_8(addr,dom,signed) if signed then return self:read_s8(addr,dom) end From 73814726ea2f690330d8d1179421c8c3680ea6f6 Mon Sep 17 00:00:00 2001 From: Gahaku Date: Mon, 6 Mar 2023 23:58:42 +0900 Subject: [PATCH 2/2] Added boundary checks to memory write --- .../BizHawk/Utility/Memory.lua | 94 +++++++++++++------ 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua b/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua index a2ffa1a..104fa15 100644 --- a/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua +++ b/universal-ds-lua-script/EmulatorDependencies/BizHawk/Utility/Memory.lua @@ -2,33 +2,65 @@ Memory = {} -- Memory reads outside the range will cause performance problems, -- so in such cases, no reads are performed and 0 is returned. -local function to_checked_read(func, size) - return function(addr, dom) - if addr < 0 or addr + size > 0x100000000 then - return 0 - end - return func(addr, dom) - end +function Memory.read_u32_be(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFC) then return 0 end + return memory.read_u32_be(addr, dom) +end + +function Memory.read_u32_le(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFC) then return 0 end + return memory.read_u32_le(addr, dom) +end + +function Memory.read_s32_be(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFC) then return 0 end + return memory.read_s32_be(addr, dom) end -Memory.read_u32_be = to_checked_read(memory.read_u32_be, 4) -Memory.read_u32_le = to_checked_read(memory.read_u32_le, 4) -Memory.read_s32_be = to_checked_read(memory.read_s32_be, 4) -Memory.read_s32_le = to_checked_read(memory.read_s32_le, 4) -Memory.read_u16_be = to_checked_read(memory.read_u16_be, 2) -Memory.read_u16_le = to_checked_read(memory.read_u16_le, 2) -Memory.read_s16_be = to_checked_read(memory.read_s16_be, 2) -Memory.read_s16_le = to_checked_read(memory.read_s16_le, 2) -Memory.read_u8 = to_checked_read(memory.read_u8, 1) -Memory.read_s8 = to_checked_read(memory.read_s8, 1) -Memory.read_bytes_as_array = function(addr, length, dom) - if addr < 0 or addr + length > 0x100000000 then +function Memory.read_s32_le(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFC) then return 0 end + return memory.read_s32_le(addr, dom) +end + +function Memory.read_u16_be(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFE) then return 0 end + return memory.read_u16_be(addr, dom) +end + +function Memory.read_u16_le(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFE) then return 0 end + return memory.read_u16_le(addr, dom) +end + +function Memory.read_s16_be(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFE) then return 0 end + return memory.read_s16_be(addr, dom) +end + +function Memory.read_s16_le(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFE) then return 0 end + return memory.read_s16_le(addr, dom) +end + +function Memory.read_u8(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFF) then return 0 end + return memory.read_u8(addr, dom) +end + +function Memory.read_s8(addr, dom) + if (addr < 0 or addr > 0xFFFFFFFF) then return 0 end + return memory.read_s8(addr, dom) +end + +function Memory.read_bytes_as_array(addr, length, dom) + if (addr < 0 or addr + length > 0x100000000) then return {} end return memory.read_bytes_as_array(addr, length, dom) end -Memory.read_bytes_as_dict = function(addr, length, dom) - if addr < 0 or addr + length > 0x100000000 then + +function Memory.read_bytes_as_dict(addr, length, dom) + if (addr < 0 or addr + length > 0x100000000) then return {} end return memory.read_bytes_as_dict(addr, length, dom) @@ -82,46 +114,47 @@ function Memory:readascii(addr,length) end function Memory:write_u8(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFF) then return end mainmemory.writebyte(addr-0x2000000, val) end function Memory:write_u16_be(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFE) then return end mainmemory.write_u16_be(addr-0x2000000, val) end function Memory:write_u16_le(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFE) then return end mainmemory.write_u16_le(addr-0x2000000, val) end function Memory:write_s16_le(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFE) then return end mainmemory.write_s16_le(addr-0x2000000, val) end function Memory:write_u32_be(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFC) then return end mainmemory.write_u32_be(addr-0x2000000, val) end function Memory:write_u32_le(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFC) then return end mainmemory.write_u32_le(addr-0x2000000, val) end function Memory:write_s32_le(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr > 0x2FFFFFC) then return end mainmemory.write_s32_le(addr-0x2000000, val) end function Memory:write_bytes_as_array(addr, val) - if (addr < 0x2000000) then return end + if (addr < 0x2000000 or addr + #val > 0x3000000) then return end mainmemory.write_bytes_as_array(addr-0x2000000, val) end -function Memory:getByteRange_be(table,index, size) +function Memory:getByteRange_be(table, index, size) + if (index + size > #table) then return 0 end local shift = (size - 1) * 8 local value = 0 for i = index, index + size - 1 do @@ -132,6 +165,7 @@ function Memory:getByteRange_be(table,index, size) end function Memory:getByteRange(table, index, size) + if (index + size > #table) then return 0 end local shift = 0 local value = 0 for i = index, index + size - 1 do