【发布时间】:2018-04-10 21:54:17
【问题描述】:
我正在使用 ptrace 来拦截系统调用。除了我拦截了 16 个对 execve 的调用(8 个用于系统前调用,8 个用于系统调用后)之外,一切似乎都运行良好。
我见过没有它的工作示例,但我正在尝试使用标志 PTRACE_O_TRACESYSGOOD。
其他answers to ptrace problems 表示我应该只看到一个前/后+一个信号,但他们没有使用PTRACE_O_TRACESYSGOOD。
我的输出如下:
Intercepted rt_sigprocmask[14]
Syscall returned with value 0
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value -2
Intercepted execve[59]
Syscall returned with value 0
Tracer: Received signal: 5
Intercepted brk[12]
...
输出的其余部分与strace 的输出相匹配。
每个“拦截”和“返回的系统调用”对应一个 waitid() 调用。重现此的极简示例代码:
#include <sys/types.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/vfs.h>
#include <sys/ptrace.h>
#include <sys/reg.h> /* For constants ORIG_EAX, etc */
#include <string.h>
#include <sys/wait.h>
#include <sys/syscall.h> /* For SYS_write, etc */
#include <unistd.h>
#include <stdio.h>
int main(){
pid_t pid = fork();
// Child.
if(pid == 0){
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
// Wait for parent to be ready.
raise(SIGSTOP);
execlp("pwd", "pwd", NULL);
return 0;
}
// Tracer.
else{
struct user_regs_struct regs;
bool isPre = true;
int status;
// Wait for child to stop itself.
waitpid(pid, &status, 0);
ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACESYSGOOD);
while(true){
ptrace(PTRACE_SYSCALL, pid, 0, 0);
pid = waitpid(pid, &status, 0);
// Check if tracee has exited.
if (WIFEXITED(status)){
return 0;
}
// This is a stop caused by a system call exit-pre/exit-post.
if(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP |0x80) ){
ptrace(PTRACE_GETREGS, pid, NULL, ®s);
if(isPre){
printf("Intercepted syscall: %llu\n", regs.orig_rax);
isPre = ! isPre;
}else{
printf("Done with system call!\n");
isPre = ! isPre;
}
}else{
printf("Tracer: Received signal: %d\n", WSTOPSIG(status));
}
}
}
return 0;
}
我担心我误解了execve 或PTRACE_O_TRACESYSGOOD。
我在内核版本为 4.10.0-37-generic 的 Lubuntu 16.04 上运行它。
编辑:修复了系统调用的返回值。
【问题讨论】:
标签: c system-calls ptrace