【发布时间】:2020-08-27 16:18:21
【问题描述】:
我正在尝试使用 ptrace 在 linux arm64 上将调用从一个系统调用更改为另一个系统调用。
据我了解,系统调用号在 x8 中,读取系统调用的寄存器可以确认这一点。即时更改此号码并调用 SETREGSET 并调用旧系统调用而不是新系统调用。当我检查从系统调用返回的寄存器时,x8 设置为我给他的系统调用。
为同一个系统调用更改其他参数是可行的。
我看到一些使用 PTRACE_SET_SYSCALL 的地方,但我找不到很多关于它的信息,我尝试使用它,但它似乎在这个拱门中不受支持,它没有定义并且写入数字反而因为不存在而失败。
我做错了什么?为什么它不起作用?
这是代码,为了简单起见,我删除了打印和验证,对于这个例子,我只是试图停止写入系统调用:
ptrace(PTRACE_ATTACH, pid, NULL, NULL);
int status;
waitpid(pid, &status, 0);
while (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) == 0)
{
waitpid(pid, &status, 0);
struct user_pt_regs regs;
struct iovec io;
io.iov_base = ®s;
io.iov_len = sizeof(regs);
ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &io);
// reg[7] is 0 before syscall and 1 after
if (regs.regs[7] == 0)
{
// Change write syscall
if (regs.regs[8] == 64)
{
// Change the syscall to getpid (doesn't matter)
regs.regs[8] = 172;
ptrace(PTRACE_SETREGSET, pid, (void*)NT_PRSTATUS, &io);
}
}
}
至于tracee,一个简单的hello world with write with sleep;
char buf[] = "hello world\n";
while(1)
{
write(1, buf, sizeof(buf));
sleep(5);
}
虽然程序运行没有错误并打印正确的寄存器,但系统调用并没有改变,它继续打印 hello world
【问题讨论】: