Skip to content

Commit

Permalink
chore: rename vars and struct members for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
f1zm0 committed Apr 19, 2023
1 parent 58a25b4 commit 25f21db
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 30 deletions.
8 changes: 4 additions & 4 deletions acheron.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@ type (
)

type options struct {
hasher hashing.HashFunction
hashFunction hashing.HashFunction
}

// WithHashFunction returns an Option that sets a custom hashing or obfuscation function.
func WithHashFunction(f hashing.HashFunction) Option {
return func(o *options) {
o.hasher = f
o.hashFunction = f
}
}

// New returns a new Acheron instance with the given options, or an error if initialization fails.
func New(opts ...Option) (*Acheron, error) {
options := &options{
hasher: hashing.DJB2,
hashFunction: hashing.DJB2,
}
for _, o := range opts {
o(options)
}

if r, err := rvasort.NewResolver(options.hasher); err != nil {
if r, err := rvasort.NewResolver(options.hashFunction); err != nil {
return nil, err
} else {
return &Acheron{
Expand Down
29 changes: 14 additions & 15 deletions internal/resolver/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ type Syscall struct {
TrampolineAddr uintptr
}

// ParseNtdllModule returns a NtModule struct with the relevant infortion
// about the in-ry ntdll.dll dule.
// ParseNtdllModule returns a slice of Syscall structs for all Zw* syscalls from in-memory ntdll.dll.
func ParseNtdllModule(hashFn hashing.HashFunction) []*Syscall {
baseAddr := getNtdllBaseAddr()
exportsBaseAddr := getModuleExportsDirAddr(baseAddr)
Expand All @@ -23,22 +22,22 @@ func ParseNtdllModule(hashFn hashing.HashFunction) []*Syscall {
addressOfNames := getExportsAddressOfNames(baseAddr, exportsBaseAddr)
addressOfNameOrdinals := getExportsAddressOfNameOrdinals(baseAddr, exportsBaseAddr)

zwStubs := make([]*Syscall, 0, numberOfNames/4) // Zw* < 25% of all exports
sysStubs := make([]*Syscall, 0, numberOfNames/4) // Zw* < 25% of all exports
for i := uint32(0); i < numberOfNames; i++ {
fn := memory.ReadCStringAt(baseAddr, memory.ReadDwordAt(addressOfNames, i*4))
if fn[0] != 'Z' || fn[1] != 'w' {
continue
}
fnHash := hashFn(fn)
nameOrd := memory.ReadWordAt(addressOfNameOrdinals, i*2)
rva := memory.ReadDwordAt(addressOfFunctions, uint32(nameOrd*4))
if fn[0] == 'Z' && fn[1] == 'w' {
fn[0] = 'N'
fn[1] = 't'
nameOrd := memory.ReadWordAt(addressOfNameOrdinals, i*2)
rva := memory.ReadDwordAt(addressOfFunctions, uint32(nameOrd*4))

zwStubs = append(zwStubs, &Syscall{
NameHash: fnHash,
RVA: rva,
VA: memory.RVA2VA(baseAddr, rva),
})
sysStubs = append(sysStubs, &Syscall{
NameHash: hashFn(fn),
RVA: rva,
VA: memory.RVA2VA(baseAddr, rva),
})
}
}

return zwStubs
return sysStubs
}
21 changes: 10 additions & 11 deletions internal/resolver/rvasort/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

type ssnSortResolver struct {
hasher hashing.HashFunction
zwStubs map[uint64]*resolver.Syscall
syscallStubs map[uint64]*resolver.Syscall
cleanTrampolines []uintptr
}

Expand All @@ -21,38 +21,37 @@ func NewResolver(h hashing.HashFunction) (resolver.Resolver, error) {
r := &ssnSortResolver{
hasher: h,
}
zws := resolver.ParseNtdllModule(r.hasher) // returns a slice of Syscall structs
ss := resolver.ParseNtdllModule(r.hasher) // returns a slice of Syscall structs

sort.Slice(zws, func(i, j int) bool {
return zws[i].RVA < zws[j].RVA // sort stubs by RVA
sort.Slice(ss, func(i, j int) bool {
return ss[i].RVA < ss[j].RVA // sort stubs by RVA
})

// search clean syscall;ret gadgets to use as syscall trampolines in stubs memory range
for _, st := range zws {
for _, st := range ss {
if trampoline := getTrampoline(st.VA); trampoline != uintptr(0) {
st.TrampolineAddr = trampoline
r.cleanTrampolines = append(r.cleanTrampolines, trampoline)
}
}

r.zwStubs = make(map[uint64]*resolver.Syscall, len(zws))
for idx, st := range zws {
r.syscallStubs = make(map[uint64]*resolver.Syscall, len(ss))
for idx, st := range ss {
st.SSN = uint16(idx)

// keep its default trampoline if it was unhooked, otherwise use one of the clean ones
if st.TrampolineAddr == uintptr(0) {
zws[idx].TrampolineAddr = r.cleanTrampolines[0] // pick random one?
ss[idx].TrampolineAddr = r.cleanTrampolines[0] // pick random one?
}

// add to zwStubs map
r.zwStubs[zws[idx].NameHash] = zws[idx]
r.syscallStubs[ss[idx].NameHash] = ss[idx]
}

return r, nil
}

func (r *ssnSortResolver) GetSyscall(fnHash uint64) (*resolver.Syscall, error) {
if v, ok := r.zwStubs[fnHash]; ok {
if v, ok := r.syscallStubs[fnHash]; ok {
return v, nil
}
return nil, errors.New(fmt.Sprintf("syscall with hash %d not found", fnHash))
Expand Down

0 comments on commit 25f21db

Please sign in to comment.