gpt4 book ai didi

c - ptrace 更改系统调用编号 arm64

转载 作者:行者123 更新时间:2023-12-05 04:59:09 64 4
gpt4 key购买 nike

我正在尝试使用 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 = &regs;
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

最佳答案

在 arm64 上,出于兼容性原因,内核将要执行的系统调用存储在单独的变量 pt_regs.syscallno 中,而 ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov) 确实更改了寄存器(参见内核源代码中 struct pt_regs 的定义:commit:eec4df2/arch/arm64/include/asm/ptrace.h:178)。

当在 arm 或 arm64 上并且内核使用 CONFIG_COMPAT=yes 编译时,系统调用编号可以通过 ptrace(PTRACE_SET_SYSCALL, pid, NULL, syscallno) 更改。

对于没有 CONFIG_COMPAT=yes(更常见)的 arm64 内核,您将需要 ptrace(PTRACE_SETREGSET, pid, NT_ARM_SYSTEM_CALL, &iov)

例子:

int syscallno;
struct iovec iov = {
.iov_base = &syscallno,
.iov_len = sizeof (int),
};
ptrace(PTRACE_SETREGSET, traceePid, NT_ARM_SYSTEM_CALL, &iov);

NT_ARM_SYSTEM_CALL 的注册集在此处定义:commit:eec4df2/arch/arm64/kernel/ptrace.c:1173

SYS_writeSYS_chdir 等参数来阻止系统调用的另一种方法是将参数设置为无效地址,这样它将失败并返回 EINVAL:

struct user_regs_struct regs;
struct iovec iov = {
.iov_base = &regs,
.iov_len = sizeof (struct user_regs_struct),
};
ptrace(PTRACE_GETREGSET, traceePid, NT_PRSTATUS, &iov);
regs.regs[0] = 123;
regs.regs[1] = 456;
regs.regs[3] = 789;
ptrace(PTRACE_SETREGSET, traceePid, NT_PRSTATUS, &iov);

在系统调用中注册用法:Chromium OS Docs

另见:Gist: SBell6hf / A ptrace-based syscall jailer that runs on arm64, x86_64 and i386

关于c - ptrace 更改系统调用编号 arm64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63620203/

64 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com