Skip to content

Commit

Permalink
✨ allow logs before and after syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
froz42 committed Oct 9, 2023
1 parent 3d097e6 commit 67e44e2
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 41 deletions.
35 changes: 21 additions & 14 deletions includes/syscall_strace.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
#define X_86_64_EXECVE_SYSCALL 59
#define X_86_32_EXECVE_SYSCALL 11

typedef enum {
INT,
SIGNED_INT,
HEX,
STRING,
NONE
} arg_type_t;
#define NONE 0
#define INT 1
#define SIGNED_INT 2
#define HEX 3
#define STRING 4

/**
* @brief Negative if printed before the syscall, positive if printed after the syscall
*
*/
typedef int64_t arg_type_t;

typedef struct {
const char *name;
Expand Down Expand Up @@ -50,15 +54,18 @@ void syscall_log_name_params(pid_t pid, user_regs_t *regs_before, register_type_
void syscall_log_param(pid_t pid, arg_type_t arg_type, uint64_t arg);

/**
* @brief Log the return value of the syscall
* @brief Log remaining parameters of the syscall and return value
*
* @param pid the pid of the process
* @param syscall_no the syscall number
* @param regs_after the registers after the syscall
* @param type the registers type
* @param pid The pid of the process
* @param syscall_no The syscall number
* @param regs_after The registers after the syscall
* @param regs_after_type The registers type after the syscall
*/
void syscall_log_return(pid_t pid, int syscall_no, user_regs_t *regs_after, register_type_t type);

void syscall_log_params_return(
pid_t pid,
int syscall_no,
user_regs_t *regs_after,
register_type_t regs_after_type);
/**
* @brief Check if syscall is execve depending on the syscall number and the registers type
*
Expand Down
17 changes: 9 additions & 8 deletions srcs/analysis/analysis_routine.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ int handle_syscall(pid_t pid, analysis_routine_data_t *data)
log_error("handle_syscall", "ptrace(PTRACE_GETREGS)(1) failed", true);
return NO_STATUS;
}
register_type_t register_type = registers_get_type(regs_before_iov.iov_len);
if (data->register_type != register_type)
register_type_t register_type_before = registers_get_type(regs_before_iov.iov_len);
if (data->register_type != register_type_before)
{
data->register_type = register_type;
data->register_type = register_type_before;
ft_dprintf(STDERR_FILENO, "[ Process PID=%d runs in 32 bit mode. ]\n", pid);
}
uint64_t syscall_no = registers_get_syscall(&regs_before, register_type);
uint64_t syscall_no = registers_get_syscall(&regs_before, register_type_before);
if (syscall_no > MAX_SYSCALL_NO)
return NO_STATUS;

Expand All @@ -61,14 +61,14 @@ int handle_syscall(pid_t pid, analysis_routine_data_t *data)
log_error("handle_syscall", "ptrace failed", true);
return NO_STATUS;
}
bool_t is_execve = syscall_is_execve(syscall_no, register_type);
bool_t is_execve = syscall_is_execve(syscall_no, register_type_before);
if (data->status == ERROR && !is_execve)
return NO_STATUS;
if (data->status == NOT_ENCOUNTERED && !is_execve)
return NO_STATUS;
bool_t should_log = data->status == ENCOUNTERED || (data->status != ERROR && is_execve);
if (should_log)
syscall_log_name_params(pid, &regs_before, register_type);
syscall_log_name_params(pid, &regs_before, register_type_before);
int status;
if (waitpid(pid, &status, 0) < 0)
{
Expand All @@ -90,10 +90,11 @@ int handle_syscall(pid_t pid, analysis_routine_data_t *data)
log_error("handle_syscall", "ptrace(PTRACE_GETREGS)(2) failed", true);
return NO_STATUS;
}
register_type_t register_type_after = registers_get_type(regs_after_iov.iov_len);
if (data->status == NOT_ENCOUNTERED && syscall_no == SYS_EXECVE)
data->status = (int64_t)registers_get_return(&regs_after, register_type) < 0 ? ERROR : ENCOUNTERED;
data->status = (int64_t)registers_get_return(&regs_after, register_type_after) < 0 ? ERROR : ENCOUNTERED;
if (should_log)
syscall_log_return(pid, syscall_no, &regs_after, register_type);
syscall_log_params_return(pid, syscall_no, &regs_after, register_type_after);
return NO_STATUS;
}

Expand Down
2 changes: 1 addition & 1 deletion srcs/syscall/syscall_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

/* [SYSCALL_NO] = { "SYSCALL_NAME", RETURN_TYPE, { ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6 } } */
static const syscall_description_t x86_64_syscalls[] = {
[0] = {"read", SIGNED_INT, {SIGNED_INT, STRING, INT, NONE}}
[0] = {"read", SIGNED_INT, {-SIGNED_INT, STRING, INT, NONE}}
};
52 changes: 36 additions & 16 deletions srcs/syscall/syscall_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,69 @@
#include <assert.h>
#include <ft_string.h>

#define ERROR_RANGE_START 0
#define ERROR_RANGE_END 4095

/**
* @brief Log the name of the syscall and its parameters
*
* @param pid The pid of the process
* @param regs_before The registers before the syscall
* @param type the registers type
*/
void syscall_log_name_params(pid_t pid, user_regs_t *regs_before, register_type_t type)
void syscall_log_name_params(pid_t pid, user_regs_t *regs_before, register_type_t register_type)
{
uint64_t syscall_no = registers_get_syscall(regs_before, type);
const syscall_description_t *syscall_desc = syscall_get_description(syscall_no, type);
uint64_t syscall_no = registers_get_syscall(regs_before, register_type);
const syscall_description_t *syscall_desc = syscall_get_description(syscall_no, register_type);
ft_dprintf(STDERR_FILENO, "%s(", syscall_desc->name);
const size_t param_count = ELEM_COUNT(syscall_desc->arg_types);
for (uint8_t i = 0; i < param_count; i++)
{
if (syscall_desc->arg_types[i] == NONE)
if (syscall_desc->arg_types[i] == NONE || syscall_desc->arg_types[i] > 0)
break;
uint64_t arg = registers_get_param(regs_before, type, i);
syscall_log_param(pid, syscall_desc->arg_types[i], arg);
int64_t positive_arg_type = -syscall_desc->arg_types[i];
uint64_t arg = registers_get_param(regs_before, register_type, i);
syscall_log_param(pid, positive_arg_type, arg);
if (!(i == param_count - 1 || syscall_desc->arg_types[i + 1] == NONE))
ft_dprintf(STDERR_FILENO, ", ");
}
}

/**
* @brief Log the return value of the syscall
* @brief Log remaining parameters of the syscall and return value
*
* @param pid the pid of the process
* @param syscall_no the syscall number
* @param regs_after the registers after the syscall
* @param type the registers type
* @param pid The pid of the process
* @param syscall_no The syscall number
* @param regs_after The registers after the syscall
* @param regs_after_type The registers type after the syscall
*/
void syscall_log_return(pid_t pid, int syscall_no, user_regs_t *regs_after, register_type_t type)
void syscall_log_params_return(
pid_t pid,
int syscall_no,
user_regs_t *regs_after,
register_type_t regs_after_type)
{
const syscall_description_t *syscall_desc = syscall_get_description(syscall_no, type);
ft_dprintf(STDERR_FILENO, ") = ");
int64_t return_value = (int64_t)registers_get_return(regs_after, type);
const syscall_description_t *syscall_desc = syscall_get_description(syscall_no, regs_after_type);
int64_t return_value = (int64_t)registers_get_return(regs_after, regs_after_type);
int errno = 0;
if (return_value < 0)
if (return_value < 0 && return_value >= -4096)
{
errno = -return_value;
return_value = -1;
}
const size_t param_count = ELEM_COUNT(syscall_desc->arg_types);
for (uint8_t i = 0; i < param_count; i++)
{
if (syscall_desc->arg_types[i] == NONE)
break;
if (syscall_desc->arg_types[i] < 0)
continue;
uint64_t arg = registers_get_param(regs_after, regs_after_type, i);
syscall_log_param(pid, syscall_desc->arg_types[i], arg);
if (!(i == param_count - 1 || syscall_desc->arg_types[i + 1] == NONE))
ft_dprintf(STDERR_FILENO, ", ");
}
ft_dprintf(STDERR_FILENO, ") = ");
syscall_log_param(pid, syscall_desc->return_type, return_value);
if (errno)
ft_dprintf(STDERR_FILENO, " %s (%s)", ft_strerror(errno), "Not implemented");
Expand Down
2 changes: 1 addition & 1 deletion srcs/syscall/syscall_log_param.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ void syscall_log_param(pid_t pid, arg_type_t arg_type, uint64_t arg)
{
(void)pid;
static const log_function_t log_functions[] = {
[NONE] = log_NONE,
[INT] = log_INT,
[SIGNED_INT] = log_UNSIGNED_INT,
[HEX] = log_HEX,
[STRING] = log_STRING,
[NONE] = log_NONE
};
log_functions[arg_type](arg);
}
2 changes: 1 addition & 1 deletion tests/syscall/syscall_get_description.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ START_TEST(test_read_description, "Test that the description is right for read")
const syscall_description_t *description = syscall_get_description(0, X86_64);
assert_string_equal(description->name, "read");
assert_equal(description->return_type, SIGNED_INT);
assert_equal(description->arg_types[0], SIGNED_INT);
assert_equal(description->arg_types[0], -SIGNED_INT);
assert_equal(description->arg_types[1], STRING);
assert_equal(description->arg_types[2], INT);
assert_equal(description->arg_types[3], NONE);
Expand Down

0 comments on commit 67e44e2

Please sign in to comment.