Files
go-obfuscation/pkg/antidebug/antidebug_hwbp_linux.go
T
2026-05-31 19:48:56 +01:00

66 lines
1.7 KiB
Go

package antidebug
import (
"syscall"
"unsafe"
)
const (
offsetofDR0 = 6 * 8 // offsetof(struct user, u_debugreg[0])
offsetofDR7 = 13 * 8 // offsetof(struct user, u_debugreg[7])
)
func checkHardwareBreakpoints() bool {
pid, _, _ := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
if pid == 0 {
// Child: attach to parent, read debug registers, report via exit code
syscall.RawSyscall(syscall.SYS_PTRACE, uintptr(syscall.PTRACE_ATTACH), uintptr(syscall.Getppid()), 0)
var status syscall.WaitStatus
syscall.RawSyscall(syscall.SYS_WAIT4, uintptr(syscall.Getppid()), uintptr(unsafe.Pointer(&status)), 0, 0)
detected := false
for i := 0; i < 4; i++ {
drVal, _, _ := syscall.RawSyscall6(
syscall.SYS_PTRACE,
uintptr(syscall.PTRACE_PEEKUSER),
uintptr(syscall.Getppid()),
uintptr(offsetofDR0+i*8),
0, 0, 0,
)
if drVal != 0 {
detected = true
break
}
}
if !detected {
dr7, _, _ := syscall.RawSyscall6(
syscall.SYS_PTRACE,
uintptr(syscall.PTRACE_PEEKUSER),
uintptr(syscall.Getppid()),
uintptr(offsetofDR7),
0, 0, 0,
)
// Bits 0,2,4,6 enable DR0-DR3; bits 1,3,5,7 are condition bits
// If any enable bit is set, a hardware breakpoint is active
if dr7&0x55 != 0 {
detected = true
}
}
syscall.RawSyscall(syscall.SYS_PTRACE, uintptr(syscall.PTRACE_DETACH), uintptr(syscall.Getppid()), 0)
exitCode := 0
if detected {
exitCode = 1
}
syscall.RawSyscall(syscall.SYS_EXIT, uintptr(exitCode), 0, 0)
}
// Parent: wait for child result
var status syscall.WaitStatus
syscall.RawSyscall(syscall.SYS_WAIT4, pid, uintptr(unsafe.Pointer(&status)), 0, 0)
return status.ExitStatus() == 1
}