You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下Golang基于C实现函数Hook失败:ptrace权限问题

针对ptrace附加失败的解决方案

1. 关闭Go的Seccomp过滤

Go运行时默认启用Seccomp安全机制,可能阻断ptrace系统调用。可以通过两种方式关闭:

  • 运行程序时添加环境变量:GODEBUG=seccomp=0 ./your_go_binary
  • 编译时禁用Seccomp:go build -tags=seccomp_off -o your_go_binary your_code.go

2. 排查系统安全模块限制

  • Yama配置确认:确保ptrace_scope确实设置为0,执行:
    echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
    
  • SELinux(RHEL8):执行sestatus查看状态,若为Enforcing模式,临时关闭测试:sudo setenforce 0,问题解决后可考虑添加自定义SELinux规则放行ptrace。
  • AppArmor(WSL/Ubuntu):执行sudo aa-status检查状态,临时禁用:sudo systemctl stop apparmor,验证是否解决问题。

3. 调整ptrace调用逻辑

内核可能限制进程ptrace自身,可改为fork子进程来附加父进程:

package main

import (
    "os"
    "syscall"
    "time"
)

func main() {
    pid := os.Getpid()
    child, err := syscall.Fork()
    if err != nil {
        panic(err)
    }
    if child == 0 {
        // 子进程附加父进程
        err := syscall.PtraceAttach(pid)
        if err != nil {
            panic(err)
        }
        syscall.Wait4(pid, nil, 0, nil)
        os.Exit(0)
    }
    // 父进程等待子进程完成附加
    time.Sleep(100 * time.Millisecond)
    // 后续执行Hook逻辑
}

4. 替代方案:直接修改内存权限跳转

放弃ptrace,直接修改Go函数内存页权限并写入跳转指令:

  • 使用syscall.Mprotect将函数所在内存页设置为可读可写可执行
  • 通过指针直接修改内存中的指令,跳转到C函数的地址(需要先通过dlopen和dlsym获取C函数地址)

5. 确认动态库加载权限

确保编译的.so文件有可执行权限,且程序能找到:

chmod +x libyourlib.so
LD_LIBRARY_PATH=. ./your_go_binary

内容的提问来源于stack exchange,提问作者Shaked Shitrit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:35:09