gohellsgate

package module
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2023 License: GPL-3.0 Imports: 5 Imported by: 0

README

gohellsgate

A pure golang implementation of hellsgate.

This library allows for both direct and indrect syscalls in golang.

This is the best document out there to understand the technique https://github.com/am0nsec/HellsGate/blob/master/hells-gate.pdf

Also this is a great resource https://github.com/C-Sto/BananaPhone. Stolen the bpSyscall function from this repo. This is a great way to avoid using VirtuallAlloc and CreateThread.

Caveats

It currently works only with Nt functions

Usage

func gohellsgate.IndirectSyscall(ntapi string, argh ...uintptr) (errcode uint32, err error)
func gohellsgate.Syscall(ntapi string, argh ...uintptr) (errcode uint32, err error)

I like to wrap the syscall function in its own function but you don't have to. This is my implementation of NtAllocateVirtualMemorySyscall

In the main function

	addr, err := NtAllocateVirtualMemorySyscall("NtAllocateVirtualMemory", uintptr(pHandle), uintptr(len(sc)), windows.MEM_COMMIT|windows.MEM_RESERVE, flProtect, verbose)
	if err != nil {
		return fmt.Errorf("NtAllocateVirtualMemorySyscall: Failed to allocate memory %v\n", err)
	}

Wrapper function. If you would like to use a direct syscall instead of indirect simply change from gohellsgate.IndrectSyscall to gohellsgate.Syscall

func NtAllocateVirtualMemorySyscall(ntapi string, handle uintptr, length uintptr, alloctype int, protect int, verbose bool) (uintptr, error) {
	/*
			__kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(
		  [in]      HANDLE    ProcessHandle, 1
		  [in, out] PVOID     *BaseAddress,  2
		  [in]      ULONG_PTR ZeroBits,      3
		  [in, out] PSIZE_T   RegionSize,    4
		  [in]      ULONG     AllocationType,5
		  [in]      ULONG     Protect        6
		);*/
	// syscall for NtAllocateVirtualMemory

	var BaseAddress uintptr

	err1, err := gohellsgate.IndirectSyscall(
		ntapi,
		uintptr(unsafe.Pointer(handle)),       //1
		uintptr(unsafe.Pointer(&BaseAddress)), //2
		0,                                     //3
		uintptr(unsafe.Pointer(&length)),      //4
		uintptr(0x3000),                       //5
		0x40,                                  //6
	)
	if err != nil {
		return 0, fmt.Errorf("1 %s %x\n", err, err1)
	}
	if verbose {
		fmt.Printf("[+] Allocated address from NtAllocateVirtualMemory %p\n", unsafe.Pointer(BaseAddress))
	}

	return BaseAddress, nil
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetBaseAddrOfLoadedDll

func GetBaseAddrOfLoadedDll(name string) (uintptr, error)

returns address of a loaded module Example : addr, err := getBaseAddrOfLoadedDll("ntdll.dll")

func GetSyscallFromName added in v0.9.0

func GetSyscallFromName(function string, exports *[]Exportfunc) (byte, uintptr, error)

func GetSyscallNumbers

func GetSyscallNumbers(exports *[]Exportfunc) error

func IndirectSyscall added in v0.9.0

func IndirectSyscall(ntapi string, argh ...uintptr) (errcode uint32, err error)

func ListDllFromPEB

func ListDllFromPEB() []dllstruct

adds all loaded modules and their base addresses in a slice

func PrintModules

func PrintModules()

prints loaded modules in the current process

func Syscall

func Syscall(ntapi string, argh ...uintptr) (errcode uint32, err error)

Syscall calls the system function specified by callid with n arguments. Works much the same as syscall.Syscall - return value is the call error code and optional error text. All args are uintptrs to make it easy.

func UnhookSyscalls

func UnhookSyscalls(exports *[]Exportfunc) error

Beta Version, This needs a lot of testing. I only tested this on win11 x64 and limited AVs

Types

type Exportfunc added in v0.7.0

type Exportfunc struct {
	// contains filtered or unexported fields
}

func GetModuleExports

func GetModuleExports(name string) ([]Exportfunc, error)

Loops through the exports and returns it into a slice Any future queries or any unhooking will be happening on the slice and not the dll itself

type IMAGE_EXPORT_DIRECTORY

type IMAGE_EXPORT_DIRECTORY struct {
	Characteristics       uint32 // 0x0
	TimeDateStamp         uint32 // 0x4
	MajorVersion          uint16 // 0x8
	MinorVersion          uint16 // 0xa
	Name                  uint32 // 0xc
	Base                  uint32 // 0x10
	NumberOfFunctions     uint32 // 0x14
	NumberOfNames         uint32 // 0x18
	AddressOfFunctions    uint32 // 0x1c
	AddressOfNames        uint32 // 0x20
	AddressOfNameOrdinals uint32 // 0x24
}

func GetImageExportDirectory

func GetImageExportDirectory(name string) (*IMAGE_EXPORT_DIRECTORY, error)

Get Image Export directory. We are interested in - AddressofFunctions - AddressOfNames - AddressOFNameOrdinals (maybe in the future) - Number of functions

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL