Skip to content

Commit

Permalink
✨ add more syscalls and better signal handling
Browse files Browse the repository at this point in the history
  • Loading branch information
froz42 committed Oct 14, 2023
1 parent 5334fc7 commit 4f0091d
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 58 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ SRCS += syscall/syscall_get_description.c \
syscall/syscall_log.c \
syscall/syscall_log_param.c \
syscall/syscall_is_execve.c \
syscall/param_log/param_log_memseg.c \
syscall/param_log/log_memseg.c \
syscall/param_log/log_string.c \
syscall/param_log/log_open_flags.c \
syscall/param_log/log_open_mode.c \
syscall/syscall_handle.c

# registers srcs
Expand All @@ -56,7 +59,8 @@ SRCS += registers/registers_get_param.c \

# signals srcs

SRCS += signals/signals_block.c
SRCS += signals/signals_block.c \
signals/signals_handle.c

OBJS_MAIN_RELEASE := $(addprefix $(OBJSDIR_RELEASE)/,$(SRCS_MAIN:.c=.o))
OBJS_MAIN_DEBUG := $(addprefix $(OBJSDIR_DEBUG)/,$(SRCS_MAIN:.c=.o))
Expand Down
12 changes: 11 additions & 1 deletion includes/signals_strace.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <sys/types.h>
#include <syscall_strace.h>

/**
* @brief Block signals
*
Expand All @@ -10,4 +13,11 @@ void signals_block(void);
* @brief Unblock signals
*
*/
void signals_unblock(void);
void signals_unblock(void);

/**
* @brief Handle the signal raised by the tracee
*
* @param pid the pid of the tracee
*/
int signals_handle(pid_t pid, int *cont_signal, analysis_routine_data_t *data);
4 changes: 3 additions & 1 deletion includes/syscall_strace.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#define HEX 3
#define STRING 4
#define MEMSEG 5
#define OPEN_FLAGS 6
#define OPEN_MODE 7

/**
* @brief Negative if printed before the syscall, positive if printed after the
Expand Down Expand Up @@ -111,4 +113,4 @@ bool_t syscall_is_execve(uint64_t syscall_no, register_type_t type);
* @return int the status code of the tracee or NO_STATUS if no status code is
* available
*/
int syscall_handle(pid_t pid, analysis_routine_data_t *data, int cont_signal);
int syscall_handle(pid_t pid, analysis_routine_data_t *data, int *cont_signal);
49 changes: 9 additions & 40 deletions srcs/analysis/analysis_routine.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@

#include <analysis.h>
#include <errno.h>
#include <ft_printf.h>
#include <ft_strace_utils.h>
#include <ft_string.h>
#include <signal.h>
#include <signals_strace.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <syscall_strace.h>
#include <ft_string.h>

/**
* @brief Handle the status of the tracee
Expand All @@ -16,9 +18,8 @@
* @return int the status code of the tracee or NO_STATUS if no status code is
* available
*/
static int handle_status(int status, int *cont_signal)
static int handle_status(pid_t pid, int status, int *cont_signal, analysis_routine_data_t *data)
{
*cont_signal = 0;
if (status == NO_STATUS)
return NO_STATUS;
if (WIFEXITED(status))
Expand All @@ -32,38 +33,10 @@ static int handle_status(int status, int *cont_signal)
return status;
}
if (WIFSTOPPED(status))
{
int sig = WSTOPSIG(status);
if (sig == SIGTRAP || sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
return NO_STATUS;
*cont_signal = sig;
return SIG_RAISED;
}
return signals_handle(pid, cont_signal, data);
return NO_STATUS;
}

/**
* @brief Handle the signal raised by the tracee
*
* @param pid the pid of the tracee
*/
static void handle_signal(pid_t pid)
{
siginfo_t siginfo = {0};
if (ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo) < 0)
{
log_error("handle_signal", "ptrace(PTRACE_GETSIGINFO) failed", true);
return;
}
ft_printf("--- %s {si_signo=%s, si_code=%s, si_pid=%d, si_uid=%d} ---\n",
ft_signalname(siginfo.si_signo),
ft_signalname(siginfo.si_signo),
ft_sicodename(siginfo.si_signo, siginfo.si_code),
siginfo.si_pid,
siginfo.si_uid);

}

/**
* @brief Analysis routine of the tracer
*
Expand All @@ -84,26 +57,22 @@ int analysis_routine(pid_t pid)
log_error("analysis_routine", "ptrace failed", true);
return ROUTINE_ERROR;
}
cont_signal = 0;
int status;
if (waitpid(pid, &status, 0) < 0)
{
log_error("analysis_routine", "waitpid failed", true);
return ROUTINE_ERROR;
}
int status_code = handle_status(status, &cont_signal);
int status_code = handle_status(pid, status, &cont_signal, &data);
if (status_code == SIG_RAISED)
{
handle_signal(pid);
continue;
}
if (status_code != NO_STATUS)
return status_code;
status_code = handle_status(syscall_handle(pid, &data, cont_signal), &cont_signal);
status_code =
handle_status(pid, syscall_handle(pid, &data, &cont_signal), &cont_signal, &data);
if (status_code == SIG_RAISED)
{
handle_signal(pid);
continue;
}
if (status_code != NO_STATUS)
return status_code;
}
Expand Down
40 changes: 40 additions & 0 deletions srcs/signals/signals_handle.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#define _XOPEN_SOURCE
#define _XOPEN_SOURCE_EXTENDED 1

#include <analysis.h>
#include <ft_printf.h>
#include <ft_strace_utils.h>
#include <ft_string.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <syscall_strace.h>

/**
* @brief Handle the signal raised by the tracee
*
* @param pid the pid of the tracee
*/
int signals_handle(pid_t pid, int *cont_signal, analysis_routine_data_t *data)
{
siginfo_t siginfo = {0};
if (ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo) < 0)
{
log_error("handle_signal", "ptrace(PTRACE_GETSIGINFO) failed", true);
return SIG_RAISED;
}
if (siginfo.si_signo == SIGTRAP && siginfo.si_code == TRAP_UNK)
{
return NO_STATUS;
}
if (siginfo.si_signo == SIGSTOP && siginfo.si_code != SI_TKILL)
{
*cont_signal = SIGSTOP;
return SIG_RAISED;
}
if (data->status == ENCOUNTERED)
ft_printf("--- %s {si_signo=%s, si_code=%s, si_pid=%d, si_uid=%d} ---\n",
ft_signalname(siginfo.si_signo), ft_signalname(siginfo.si_signo),
ft_sicodename(siginfo.si_signo, siginfo.si_code), siginfo.si_pid, siginfo.si_uid);
*cont_signal = siginfo.si_signo;
return SIG_RAISED;
}
Empty file removed srcs/signals/signals_raise.c
Empty file.
File renamed without changes.
58 changes: 58 additions & 0 deletions srcs/syscall/param_log/log_open_flags.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#define _GNU_SOURCE

#include "param_log.h"
#include <ft_printf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <macros.h>

typedef struct {
uint64_t flag;
const char *str;
} flag_str_t;

#define FLAG_STR(flag) {flag, #flag}

static const flag_str_t flags[] = {
FLAG_STR(O_RDONLY),
FLAG_STR(O_WRONLY),
FLAG_STR(O_RDWR),
FLAG_STR(O_CREAT),
FLAG_STR(O_EXCL),
FLAG_STR(O_NOCTTY),
FLAG_STR(O_TRUNC),
FLAG_STR(O_APPEND),
FLAG_STR(O_NONBLOCK),
FLAG_STR(O_DSYNC),
FLAG_STR(O_ASYNC),
FLAG_STR(O_DIRECT),
FLAG_STR(O_LARGEFILE),
FLAG_STR(O_DIRECTORY),
FLAG_STR(O_NOFOLLOW),
FLAG_STR(O_NOATIME),
FLAG_STR(O_CLOEXEC),
FLAG_STR(O_PATH),
FLAG_STR(O_TMPFILE),
};

/**
* @brief Log open flags
*
* @param value the value to log
*/
void log_OPEN_FLAGS(uint64_t value)
{
bool_t first = true;
for (size_t i = 0; i < ELEM_COUNT(flags); i++)
{
if (value & flags[i].flag)
{
if (!first)
ft_dprintf(STDERR_FILENO, "|");
ft_dprintf(STDERR_FILENO, "%s", flags[i].str);
first = false;
value &= ~flags[i].flag;
}
}
}
12 changes: 12 additions & 0 deletions srcs/syscall/param_log/log_open_mode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "param_log.h"
#include <ft_printf.h>

/**
* @brief Log open mode
*
* @param value the value to log
*/
void log_OPEN_MODE(uint64_t value)
{
ft_dprintf(STDERR_FILENO, "%#o", value);
}
65 changes: 65 additions & 0 deletions srcs/syscall/param_log/log_string.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#define _GNU_SOURCE

#include "param_log.h"
#include <ft_printf.h>
#include <ft_strace_utils.h>
#include <ft_string.h>
#include <registers.h>
#include <sys/uio.h>

#define DEFAULT_BUFFER_SIZE 32

typedef struct
{
char *buffer;
size_t size_buffer;
size_t index;
} buffer_t;

static void buffer_add_char(buffer_t *buffer, char c)
{
if (buffer->index >= buffer->size_buffer)
{
buffer->size_buffer *= 2;
buffer->buffer = realloc(buffer->buffer, buffer->size_buffer);
}
buffer->buffer[buffer->index++] = c;
}

/**
* @brief log memory segment
*
* @param value the value
* @param context the context
*/
void log_STRING(uint64_t value, syscall_log_param_t *context)
{
buffer_t buffer = {
.buffer = malloc(DEFAULT_BUFFER_SIZE),
.size_buffer = DEFAULT_BUFFER_SIZE,
.index = 0,
};
char c = 1; // dummy value that will be overwritten by the first read
while (c != '\0')
{
struct iovec local = {
.iov_base = &c,
.iov_len = 1,
};
struct iovec remote = {
.iov_base = (void *)value + buffer.index,
.iov_len = 1,
};
if (process_vm_readv(context->pid, &local, 1, &remote, 1, 0) < 0)
{
log_error("log_STRING", "process_vm_readv failed", true);
free(buffer.buffer);
return;
}
buffer_add_char(&buffer, c);
}
char *escaped_buffer = ft_escape(buffer.buffer, buffer.index - 1);
ft_dprintf(STDERR_FILENO, "\"%s\"", escaped_buffer);
free(escaped_buffer);
free(buffer.buffer);
}
26 changes: 24 additions & 2 deletions srcs/syscall/param_log/param_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ typedef void (*log_function_t)();
* @brief log memory segment
*
* @param value the value
* @param context the context
* @param context the context of the syscall
*/
void log_MEMSEG(uint64_t value, syscall_log_param_t *context);
void log_MEMSEG(uint64_t value, syscall_log_param_t *context);

/**
* @brief Log a string
*
* @param value the value
* @param context the context of the syscall
*/
void log_STRING(uint64_t value, syscall_log_param_t *context);

/**
* @brief Log open flags
*
* @param value the value to log
*/
void log_OPEN_FLAGS(uint64_t value);

/**
* @brief Log open mode
*
* @param value the value to log
*/
void log_OPEN_MODE(uint64_t value);
4 changes: 3 additions & 1 deletion srcs/syscall/syscall_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
* ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6 } } */
static const syscall_description_t x86_64_syscalls[] = {
[0] = {"read", SIGNED_INT, {-SIGNED_INT, MEMSEG, INT, NONE}},
[1] = {"write", SIGNED_INT, {-SIGNED_INT, -MEMSEG, -INT, NONE}}};
[1] = {"write", SIGNED_INT, {-SIGNED_INT, -MEMSEG, -INT, NONE}},
[2] = {"open", SIGNED_INT, {-STRING, -OPEN_FLAGS, -OPEN_MODE, NONE}},
[3] = {"close", SIGNED_INT, {-INT, NONE}}};
Loading

0 comments on commit 4f0091d

Please sign in to comment.