基本上,标题,我不能让它工作,我也找不到任何理由,它不应该工作。
ptrace(2)的手册规定,Linux 5.3+是必需的,我正在运行Linux5.17.4,下面的简化代码编译时没有任何警告,在检测每个系统调用时运行时没有任何错误,但是syscall_info.op总是有值PTRACE_SYSCALL_INFO_NONE。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <sys/user.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <linux/ptrace.h>
#include <sys/errno.h>
int main(int argc, char **argv) {
pid_t pid = fork();
switch(pid) {
case -1:
//error...
case 0:
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execvp(argv[1], argv + 1);
//error...
}
waitpid(pid, NULL, 0);
ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_EXITKILL);
struct ptrace_syscall_info syscall_info;
size_t size = sizeof(syscall_info);
while(1) {
if(ptrace(PTRACE_SYSCALL, pid, NULL, NULL) == -1) {
//error...
}
if(waitpid(pid, NULL, 0) == -1) {
//error...
}
// syscall entry
if(ptrace(PTRACE_GET_SYSCALL_INFO, pid, (void *)size, &syscall_info) == -1) {
//error...
}
/* syscall_info.op is always PTRACE_SYSCALL_INFO_NONE
instead of PTRACE_SYSCALL_INFO_ENTRY */
if(ptrace(PTRACE_SYSCALL, pid, NULL, NULL) == -1) {
//error...
}
if(waitpid(pid, NULL, 0) == -1) {
//error...
}
// syscall exit
if(ptrace(PTRACE_GET_SYSCALL_INFO, pid, (void *)size, &syscall_info) == -1) {
if(errno == ESRCH) {
exit(syscall_info.exit.rval);
}
//error...
}
/* Same here, should be PTRACE_SYSCALL_INFO_EXIT but still
is PTRACE_SYSCALL_INFO_NONE */
}
}在过去的3天里,我一直在谷歌上搜索,我找不到多少东西来验证我是否正确地使用了它,也没有找到任何解释为什么不应该这样做的帖子。我甚至研究了strace的源代码,看看它们是如何做到的,而我所能找到的只有几个宏,它们一开始是否支持PTRACE_GET_SYSCALL_INFO,但不知道这些测试是什么。如果除了内核版本之外,PTRACE_GET_SYSCALL_INFO还有特定的标准,为什么没有在手册中列出呢?
发布于 2022-05-28 05:01:13
经过一番研究,看来您必须启用PTRACE_O_TRACESYSGOOD选项PTRACE_SETOPTIONS,才能从PTRACE_GET_SYSCALL_INFO获得完整的信息。
这一要求似乎没有文档化。目前还不清楚它是有意的还是内核错误的。
https://stackoverflow.com/questions/72410182
复制相似问题