Вы можете запустить скомпилированную программу, разветвив ее из оболочки и используя средство Linux ptrace (2) для перехвата и проверки всех системных вызовов, вызванных программой.
В следующем примере кода показана оболочка, которая выполняет команду / usr / bin / w, печатает каждый системный вызов, вызванный командой, и завершает команду, если она пытается вызвать системный вызов write (2).
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/reg.h>
#define BAD_SYSCALL __NR_write
int main(int argc, char *argv)
{
pid_t child;
int status, syscall_nr;
child = fork();
if (child == 0) {
/* In child. */
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/usr/bin/w", NULL, NULL);
// not reached
}
/* In parent. */
while (1) {
wait(&status);
/* Abort loop if child has exited. */
if (WIFEXITED(status) || WIFSIGNALED(status))
break;
/* Obtain syscall number from the child's process context. */
syscall_nr = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
printf("Child wants to execute system call %d: ", syscall_nr);
if (syscall_nr != BAD_SYSCALL) {
/* Allow system call. */
printf("allowed.\n");
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
} else {
/* Terminate child. */
printf("not allowed. Terminating child.\n");
ptrace(PTRACE_KILL, child, NULL, NULL);
}
}
exit(EXIT_SUCCESS);
}
С помощью ptrace вы можете делать гораздо более мощные вещи, такие как проверка и изменение адресного пространства процесса (например, для получения и изменения параметров, передаваемых системному вызову).
Хорошее введение можно найти в этой статье журнала Linux и ее последующих действиях .