Skip to content

Commit

Permalink
feat: add lib entrypoint and indirect syscall asm
Browse files Browse the repository at this point in the history
  • Loading branch information
f1zm0 committed Apr 5, 2023
1 parent f3c3edb commit 7db263d
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
30 changes: 30 additions & 0 deletions acheron.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package acheron

import (
"github.com/f1zm0/acheron/internal/resolver"
"github.com/f1zm0/acheron/internal/resolver/ssnsort"
"github.com/f1zm0/acheron/pkg/hashing"
)

type Acheron struct {
resolver resolver.Resolver
}

// New returns a new Acheron instance that can be used as a proxy to perform
// indirect syscalls for native api functions, or an error if the initialization fails.
func New(opts ...Option) (*Acheron, error) {
options := &options{
hasher: hashing.NewDjb2(),
}
for _, o := range opts {
o(options)
}

if r, err := ssnsort.NewResolver(options.hasher); err != nil {
return nil, err
} else {
return &Acheron{
resolver: r,
}, nil
}
}
68 changes: 68 additions & 0 deletions asm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// syscall implementation is a mix of:
// - https://golang.org/src/runtime/sys_windows_amd64.s
// - https://github.com/C-Sto/BananaPhone/blob/master/pkg/BananaPhone/asm_x64.s#L96
// with added support for indirect syscall inspired by:
// - https://github.com/thefLink/RecycledGate

// func execSyscall(ssn uint16, gateAddr uintptr, argh ...uintptr) (errcode uint32)
#define maxargs 16
TEXT ·execIndirectSyscall(SB), $0-56
XORQ AX,AX
MOVW ssn+0(FP), AX
PUSHQ CX

XORQ BX,BX
MOVQ gateAddr+8(FP),BX

//put variadic pointer into SI
MOVQ argh_base+16(FP),SI
//put variadic size into CX
MOVQ argh_len+24(FP),CX

// SetLastError(0).
MOVQ 0x30(GS), DI
MOVL $0, 0x68(DI)
SUBQ $(maxargs*8), SP // room for args

// Fast version, do not store args on the stack.
CMPL CX, $4
JLE loadregs

// Check we have enough room for args.
CMPL CX, $maxargs
JLE 2(PC)
INT $3 // not enough room -> crash

// Copy args to the stack.
MOVQ SP, DI
CLD
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
MOVQ 8(SI), DX
MOVQ 16(SI), R8
MOVQ 24(SI), R9

// Floating point arguments are passed in the XMM
MOVQ CX, X0
MOVQ DX, X1
MOVQ R8, X2
MOVQ R9, X3

MOVQ CX, R10

// jump to gate instead of direct syscall
CALL BX

ADDQ $((maxargs+1)*8), SP

// Return result.
POPQ CX
MOVL AX, errcode+32(FP)
RET
24 changes: 24 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package acheron

import (
"github.com/f1zm0/acheron/pkg/hashing"
)

// Option is a configuration option which can be used within a
// call to the formatter constructor.
type (
Option func(*options)
Options []Option
)

type options struct {
hasher hashing.Hasher
}

// WithHashFunction returns an Option that sets a custom hashing (or obfuscation)
// function that will be used when resolving native api procedures by hash.
func WithHashFunction(f hashing.Hasher) Option {
return func(o *options) {
o.hasher = f
}
}
25 changes: 25 additions & 0 deletions syscall.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package acheron

import (
"errors"
"fmt"
)

// Syscall executes a syscall with the given function hash and arguments.
// Returns the error code and an error if the syscall failed.
func (a *Acheron) Syscall(fnHash int64, args ...uintptr) error {
ssn, err := a.resolver.GetSyscallSSN(fnHash)
if err != nil {
return err
}
gateAddr := a.resolver.GetSafeGate()

if errCode := execIndirectSyscall(ssn, gateAddr, args...); errCode != 0 {
return errors.New(fmt.Sprintf("syscall failed with error code %d", errCode))
}
return nil
}

// execIndirectSyscall function signature for go-asm impelementation.
// returns 0 if the syscall was successful or an error code if the operation failed.
func execIndirectSyscall(ssn uint16, gateAddr uintptr, argh ...uintptr) (errcode uint32)

0 comments on commit 7db263d

Please sign in to comment.