logo

mstrace

Small Linux strace(1) implementation
commit: 3f004e71507247c1ea0c9ce0183838ec4570a72b
parent b1ab1aca67934866324807306176375f4e08b06c
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 27 Nov 2024 21:33:06 +0100

rename from ministrace to mstrace

Diffstat:

M.gitignore4++--
MMakefile10+++++-----
Dministrace.c139-------------------------------------------------------------------------------
Amstrace.c139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mprint_syscall.c2+-
Mstrsyscall.sh2+-
6 files changed, 148 insertions(+), 148 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,7 +1,7 @@ -# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+ministrace@hacktivis.me> +# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+mstrace@hacktivis.me> # SPDX-License-Identifier: 0BSD -/ministrace +/mstrace /strsyscall.c /strsyscall.h /tmp_strsyscall.h diff --git a/Makefile b/Makefile @@ -1,8 +1,8 @@ -# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+ministrace@hacktivis.me> +# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+mstrace@hacktivis.me> # SPDX-License-Identifier: MPL-2.0 -ministrace: ministrace.c strsyscall.c print_syscall.o - ${CC} -std=c99 ${CFLAGS} -o ministrace ministrace.c strsyscall.c print_syscall.o ${LDFLAGS} ${LDSTATIC} +mstrace: mstrace.c strsyscall.c print_syscall.o + ${CC} -std=c99 ${CFLAGS} -o mstrace mstrace.c strsyscall.c print_syscall.o ${LDFLAGS} ${LDSTATIC} print_syscall.o: print_syscall.c syscalls_cases.h @@ -17,8 +17,8 @@ strsyscall.c: strsyscall.sh tmp_strsyscall.h .PHONY: clean clean: - rm -f ministrace tmp_strsyscall.h strsyscall.c print_syscall.o + rm -f mstrace tmp_strsyscall.h strsyscall.c print_syscall.o .PHONY: format format: - clang-format -style=file -assume-filename=.clang-format -i ministrace.c print_syscall.c + clang-format -style=file -assume-filename=.clang-format -i mstrace.c print_syscall.c diff --git a/ministrace.c b/ministrace.c @@ -1,139 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+ministrace@hacktivis.me> -// SPDX-License-Identifier: MPL-2.0 - -#define _DEFAULT_SOURCE - -#include <errno.h> -#include <inttypes.h> // PRIu64 -#include <linux/ptrace.h> // ptrace_syscall_info, __u64 -#include <stdbool.h> -#include <stdio.h> // fprintf -#include <string.h> // strerror -#include <sys/ptrace.h> // ptrace() -#include <sys/wait.h> -#include <unistd.h> // getpid, fork, execvp - -extern void print_syscall(__u64 nr, __u64 args[6]); - -pid_t child = -1; - -static int -wait_for_syscall(int *status) -{ - while(1) - { - ptrace(PTRACE_SYSCALL, child, 0, 0); - waitpid(child, status, 0); - - if(WIFSTOPPED(*status) && WSTOPSIG(*status) & 0x80) return 0; - - if(WIFEXITED(*status)) return 1; - } -} - -int -main(int argc, char *argv[]) -{ - argc -= 1; - argv += 1; - - if(argc < 1) - { - fprintf(stderr, "Usage: ministrace <command> [args...]\n"); - return 1; - } - - child = fork(); - if(child < 0) - { - fprintf(stderr, "ministrace: error: Failed creating child process: %s\n", strerror(errno)); - return 1; - } - else if(child == 0) - { - errno = 0; - int ret = ptrace(PTRACE_TRACEME); - if(ret < 0 && errno != 0) - { - fprintf(stderr, "ministrace: error: Failed ptrace(PTRACE_TRACEME): %s\n", strerror(errno)); - return 1; - } - - if(kill(getpid(), SIGSTOP) < 0) - { - fprintf(stderr, "ministrace: error: Failed stopping parent: %s\n", strerror(errno)); - return 1; - } - - execvp(argv[0], argv); - - return 1; - } - - bool neednl = false; - - int status; - waitpid(child, &status, 0); - ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD); - while(1) - { - if(wait_for_syscall(&status) != 0) break; - - struct ptrace_syscall_info syscall_info; - long ret = - ptrace(PTRACE_GET_SYSCALL_INFO, child, sizeof(struct ptrace_syscall_info), &syscall_info); - if(ret < 0) - { - fprintf( - stderr, - "ministrace: error: Failed getting syscall information via PTRACE_GET_SYSCALL_INFO: %s\n", - strerror(errno)); - continue; - } - - switch(syscall_info.op) - { - case PTRACE_SYSCALL_INFO_ENTRY: - print_syscall(syscall_info.entry.nr, syscall_info.entry.args); - neednl = true; - break; - case PTRACE_SYSCALL_INFO_EXIT: - if(syscall_info.exit.is_error) - { - fprintf(stderr, - " = (errno: %" PRIi64 ") %s\n", - (int64_t)(-syscall_info.exit.rval), - strerror(-syscall_info.exit.rval)); - } - else - { - fprintf(stderr, " = %" PRIi64 "\n", (int64_t)syscall_info.exit.rval); - } - neednl = false; - break; - case PTRACE_SYSCALL_INFO_SECCOMP: - print_syscall(syscall_info.seccomp.nr, syscall_info.seccomp.args); - neednl = true; - - // TODO: Check how strace manages this - fprintf(stderr, " [seccomp_ret = %" PRIu32 "]", syscall_info.seccomp.ret_data); - break; - case PTRACE_SYSCALL_INFO_NONE: - if(neednl) fprintf(stderr, "\n"); - - fprintf(stderr, "[syscall-info] none\n"); - neednl = false; - break; - } - } - - if(neednl) fprintf(stderr, "\n"); - - if(WIFEXITED(status)) - { - fprintf(stderr, "+++ exited with %d +++\n", WEXITSTATUS(status)); - return WEXITSTATUS(status); - } - - return 0; -} diff --git a/mstrace.c b/mstrace.c @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+mstrace@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +#define _DEFAULT_SOURCE + +#include <errno.h> +#include <inttypes.h> // PRIu64 +#include <linux/ptrace.h> // ptrace_syscall_info, __u64 +#include <stdbool.h> +#include <stdio.h> // fprintf +#include <string.h> // strerror +#include <sys/ptrace.h> // ptrace() +#include <sys/wait.h> +#include <unistd.h> // getpid, fork, execvp + +extern void print_syscall(__u64 nr, __u64 args[6]); + +pid_t child = -1; + +static int +wait_for_syscall(int *status) +{ + while(1) + { + ptrace(PTRACE_SYSCALL, child, 0, 0); + waitpid(child, status, 0); + + if(WIFSTOPPED(*status) && WSTOPSIG(*status) & 0x80) return 0; + + if(WIFEXITED(*status)) return 1; + } +} + +int +main(int argc, char *argv[]) +{ + argc -= 1; + argv += 1; + + if(argc < 1) + { + fprintf(stderr, "Usage: mstrace <command> [args...]\n"); + return 1; + } + + child = fork(); + if(child < 0) + { + fprintf(stderr, "mstrace: error: Failed creating child process: %s\n", strerror(errno)); + return 1; + } + else if(child == 0) + { + errno = 0; + int ret = ptrace(PTRACE_TRACEME); + if(ret < 0 && errno != 0) + { + fprintf(stderr, "mstrace: error: Failed ptrace(PTRACE_TRACEME): %s\n", strerror(errno)); + return 1; + } + + if(kill(getpid(), SIGSTOP) < 0) + { + fprintf(stderr, "mstrace: error: Failed stopping parent: %s\n", strerror(errno)); + return 1; + } + + execvp(argv[0], argv); + + return 1; + } + + bool neednl = false; + + int status; + waitpid(child, &status, 0); + ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD); + while(1) + { + if(wait_for_syscall(&status) != 0) break; + + struct ptrace_syscall_info syscall_info; + long ret = + ptrace(PTRACE_GET_SYSCALL_INFO, child, sizeof(struct ptrace_syscall_info), &syscall_info); + if(ret < 0) + { + fprintf( + stderr, + "mstrace: error: Failed getting syscall information via PTRACE_GET_SYSCALL_INFO: %s\n", + strerror(errno)); + continue; + } + + switch(syscall_info.op) + { + case PTRACE_SYSCALL_INFO_ENTRY: + print_syscall(syscall_info.entry.nr, syscall_info.entry.args); + neednl = true; + break; + case PTRACE_SYSCALL_INFO_EXIT: + if(syscall_info.exit.is_error) + { + fprintf(stderr, + " = (errno: %" PRIi64 ") %s\n", + (int64_t)(-syscall_info.exit.rval), + strerror(-syscall_info.exit.rval)); + } + else + { + fprintf(stderr, " = %" PRIi64 "\n", (int64_t)syscall_info.exit.rval); + } + neednl = false; + break; + case PTRACE_SYSCALL_INFO_SECCOMP: + print_syscall(syscall_info.seccomp.nr, syscall_info.seccomp.args); + neednl = true; + + // TODO: Check how strace manages this + fprintf(stderr, " [seccomp_ret = %" PRIu32 "]", syscall_info.seccomp.ret_data); + break; + case PTRACE_SYSCALL_INFO_NONE: + if(neednl) fprintf(stderr, "\n"); + + fprintf(stderr, "[syscall-info] none\n"); + neednl = false; + break; + } + } + + if(neednl) fprintf(stderr, "\n"); + + if(WIFEXITED(status)) + { + fprintf(stderr, "+++ exited with %d +++\n", WEXITSTATUS(status)); + return WEXITSTATUS(status); + } + + return 0; +} diff --git a/print_syscall.c b/print_syscall.c @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+ministrace@hacktivis.me> +// SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+mstrace@hacktivis.me> // SPDX-License-Identifier: MPL-2.0 #define _DEFAULT_SOURCE diff --git a/strsyscall.sh b/strsyscall.sh @@ -1,5 +1,5 @@ #!/bin/sh -# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+ministrace@hacktivis.me> +# SPDX-FileCopyrightText: 2024 Haelwenn (lanodan) Monnier <contact+mstrace@hacktivis.me> # SPDX-License-Identifier: MPL-2.0 grep -F '#define SYS_' tmp_strsyscall.h | sort -n -k 3 -r | head -1 | if read op name num; then