[SECTION .text]
Spoof:
pop r11
add rsp, 8
mov rax, [rsp + 24]
mov r10, [rax]
mov [rsp], r10
mov r10, [rax + 8]
mov [rax + 8], r11
mov [rax + 16], rbx
lea rbx, [fixup]
mov [rax], rbx
mov rbx, rax
jmp r10
fixup:
sub rsp, 16
mov rcx, rbx
mov rbx, [rcx + 16]
jmp QWORD [rcx + 8]
PVOID SpoofRetAddr( PVOID Function, HANDLE Module, ULONG Size, PVOID a, PVOID b, PVOID c, PVOID d, PVOID e, PVOID f, PVOID g, PVOID h )
{
PVOID Trampoline = NULL;
if ( Function != NULL )
{
Trampoline = FindGadget( Module, Size );
if ( Trampoline != NULL )
{
PRM param = { Trampoline, Function };
return ( ( PVOID( * ) ( PVOID, PVOID, PVOID, PVOID, PPRM, PVOID, PVOID, PVOID, PVOID, PVOID ) ) ( ( PVOID ) Spoof ) ) ( a, b, c, d, ¶m, NULL, e, f, g, h );
}
}
return NULL;
}
SpoofRetAddr
Function
⇒ Function to callModule
⇒ Module to search for a jmp rbx
gadgetSize
⇒ Amount of bytes to look through within the module to find the gadgetFindGadget
to find a jmp rbx
gadget within Size
bytes of Module
param
is use to hold the gadget and the functionSpoof
is then called, passing in the first 4 arguments, then param
, NULL
, and the other 4 argumentsSpoof
https://www.unknowncheats.me/forum/anti-cheat-bypass/268039-x64-return-address-spoofing-source-explanation.html
rax
is stored in r10
rsp
is now the address in r10
r10
is now the value at the address rax + 8
pop r11 ; Store return address in r11 (and decrement rsp by 8)
add rsp, 8 ; RSP is pointing back to original spot on stack
mov rax, [rsp + 24] ; Copy value at rsp+24 inside rax
mov r10, [rax] ; Copy value at rax inside r10
mov [rsp], r10 ; Copy address at r10 into value at rsp
mov r10, [rax + 8] ; Copy value at rax + 8 into r10
mov [rax + 8], r11 ; Copy address at r11 into value at rax + 8
mov [rax + 16], rbx ; Copy address at rbx into value at rax + 16
lea rbx, [fixup] ; Load the address of fixup into the rbx
mov [rax], rbx ; Copy address at rbx into value at rax
mov rbx, rax ; Copy address at rax into address at rbx
jmp r10
param = { 0xGadgetAddr, MessageBoxA } // 0xParam
pText = "bruh"; // 0xText
Spoof(0, pText, pText, 1, ¶m, NULL, 0, 0, 0, 0);