Created
September 3, 2022 02:20
-
-
Save praydog/4b9e456c0c8e6bd516d177d0b8a6de3b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function allocate_string(str) | |
local p = regenny:process() | |
local str_ptr = p:allocate_rwx(0, #str + 1) | |
for i=1, #str do | |
p:write_uint8(str_ptr + (i - 1), string.byte(str, i)) | |
end | |
p:write_uint8(str_ptr + #str, 0) | |
return str_ptr | |
end | |
function call(addr, rcx, rdx, r8, r9) | |
rcx = rcx or 0 | |
rdx = rdx or 0 | |
r8 = r8 or 0 | |
r9 = r9 or 0 | |
if type(rcx) == "string" then | |
rcx = allocate_string(rcx) | |
end | |
if type(rdx) == "string" then | |
rdx = allocate_string(rdx) | |
end | |
if type(r8) == "string" then | |
r8 = allocate_string(r8) | |
end | |
if type(r9) == "string" then | |
r9 = allocate_string(r9) | |
end | |
--[[ | |
movabs rcx, 0 | |
movabs rdx, 0 | |
movabs r8, 0 | |
movabs r9, 0 | |
movabs rax, 0 | |
]] | |
local sub_rsp_40 = { 0x48, 0x83, 0xEC, 0x28 } | |
local mov_rcx_prologue = { 0x48, 0xB9 } | |
local mov_rdx_prologue = { 0x48, 0xBA } | |
local mov_r8_prologue = { 0x49, 0xB8 } | |
local mov_r9_prologue = { 0x49, 0xB9 } | |
local mov_rax_prologue = { 0x48, 0xB8 } | |
local call_rax = { 0xFF, 0xD0 } | |
local add_rsp_40 = { 0x48, 0x83, 0xC4, 0x28 } | |
local ret = { 0xC3 } | |
-- turn rcx, rdx, r8, r9 into a table | |
-- the arguments passed are int64s, so we need to split them into 8 bytes | |
local int64_to_little_endian = function(x) | |
local bytes = {} | |
for i=1, 8 do | |
bytes[i] = x & 0xFF | |
x = x >> 8 | |
end | |
return bytes | |
end | |
local rcx_bytes = int64_to_little_endian(rcx) | |
local rdx_bytes = int64_to_little_endian(rdx) | |
local r8_bytes = int64_to_little_endian(r8) | |
local r9_bytes = int64_to_little_endian(r9) | |
local rax_bytes = int64_to_little_endian(addr) | |
local concat = function(x, y) | |
for i=1, #y do | |
table.insert(x, y[i]) | |
end | |
end | |
local instructions = {} | |
concat(mov_rcx_prologue, rcx_bytes) | |
concat(mov_rdx_prologue, rdx_bytes) | |
concat(mov_r8_prologue, r8_bytes) | |
concat(mov_r9_prologue, r9_bytes) | |
concat(mov_rax_prologue, rax_bytes) | |
concat(instructions, sub_rsp_40) | |
concat(instructions, mov_rcx_prologue) | |
concat(instructions, mov_rdx_prologue) | |
concat(instructions, mov_r8_prologue) | |
concat(instructions, mov_r9_prologue) | |
concat(instructions, mov_rax_prologue) | |
concat(instructions, call_rax) | |
concat(instructions, add_rsp_40) | |
concat(instructions, ret) | |
local p = regenny:process() | |
local code_ptr = p:allocate_rwx(0, #instructions) | |
for i=1, #instructions do | |
p:write_uint8(code_ptr + (i - 1), instructions[i]) | |
end | |
print(string.format("%x", code_ptr)) | |
p:create_remote_thread(code_ptr, 0) | |
end | |
function get_virtual(obj, index) | |
if not obj then return nil end | |
local p = regenny:process() | |
local vtable = p:read_uint64(obj) | |
if not vtable then return nil end | |
local func = p:read_uint64(vtable + (index * 8)) | |
if not func then return nil end | |
return func | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment