Ich versuche, syscalls für eine Binärdatei mit ptrace zu überwachen. Das binary schläft in pselect() und ohne ptrace bewirkt ein SIGQUIT, dass es von pselect zurückgegeben wird. Die Maske der blockierten Signale, die an pselect übergeben werden, enthält SIGQUIT.Ptrace verhindert, dass Signal pselect() im verfolgten Prozess unterbricht
Wenn es mit ptrace ausgeführt wird, wird es von sys_pselect6, aber nicht vollständig aus glibcs pselect beendet. Was mache ich, die verhindert, dass sys_pselect6 zu Benutzercode austritt?
Tracer:
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <err.h>
#include <wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int pid = fork(), sys_in = 1, status;
if (pid == 0) {
if (ptrace(PTRACE_TRACEME, getppid(), NULL, NULL) < 0)
err(1, "TRACEME()");
execl("./child", "./child", NULL);
err(1, "execl()");
}
if (waitpid(pid, &status, 0) != pid) err(1, "wait()");
for (;; sys_in ^= 1) {
if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0) err(1, "SYSCALL");
if (waitpid(pid, &status, 0) != pid) err(1, "wait()");
if (sys_in) {
long long sys_no = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, NULL);
printf("syscall entry %lld\n", sys_no);
}
else printf("syscall exit\n");
}
return 0;
}
Kind:
#include <stdio.h>
#include <sys/select.h>
#include <signal.h>
#include <err.h>
void handle_sigquit(int sig, siginfo_t* info, void *ctx)
{
}
int main()
{
sigset_t mask;
sigset_t orig_mask;
struct sigaction sa = {};
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handle_sigquit;
sigaction(SIGQUIT, &sa, NULL);
sigemptyset(&mask);
sigaddset(&mask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) err(1, "sigprocmask()");
pselect(0, NULL, NULL, NULL, NULL, &orig_mask);
warn("pselect()");
return 0;
}