137 lines
5.0 KiB
NASM
137 lines
5.0 KiB
NASM
|
|
.code
|
||
|
|
|
||
|
|
; A function can be called like so
|
||
|
|
;
|
||
|
|
; Spoof(arg1, arg2, arg3, arg4, ¶m, function, (PVOID)0);
|
||
|
|
;
|
||
|
|
; Param is a struct containing some necessary information for the call to have fake frames added.
|
||
|
|
; The 6th argument is a pointer to the function to execute
|
||
|
|
; The 7th argument specifies the number of args to pass to the stack. It has to be at an 8 byte size.
|
||
|
|
|
||
|
|
Spoof PROC
|
||
|
|
pop rax ; Real return address in rax
|
||
|
|
|
||
|
|
mov r10, rdi ; Store OG rdi in r10
|
||
|
|
mov r11, rsi ; Store OG rsi in r11
|
||
|
|
|
||
|
|
mov rdi, qword ptr [rsp + 32] ; Storing struct in rdi
|
||
|
|
mov rsi, qword ptr [rsp + 40] ; Storing function to call
|
||
|
|
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
; Storing our original registers
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
|
||
|
|
mov qword ptr [rdi + 24], r10 ; Storing OG rdi into param
|
||
|
|
mov qword ptr [rdi + 88], r11 ; Storing OG rsi into param
|
||
|
|
mov qword ptr [rdi + 96], r12 ; Storing OG r12 into param
|
||
|
|
mov qword ptr [rdi + 104], r13 ; Storing OG r13 into param
|
||
|
|
mov qword ptr [rdi + 112], r14 ; Storing OG r14 into param
|
||
|
|
mov qword ptr [rdi + 120], r15 ; Storing OG r15 into param
|
||
|
|
|
||
|
|
mov r12, rax ; OG code used r12 for ret addr
|
||
|
|
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
; Prepping to move stack args
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
|
||
|
|
xor r11, r11 ; r11 = # of args pushed
|
||
|
|
mov r13, qword ptr [rsp + 30h] ; r13 = total args to push
|
||
|
|
|
||
|
|
mov r14, 200h ; Initial offset
|
||
|
|
add r14, 8
|
||
|
|
add r14, qword ptr [rdi + 56] ; Add RUTS stack size
|
||
|
|
add r14, qword ptr [rdi + 48] ; Add BTIT stack size
|
||
|
|
add r14, qword ptr [rdi + 32] ; Add gadget frame size
|
||
|
|
sub r14, 20h ; Adjust for first stack arg
|
||
|
|
|
||
|
|
mov r10, rsp
|
||
|
|
add r10, 30h ; Stack args base address
|
||
|
|
|
||
|
|
looping_label:
|
||
|
|
xor r15, r15
|
||
|
|
cmp r11, r13
|
||
|
|
je finish_label
|
||
|
|
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
; Calculate target stack position
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
sub r14, 8
|
||
|
|
mov r15, rsp
|
||
|
|
sub r15, r14
|
||
|
|
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
; Move stack argument
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
add r10, 8
|
||
|
|
push qword ptr [r10]
|
||
|
|
pop qword ptr [r15]
|
||
|
|
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
; Increment counter and loop
|
||
|
|
; ---------------------------------------------------------------------
|
||
|
|
add r11, 1
|
||
|
|
jmp looping_label
|
||
|
|
|
||
|
|
finish_label:
|
||
|
|
|
||
|
|
; ----------------------------------------------------------------------
|
||
|
|
; Create working space and setup fake frames
|
||
|
|
; ----------------------------------------------------------------------
|
||
|
|
sub rsp, 200h
|
||
|
|
push 0
|
||
|
|
|
||
|
|
; RtlUserThreadStart frame
|
||
|
|
sub rsp, qword ptr [rdi + 56]
|
||
|
|
mov r11, qword ptr [rdi + 64]
|
||
|
|
mov qword ptr [rsp], r11
|
||
|
|
|
||
|
|
; BaseThreadInitThunk frame
|
||
|
|
sub rsp, qword ptr [rdi + 32]
|
||
|
|
mov r11, qword ptr [rdi + 40]
|
||
|
|
mov qword ptr [rsp], r11
|
||
|
|
|
||
|
|
; Gadget frame -- `jmp QWORD PTR [rbx]`
|
||
|
|
sub rsp, qword ptr [rdi + 48]
|
||
|
|
mov r11, qword ptr [rdi + 80]
|
||
|
|
mov qword ptr [rsp], r11
|
||
|
|
|
||
|
|
; ----------------------------------------------------------------------
|
||
|
|
; Prepare for function call and fixup
|
||
|
|
; ----------------------------------------------------------------------
|
||
|
|
mov r11, rsi ; Function to call
|
||
|
|
mov qword ptr [rdi + 8], r12 ; Store real return address
|
||
|
|
mov qword ptr [rdi + 16], rbx ; Store original RBX
|
||
|
|
lea rbx, fixup_label ; Get fixup address
|
||
|
|
mov qword ptr [rdi], rbx ; Store fixup in struct
|
||
|
|
mov rbx, rdi ; Param struct pointer
|
||
|
|
|
||
|
|
; Prepare syscall (if needed)
|
||
|
|
mov r10, rcx
|
||
|
|
mov rax, qword ptr [rdi + 72]
|
||
|
|
|
||
|
|
jmp r11 ; Jump to target function
|
||
|
|
|
||
|
|
fixup_label:
|
||
|
|
mov rcx, rbx ; Restore param struct
|
||
|
|
|
||
|
|
; Cleanup stack frames
|
||
|
|
add rsp, 200h
|
||
|
|
add rsp, qword ptr [rbx + 48]
|
||
|
|
add rsp, qword ptr [rbx + 32]
|
||
|
|
add rsp, qword ptr [rbx + 56]
|
||
|
|
|
||
|
|
; Restore original registers
|
||
|
|
mov rbx, qword ptr [rcx + 16]
|
||
|
|
mov rdi, qword ptr [rcx + 24]
|
||
|
|
mov rsi, qword ptr [rcx + 88]
|
||
|
|
mov r12, qword ptr [rcx + 96]
|
||
|
|
mov r13, qword ptr [rcx + 104]
|
||
|
|
mov r14, qword ptr [rcx + 112]
|
||
|
|
mov r15, qword ptr [rcx + 120]
|
||
|
|
|
||
|
|
jmp qword ptr [rcx + 8] ; Jump to original return address
|
||
|
|
|
||
|
|
Spoof ENDP
|
||
|
|
|
||
|
|
END
|