mirror of
https://github.com/BeneficialCode/WinArk
synced 2026-08-09 12:00:31 +00:00
108 lines
2.8 KiB
NASM
108 lines
2.8 KiB
NASM
.code
|
|
|
|
EXTERN g_DriverObject: QWORD
|
|
EXTERN __imp_ObfDereferenceObject: QWORD
|
|
|
|
EXTERN RundownRoutine_Proc : PROC
|
|
EXTERN KernelRoutine_Proc : PROC
|
|
EXTERN NormalRoutine_Proc : PROC
|
|
|
|
; VOID NTAPI KRUNDOWN_ROUTINE(_KAPC* Apc)
|
|
;
|
|
RundownRoutine PROC
|
|
; RCX = pointer to _KAPC
|
|
|
|
sub rsp,28h
|
|
call RundownRoutine_Proc
|
|
add rsp,28h
|
|
|
|
test rax,rax
|
|
jz @@1
|
|
|
|
mov rcx,g_DriverObject
|
|
jmp __imp_ObfDereferenceObject
|
|
|
|
@@1:
|
|
ret
|
|
RundownRoutine ENDP
|
|
|
|
; VOID NTAPI KKERNEL_ROUTINE(_KAPC* Apc, PVOID NormalRoutine, PVOID* NormalContext, PVOID* SystemArgument1, PVOID* SystemArgument2)
|
|
;
|
|
KernelRoutine PROC
|
|
; RCX = pointer to _KAPC
|
|
; RDX = pointer to NormalRoutine
|
|
; R8 = pointer to NormalContext
|
|
; R9 = pointer to SystemArgument1
|
|
; [RSP + 28h] = pointer to SystemArgument2
|
|
|
|
; Mov SystemArgument2 for the forwarded call to KernelRoutine_Proc
|
|
mov rax,[rsp+28h]
|
|
mov [rsp+18h],rax
|
|
|
|
; Save our return address in the shadow stack
|
|
mov rax,[rsp]
|
|
mov [rsp+20h],rax
|
|
|
|
; During call to KernelRoutine: During call to KernelRoutine_Proc:
|
|
;
|
|
; RSP:
|
|
; -10h = return address from KernelRoutine_Proc
|
|
; RSP: -08h = - shadow stack
|
|
; +00h = return address from KernelRoutine +00h = - shadow stack
|
|
; +08h = - shadow stack +08h = - shadow stack
|
|
; +10h = - shadow stack +10h = - shadow stack
|
|
; +18h = - shadow stack +18h = pointer to SystemArgument2
|
|
; +20h = - shadow stack +20h = (saved return addr)
|
|
; +28h = pointer to SystemArgument2
|
|
|
|
; Align stack pointer on the 16-byte boundary for the KernelRoutine_Proc call (and restore it afterwards)
|
|
; push rax = 8 bytes
|
|
; call = 8 bytes
|
|
push rax
|
|
call KernelRoutine_Proc
|
|
test rax,rax
|
|
pop rax
|
|
|
|
; Restore our return address
|
|
mov rax,[rsp+20h]
|
|
mov [rsp],rax
|
|
|
|
; Act depending on return value from function
|
|
jz @@1
|
|
|
|
; Then invoke ObDereferenceObject(g_DriverObject)
|
|
;
|
|
; IMPORTANT: We need to invoke ObfDereferenceObject via a JMP because it will be freeing the driver
|
|
; memory that our code runs from, thus can't return into it via a CALL instruction!
|
|
;
|
|
mov rcx, g_DriverObject
|
|
jmp __imp_ObfDereferenceObject
|
|
|
|
@@1:
|
|
ret
|
|
KernelRoutine ENDP
|
|
|
|
; VOID NTAPI KNORMAL_ROUTINE(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
|
;
|
|
NormalRoutine PROC
|
|
; RCX = NormalContext
|
|
; RDX = SystemArgument1
|
|
; R8 = SystemArgument2
|
|
|
|
; First call our NormalRoutine_Proc from C file
|
|
sub rsp,28h
|
|
call NormalRoutine_Proc
|
|
add rsp,28h
|
|
|
|
; Act depending on return value from function
|
|
test rax,rax
|
|
jz @@1
|
|
|
|
mov rcx, g_DriverObject
|
|
jmp __imp_ObfDereferenceObject
|
|
|
|
@@1:
|
|
ret
|
|
NormalRoutine ENDP
|
|
|
|
END |