commit: b1ab1aca67934866324807306176375f4e08b06c
parent 76b8c037209b30660ccb2cc4f7de533de648ab5c
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 27 Nov 2024 09:29:38 +0100
Use a simple DSL to generate syscall case-handles
Means a slightly bigger binary but likely could be optimised later
into something like a table describing each syscall.
Diffstat:
5 files changed, 113 insertions(+), 184 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -5,3 +5,5 @@
/strsyscall.c
/strsyscall.h
/tmp_strsyscall.h
+/syscalls_cases.h
+/print_syscall.o
diff --git a/Makefile b/Makefile
@@ -1,8 +1,13 @@
# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+ministrace@hacktivis.me>
# SPDX-License-Identifier: MPL-2.0
-ministrace: ministrace.c strsyscall.c print_syscall.c
- ${CC} -std=c99 ${CFLAGS} -o ministrace ministrace.c strsyscall.c print_syscall.c ${LDFLAGS} ${LDSTATIC}
+ministrace: ministrace.c strsyscall.c print_syscall.o
+ ${CC} -std=c99 ${CFLAGS} -o ministrace ministrace.c strsyscall.c print_syscall.o ${LDFLAGS} ${LDSTATIC}
+
+print_syscall.o: print_syscall.c syscalls_cases.h
+
+syscalls_cases.h: syscalls.txt syscalls.sh
+ ./syscalls.sh
tmp_strsyscall.h:
${CC} -undef -E -P -fdirectives-only -o tmp_strsyscall.h - <<<'#include <sys/syscall.h>'
@@ -12,7 +17,7 @@ strsyscall.c: strsyscall.sh tmp_strsyscall.h
.PHONY: clean
clean:
- rm ministrace tmp_strsyscall.h strsyscall.c
+ rm -f ministrace tmp_strsyscall.h strsyscall.c print_syscall.o
.PHONY: format
format:
diff --git a/print_syscall.c b/print_syscall.c
@@ -52,189 +52,9 @@ read_str(intptr_t addr, size_t len)
void
print_syscall(__u64 nr, __u64 args[6])
{
- // * Non-exhaustive
- // * Doesn't handles special cases like structures or arrays
-
- // Ordered by number-of-arguments/complexity
switch(nr)
{
- // int, path, buf, size
- case SYS_readlinkat:
- fprintf(stderr,
- "%s(" Pri_i ", " Pri_str ", " Pri_x ", %zd)",
- str_syscalls[nr],
- (int64_t)args[0],
- read_str(args[1], PATH_MAX),
- (int64_t)args[2],
- (size_t)args[3]);
- return;
- // int, path, oct, oct
- case SYS_openat:
- case SYS_faccessat:
- fprintf(stderr,
- "%s(" Pri_i ", " Pri_str ", " Pri_o ", " Pri_o ")",
- str_syscalls[nr],
- (int64_t)args[0],
- read_str(args[1], PATH_MAX),
- (int64_t)args[2],
- (int64_t)args[3]);
- return;
- // path, hex, hex
- case SYS_execve:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_x ", " Pri_x ")",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (uint64_t)args[1],
- (uint64_t)args[2]);
- return;
- // int, buf, size
- case SYS_write:
- case SYS_read:
- // Need handling of non-printable characters to print buf
- fprintf(stderr,
- "%s(" Pri_i ", " Pri_x ", %zd)",
- str_syscalls[nr],
- (int64_t)args[0],
- (int64_t)args[1],
- (size_t)args[2]);
- return;
- // int, path, path
- case SYS_linkat:
- case SYS_symlinkat:
- fprintf(stderr,
- "%s(" Pri_i ", " Pri_str ", " Pri_str ")",
- str_syscalls[nr],
- (int64_t)args[0],
- read_str(args[1], PATH_MAX),
- read_str(args[2], PATH_MAX));
- return;
- // path, buf, size
- case SYS_readlink:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_x ", %zd)",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (int64_t)args[1],
- (size_t)args[2]);
- return;
- // path, oct, oct
- case SYS_open:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_o ", " Pri_o ")",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (int64_t)args[1],
- (int64_t)args[2]);
- return;
- // path, int, int
- case SYS_chown:
- case SYS_lchown:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_i ", " Pri_o ")",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (int64_t)args[1],
- (int64_t)args[2]);
- return;
- // path, path
- case SYS_link:
- case SYS_symlink:
- case SYS_rename:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_str ")",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- read_str(args[1], PATH_MAX));
- return;
- // path, off_t
- case SYS_truncate:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_u ")",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (off_t)args[1]);
- return;
- // path, size
- case SYS_getcwd:
- fprintf(stderr,
- "%s(" Pri_str ", %zd)",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (size_t)args[1]);
- return;
- // path, oct
- case SYS_access:
- case SYS_stat:
- case SYS_lstat:
- case SYS_mkdir:
- case SYS_creat:
- case SYS_chmod:
- fprintf(stderr,
- "%s(" Pri_str ", " Pri_o ")",
- str_syscalls[nr],
- read_str(args[0], PATH_MAX),
- (int64_t)args[1]);
- return;
- // int, path
- case SYS_unlinkat:
- fprintf(stderr,
- "%s(" Pri_i ", " Pri_str ")",
- str_syscalls[nr],
- (int64_t)args[0],
- read_str(args[1], PATH_MAX));
- return;
- // int, off_t
- case SYS_ftruncate:
- fprintf(stderr, "%s(" Pri_i ", " Pri_u ")", str_syscalls[nr], (int64_t)args[0], (off_t)args[1]);
- return;
- // int, oct
- case SYS_fchmod:
- fprintf(
- stderr, "%s(" Pri_i ", " Pri_o ")", str_syscalls[nr], (int64_t)args[0], (int64_t)args[1]);
- return;
- // int, int
- case SYS_kill:
- case SYS_dup2:
- fprintf(
- stderr, "%s(" Pri_i ", " Pri_i ")", str_syscalls[nr], (int64_t)args[0], (int64_t)args[1]);
- return;
- // path
- case SYS_unlink:
- case SYS_rmdir:
- case SYS_chdir:
- fprintf(stderr, "%s(" Pri_str ")", str_syscalls[nr], read_str(args[0], PATH_MAX));
- return;
- // hex
- case SYS_brk:
- fprintf(stderr, "%s(" Pri_x ")", str_syscalls[nr], (int64_t)args[0]);
- return;
- // oct
- case SYS_umask:
- fprintf(stderr, "%s(" Pri_o ")", str_syscalls[nr], (int64_t)args[0]);
- return;
- // int
- case SYS_dup:
- case SYS_close:
- case SYS_fsync:
- case SYS_fdatasync:
- fprintf(stderr, "%s(" Pri_i ")", str_syscalls[nr], (int64_t)args[0]);
- return;
- // uint
- case SYS_alarm:
- fprintf(stderr, "%s(" Pri_u ")", str_syscalls[nr], (uint64_t)args[0]);
- return;
- // syscall0
- case SYS_getpid:
- case SYS_getppid:
- case SYS_munlockall:
- case SYS_setsid:
- case SYS_sync:
- case SYS_fork:
- case SYS_vfork:
- case SYS_pause:
- fprintf(stderr, "%s()", str_syscalls[nr]);
- return;
+#include "syscalls_cases.h"
// fallback
default:
assert(nr < SYSCALLS_MAX);
diff --git a/syscalls.sh b/syscalls.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+while read syscall args
+do
+ fmt='"%s("'
+ fmt_args='str_syscalls[nr]'
+ fmt_sep=''
+
+ n=0
+ for i in $args; do
+ case $i in
+ "")
+ break
+ ;;
+ "size")
+ fmt="${fmt}${fmt_sep}\"%zd\""
+ fmt_args="${fmt_args}, (size_t)args[$n]"
+ ;;
+ "off")
+ fmt="${fmt}${fmt_sep}Pri_u"
+ fmt_args="${fmt_args}, (off_t)args[$n]"
+ ;;
+ "uint")
+ fmt="${fmt}${fmt_sep}Pri_u"
+ fmt_args="${fmt_args}, (uint64_t)args[$n]"
+ ;;
+ "int")
+ fmt="${fmt}${fmt_sep}Pri_i"
+ fmt_args="${fmt_args}, (int64_t)args[$n]"
+ ;;
+ "oct")
+ fmt="${fmt}${fmt_sep}Pri_o"
+ fmt_args="${fmt_args}, (int64_t)args[$n]"
+ ;;
+ "hex"|"buf")
+ fmt="${fmt}${fmt_sep}Pri_x"
+ fmt_args="${fmt_args}, (int64_t)args[$n]"
+ ;;
+ "path")
+ fmt="${fmt}${fmt_sep}Pri_str"
+ fmt_args="${fmt_args}, read_str(args[$n], PATH_MAX)"
+ ;;
+ *)
+ echo "syscalls.sh: error: Unhandled type ${i}" >&2
+ exit 1
+ esac
+ : $((n+=1))
+ fmt_sep=' ", " '
+ done
+
+ fmt="${fmt}"' ")"'
+
+ printf ' case SYS_%s:\n' "$syscall"
+ printf ' fprintf(stderr, %s, %s);\n' "$fmt" "$fmt_args"
+ printf ' return;\n'
+done <syscalls.txt >syscalls_cases.h
diff --git a/syscalls.txt b/syscalls.txt
@@ -0,0 +1,46 @@
+access path oct
+alarm uint
+brk hex
+chdir path
+chmod path oct
+chown path int int
+close int
+creat path oct
+dup int
+dup2 int int
+execve path hex hex
+faccessat int path oct oct
+fchmod int oct
+fdatasync int
+fork
+fsync int
+ftruncate int off
+getcwd path size
+getpid
+getppid
+kill int int
+lchown path int int
+link path path
+linkat int path path
+lstat path hex
+mkdir path oct
+munlockall
+open path oct oct
+openat int path oct oct
+pause
+read int buf size
+readlink path buf size
+readlinkat int path buf size
+rename path path
+rmdir path
+setsid
+stat path hex
+symlink path path
+symlinkat int path path
+sync
+truncate path off
+umask oct
+unlink path
+unlinkat int path
+vfork
+write int buf size