Initial commit

This commit is contained in:
2026-05-31 01:09:34 +01:00
commit 1d51b29b92
31 changed files with 4874 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
package syscallobf
import (
"crypto/rand"
"encoding/binary"
"sync"
)
var (
dispatchKey uint64
dispatchOnce sync.Once
)
func initDispatchKey() {
dispatchOnce.Do(func() {
var buf [8]byte
rand.Read(buf[:])
dispatchKey = binary.LittleEndian.Uint64(buf[:])
if dispatchKey == 0 {
dispatchKey = 0xDEADBEEFCAFEBABE
}
})
}
func EncodeTrap(num uintptr) uintptr {
initDispatchKey()
return uintptr(uint64(num) ^ dispatchKey)
}
func DecodeTrap(encoded uintptr) uintptr {
return uintptr(uint64(encoded) ^ dispatchKey)
}
type encodedSyscall struct {
encoded uintptr
}
func NewEncodedSyscall(num uintptr) encodedSyscall {
return encodedSyscall{encoded: EncodeTrap(num)}
}
func (e encodedSyscall) Trap() uintptr {
return DecodeTrap(e.encoded)
}
+39
View File
@@ -0,0 +1,39 @@
package syscallobf
import "syscall"
func ObfPtrace(request int, pid uintptr, addr uintptr, data uintptr) (uintptr, uintptr, syscall.Errno) {
return 0, 0, syscall.ENOSYS
}
func ObfGetpid() int {
return 0
}
func ObfKill(pid int, sig int) error {
return syscall.ENOSYS
}
func ObfOpen(path string, flags int, mode int) (int, error) {
return -1, syscall.ENOSYS
}
func ObfClose(fd int) error {
return syscall.ENOSYS
}
func ObfRead(fd int, buf []byte) (int, error) {
return 0, syscall.ENOSYS
}
func ObfMmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset uintptr) (uintptr, error) {
return 0, syscall.ENOSYS
}
func ObfMprotect(addr uintptr, length uintptr, prot int) error {
return syscall.ENOSYS
}
func ObfLseek(fd int, offset int64, whence int) (int64, error) {
return 0, syscall.ENOSYS
}
+100
View File
@@ -0,0 +1,100 @@
package syscallobf
import (
"syscall"
"unsafe"
)
var (
encPtraceTrap = NewEncodedSyscall(101)
encGetpidTrap = NewEncodedSyscall(39)
encKillTrap = NewEncodedSyscall(62)
encOpenTrap = NewEncodedSyscall(2)
encCloseTrap = NewEncodedSyscall(3)
encReadTrap = NewEncodedSyscall(0)
encMmapTrap = NewEncodedSyscall(9)
encMprotectTrap = NewEncodedSyscall(10)
encLseekTrap = NewEncodedSyscall(8)
)
func ObfPtrace(request int, pid uintptr, addr uintptr, data uintptr) (uintptr, uintptr, syscall.Errno) {
trap := encPtraceTrap.Trap()
return syscall.RawSyscall6(trap, uintptr(request), pid, addr, data, 0, 0)
}
func ObfGetpid() int {
trap := encGetpidTrap.Trap()
r1, _, _ := syscall.RawSyscall(trap, 0, 0, 0)
return int(r1)
}
func ObfKill(pid int, sig int) error {
trap := encKillTrap.Trap()
_, _, errno := syscall.RawSyscall(trap, uintptr(pid), uintptr(sig), 0)
if errno != 0 {
return errno
}
return nil
}
func ObfOpen(path string, flags int, mode int) (int, error) {
trap := encOpenTrap.Trap()
pathBytes, err := syscall.BytePtrFromString(path)
if err != nil {
return -1, err
}
r1, _, errno := syscall.RawSyscall(trap, uintptr(unsafe.Pointer(pathBytes)), uintptr(flags), uintptr(mode))
if errno != 0 {
return int(r1), errno
}
return int(r1), nil
}
func ObfClose(fd int) error {
trap := encCloseTrap.Trap()
_, _, errno := syscall.RawSyscall(trap, uintptr(fd), 0, 0)
if errno != 0 {
return errno
}
return nil
}
func ObfRead(fd int, buf []byte) (int, error) {
trap := encReadTrap.Trap()
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
r1, _, errno := syscall.RawSyscall(trap, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(buf)))
if errno != 0 {
return int(r1), errno
}
return int(r1), nil
}
func ObfMmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset uintptr) (uintptr, error) {
trap := encMmapTrap.Trap()
r1, _, errno := syscall.Syscall6(trap, addr, length, uintptr(prot), uintptr(flags), uintptr(fd), offset)
if errno != 0 {
return 0, errno
}
return r1, nil
}
func ObfMprotect(addr uintptr, length uintptr, prot int) error {
trap := encMprotectTrap.Trap()
_, _, errno := syscall.RawSyscall(trap, addr, length, uintptr(prot))
if errno != 0 {
return errno
}
return nil
}
func ObfLseek(fd int, offset int64, whence int) (int64, error) {
trap := encLseekTrap.Trap()
r1, _, errno := syscall.RawSyscall(trap, uintptr(fd), uintptr(offset), uintptr(whence))
if errno != 0 {
return int64(r1), errno
}
return int64(r1), nil
}
+26
View File
@@ -0,0 +1,26 @@
package syscallobf
// ObfuscatedCall wraps a syscall with obfuscated number
type ObfuscatedCall struct {
encodedNum [4]byte
key [4]byte
}
func (o *ObfuscatedCall) Num() uintptr {
return uintptr(o.encodedNum[0]^o.key[0]) |
uintptr(o.encodedNum[1]^o.key[1])<<8 |
uintptr(o.encodedNum[2]^o.key[2])<<16 |
uintptr(o.encodedNum[3]^o.key[3])<<24
}
func encode(num uintptr, key [4]byte) ObfuscatedCall {
return ObfuscatedCall{
encodedNum: [4]byte{
byte(num&0xff) ^ key[0],
byte((num>>8)&0xff) ^ key[1],
byte((num>>16)&0xff) ^ key[2],
byte((num>>24)&0xff) ^ key[3],
},
key: key,
}
}
+63
View File
@@ -0,0 +1,63 @@
//go:build darwin
package syscallobf
import (
"syscall"
"unsafe"
)
func OpenFile(path string, flags int, mode uint32) (int, error) {
return syscall.Open(path, flags, mode)
}
func SysRead(fd int, buf []byte) (int, error) {
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
n, _, errno := syscall.Syscall(
uintptr(syscall.SYS_READ),
uintptr(fd),
uintptr(unsafe.Pointer(p)),
uintptr(len(buf)),
)
if errno != 0 {
return int(n), errno
}
return int(n), nil
}
func SysWrite(fd int, buf []byte) (int, error) {
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
n, _, errno := syscall.Syscall(
uintptr(syscall.SYS_WRITE),
uintptr(fd),
uintptr(unsafe.Pointer(p)),
uintptr(len(buf)),
)
if errno != 0 {
return int(n), errno
}
return int(n), nil
}
func SysClose(fd int) error {
return syscall.Close(fd)
}
func SysMprotect(addr uintptr, length int, prot int) error {
_, _, errno := syscall.Syscall(
uintptr(syscall.SYS_MPROTECT),
addr,
uintptr(length),
uintptr(prot),
)
if errno != 0 {
return errno
}
return nil
}
+122
View File
@@ -0,0 +1,122 @@
//go:build linux
package syscallobf
import (
"crypto/rand"
"runtime"
"syscall"
"unsafe"
)
var key [4]byte
var (
obfOpenat ObfuscatedCall
obfRead ObfuscatedCall
obfWrite ObfuscatedCall
obfClose ObfuscatedCall
obfMprotect ObfuscatedCall
)
func init() {
if _, err := rand.Read(key[:]); err != nil {
panic("syscallobf: failed to generate random key: " + err.Error())
}
if runtime.GOARCH == "arm64" {
obfOpenat = encode(56, key)
obfRead = encode(63, key)
obfWrite = encode(64, key)
obfClose = encode(57, key)
obfMprotect = encode(226, key)
} else {
obfOpenat = encode(257, key)
obfRead = encode(0, key)
obfWrite = encode(1, key)
obfClose = encode(3, key)
obfMprotect = encode(10, key)
}
}
//go:nosplit
func OpenFile(path string, flags int, mode uint32) (int, error) {
p, err := syscall.BytePtrFromString(path)
if err != nil {
return 0, err
}
r1, _, errno := syscall.Syscall(
obfOpenat.Num(),
uintptr(syscall.AT_FDCWD),
uintptr(unsafe.Pointer(p)),
uintptr(flags)|uintptr(mode),
)
if errno != 0 {
return int(r1), errno
}
return int(r1), nil
}
//go:nosplit
func SysRead(fd int, buf []byte) (int, error) {
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
r1, _, errno := syscall.Syscall(
obfRead.Num(),
uintptr(fd),
uintptr(unsafe.Pointer(p)),
uintptr(len(buf)),
)
if errno != 0 {
return int(r1), errno
}
return int(r1), nil
}
//go:nosplit
func SysWrite(fd int, buf []byte) (int, error) {
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
r1, _, errno := syscall.Syscall(
obfWrite.Num(),
uintptr(fd),
uintptr(unsafe.Pointer(p)),
uintptr(len(buf)),
)
if errno != 0 {
return int(r1), errno
}
return int(r1), nil
}
//go:nosplit
func SysClose(fd int) error {
_, _, errno := syscall.Syscall(
obfClose.Num(),
uintptr(fd),
0,
0,
)
if errno != 0 {
return errno
}
return nil
}
//go:nosplit
func SysMprotect(addr uintptr, length int, prot int) error {
_, _, errno := syscall.Syscall(
obfMprotect.Num(),
addr,
uintptr(length),
uintptr(prot),
)
if errno != 0 {
return errno
}
return nil
}
+35
View File
@@ -0,0 +1,35 @@
package syscallobf
import "testing"
func TestEncodeDecodeTrap(t *testing.T) {
initDispatchKey()
tests := []uintptr{0, 1, 39, 62, 101, 0xDEAD, 0xFFFFFFFF}
for _, num := range tests {
encoded := EncodeTrap(num)
if encoded == num {
t.Errorf("EncodeTrap(%d) should not equal input", num)
}
decoded := DecodeTrap(encoded)
if decoded != num {
t.Errorf("DecodeTrap(EncodeTrap(%d)) = %d, want %d", num, decoded, num)
}
}
}
func TestEncodedSyscall(t *testing.T) {
initDispatchKey()
enc := NewEncodedSyscall(101)
if enc.Trap() != 101 {
t.Errorf("EncodedSyscall.Trap() = %d, want 101", enc.Trap())
}
}
func TestDispatchKeyNonZero(t *testing.T) {
initDispatchKey()
if dispatchKey == 0 {
t.Error("dispatchKey should not be 0")
}
}