我正在尝试使用ptrace在linux arm64上将一个系统调用的调用更改为另一个调用。
据我所知,系统调用号码在x8中,读取系统调用的寄存器可以确认这一点。我更改了这个数字并调用SETREGSET, 旧的系统调用被调用而不是新的。在系统调用返回时检查寄存器,x8被设置为我所提供的系统调用,就像应该做的那样。
更改相同系统调用的其他参数是有效的。
我看到一些地方使用PTRACE_SET_SYSCALL,但我找不到太多相关信息,我尝试使用它,但似乎这个组合体系结构不支持它,它未定义,在写入数字失败因为不存在。
我做错了什么?为什么它不起作用?
这里是代码,我为简单起见删除了打印和验证,对于这个例子,我只是尝试停止write系统调用:
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);
}
}
}
对于被追踪的对象,一个简单的hello world程序,带有写和休眠操作;
char buf[] = "hello world\n";
while(1)
{
write(1, buf, sizeof(buf));
sleep(5);
}
尽管程序没有错误并且打印了正确的寄存器,但系统调用没有改变并且它仍然打印“hello world”。