uint64_t X64Call(uint64_t proc, uint32_t argc, ...) {
uint64_t
*
args
=
(uint64_t
*
)(&argc
+
1
);
uint64_t ret
=
0
;
static uint8_t code[]
=
{
/
*
[bits
32
]
push ebx
mov ebx, esp
and
esp,
0xFFFFFFF8
push
0x33
push _next_x64_code
retf
*
/
0x53
,
0x89
,
0xE3
,
0x83
,
0xE4
,
0xF8
,
0x6A
,
0x33
,
0x68
,
0x78
,
0x56
,
0x34
,
0x12
,
0xCB
,
/
*
[bits
64
]
push rsi
push rdi
mov rsi, args
mov rcx, [rsi]
mov rdx, [rsi
+
8
]
mov r8, [rsi
+
16
]
mov r9, [rsi
+
24
]
mov rax, argc
args_start:
cmp
rax,
4
jle args_end
mov rdi, [rsi
+
8
*
rax
-
8
]
push rdi
dec rax
jmp args_start
args_end:
mov rax, proc
sub rsp,
32
call rax
mov rdi, &ret
mov [rdi], rax
pop rdi
pop rsi
*
/
0x56
,
0x57
,
0x48
,
0xBE
,
0x88
,
0x77
,
0x66
,
0x55
,
0x44
,
0x33
,
0x22
,
0x11
,
0x48
,
0x8B
,
0xE
,
0x48
,
0x8B
,
0x56
,
0x8
,
0x4C
,
0x8B
,
0x46
,
0x10
,
0x4C
,
0x8B
,
0x4E
,
0x18
,
0x48
,
0xB8
,
0x88
,
0x77
,
0x66
,
0x55
,
0x44
,
0x33
,
0x22
,
0x11
,
0x48
,
0x83
,
0xF8
,
0x4
,
0x7E
,
0xB
,
0x48
,
0x8B
,
0x7C
,
0xC6
,
0xF8
,
0x57
,
0x48
,
0xFF
,
0xC8
,
0xEB
,
0xEF
,
0x48
,
0xB8
,
0x88
,
0x77
,
0x66
,
0x55
,
0x44
,
0x33
,
0x22
,
0x11
,
0x48
,
0x83
,
0xEC
,
0x20
,
0xFF
,
0xD0
,
0x48
,
0xBF
,
0x88
,
0x77
,
0x66
,
0x55
,
0x44
,
0x33
,
0x22
,
0x11
,
0x48
,
0x89
,
0x7
,
0x5F
,
0x5E
,
/
*
[bits
64
]
push
0x23
push _next_x86_code
retfq
*
/
0x6A
,
0x23
,
0x68
,
0x78
,
0x56
,
0x34
,
0x12
,
0x48
,
0xCB
,
/
*
[bits
32
]
mov esp, ebx
pop ebx
ret
*
/
0x89
,
0xDC
,
0x5B
,
0xC3
};
static uint32_t ptr
=
NULL;
if
(!ptr) {
ptr
=
(uint32_t)VirtualAlloc(NULL, sizeof(code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
for
(
int
i
=
0
; i < sizeof(code); i
+
+
) ((PBYTE)ptr)[i]
=
code[i];
}
*
(uint32_t
*
)(ptr
+
9
)
=
ptr
+
14
;
*
(uint64_t
*
)(ptr
+
18
)
=
(uint64_t)args;
*
(uint64_t
*
)(ptr
+
43
)
=
(uint64_t)argc;
*
(uint64_t
*
)(ptr
+
70
)
=
proc;
*
(uint64_t
*
)(ptr
+
86
)
=
(uint64_t)&ret;
*
(uint32_t
*
)(ptr
+
102
)
=
ptr
+
108
;
((void(
*
)())ptr)();
return
ret;
}