aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-06-25 14:31:34 +0200
committerMattias Andrée <maandree@kth.se>2023-06-25 14:31:34 +0200
commit8e20ec32e64b1e57972835f15e387ac1e8d6a8f6 (patch)
tree4804641f721a0ed9a16af521e4d44246856a27a7
parentAdd more system call formattings (diff)
downloadsctrace-8e20ec32e64b1e57972835f15e387ac1e8d6a8f6.tar.gz
sctrace-8e20ec32e64b1e57972835f15e387ac1e8d6a8f6.tar.bz2
sctrace-8e20ec32e64b1e57972835f15e387ac1e8d6a8f6.tar.xz
Add -a and trivial improvements
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--common.h2
-rw-r--r--linux/os.h4
-rw-r--r--memory.c32
-rw-r--r--print.c4
-rw-r--r--sctrace.113
-rw-r--r--sctrace.c22
6 files changed, 66 insertions, 11 deletions
diff --git a/common.h b/common.h
index 0f478b7..3f899fe 100644
--- a/common.h
+++ b/common.h
@@ -115,10 +115,12 @@ const char *get_errno_name(int err);
const char *get_signum_name(int sig);
/* memory.c */
+extern size_t abbreviate_memory;
char *get_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp);
int get_struct(pid_t pid, unsigned long int addr, void *out, size_t size, const char **errorp);
char *get_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp);
char *escape_memory(const char *str, size_t m);
+char *escape_string(const char *str, size_t m);
char *get_escaped_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp);
char *get_escaped_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp);
diff --git a/linux/os.h b/linux/os.h
index 59092e1..05253c2 100644
--- a/linux/os.h
+++ b/linux/os.h
@@ -37,6 +37,10 @@
# define REGARGS(a, b) a, b
#endif
+#if defined(__arm__) || defined(__thumb__)
+# define USE_PTRACE_SET_SYSCALL
+#endif
+
#ifndef KEY_SPEC_THREAD_KEYRING
# define KEY_SPEC_THREAD_KEYRING -1
diff --git a/memory.c b/memory.c
index 6a05ead..eb1ea75 100644
--- a/memory.c
+++ b/memory.c
@@ -2,6 +2,9 @@
#include "common.h"
+size_t abbreviate_memory = SIZE_MAX;
+
+
char *
get_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp)
{
@@ -133,8 +136,8 @@ istrigraphfinal(char c)
}
-char *
-escape_memory(const char *str, size_t m)
+static char *
+escape(const char *str, size_t m, size_t max)
{
char *ret = NULL;
const char *s, *end;
@@ -149,8 +152,10 @@ escape_memory(const char *str, size_t m)
eprintf("strdup:");
return ret;
}
+ if (max > m)
+ max = m;
add_char(&ret, &size, &len, '"');
- for (s = str, end = &str[m]; s != end; s++) {
+ for (s = str, end = &str[max]; s != end; s++) {
if (n) {
add_char(&ret, &size, &len, *s);
n -= 1;
@@ -209,12 +214,31 @@ escape_memory(const char *str, size_t m)
need_new_string_hex = 0;
}
add_char(&ret, &size, &len, '"');
+ if (m > max) {
+ add_char(&ret, &size, &len, '.');
+ add_char(&ret, &size, &len, '.');
+ add_char(&ret, &size, &len, '.');
+ }
add_char(&ret, &size, &len, '\0');
return ret;
}
char *
+escape_memory(const char *str, size_t m)
+{
+ return escape(str, m, abbreviate_memory);
+}
+
+
+char *
+escape_string(const char *str, size_t m)
+{
+ return escape(str, m, SIZE_MAX);
+}
+
+
+char *
get_escaped_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp)
{
char *r, *ret;
@@ -223,7 +247,7 @@ get_escaped_string(pid_t pid, unsigned long int addr, size_t *lenp, const char *
return NULL;
}
r = get_string(pid, addr, lenp, errorp);
- ret = escape_memory(r, *lenp);
+ ret = escape_string(r, *lenp);
free(r);
return ret;
}
diff --git a/print.c b/print.c
index c8d51e0..77f8f48 100644
--- a/print.c
+++ b/print.c
@@ -764,9 +764,9 @@ print_sockaddr(struct process *proc, const struct sockaddr *addr, socklen_t len)
sun = (const struct sockaddr_un *)addr;
slen = (size_t)len - offsetof(struct sockaddr_un, sun_path);
if (!slen || !sun->sun_path[0] || !memchr(sun->sun_path, 0, slen))
- str = escape_memory(sun->sun_path, slen);
+ str = escape_string(sun->sun_path, slen);
else
- str = escape_memory(sun->sun_path, strlen(sun->sun_path));
+ str = escape_string(sun->sun_path, strlen(sun->sun_path));
tprintf(proc, "{.sun_family = AF_UNIX, .sun_path = %s}", str);
free(str);
return;
diff --git a/sctrace.1 b/sctrace.1
index 61ebfd5..3014563 100644
--- a/sctrace.1
+++ b/sctrace.1
@@ -3,6 +3,8 @@
sctrace - Trace system calls
.SH SYNOPSIS
.B sctrace
+.RB [ -a
+.IR byte-count ]
.RB [ -o
.IR trace-output-file ]
.RB [ -ft ]
@@ -48,12 +50,21 @@ argument rather than the
.I command
argument.
.TP
+.BR -a " "\fIbyte-count\fP
+Limit the displayed number of bytes in any region
+of uninterpreted memory (this excludes strings
+and structures but includes file I/O) to
+.I byte-count
+bytes. The string
+.B inf
+is interpreted to remove previously applied limit.
+.TP
.B -f
Recursively trace all new children and threads.
This option implies
.BR -t .
.TP
-.BR -o " "\fItrace-output-file\fI
+.BR -o " "\fItrace-output-file\fP
Write trace outputs to the file specified in the
.I trace-output-file
argument.
diff --git a/sctrace.c b/sctrace.c
index 320bc3a..976624d 100644
--- a/sctrace.c
+++ b/sctrace.c
@@ -9,7 +9,8 @@ static unsigned long int trace_options = PTRACE_O_EXITKILL | PTRACE_O_TRACESYSGO
_Noreturn static void
usage(void)
{
- fprintf(stderr, "usage: %s [-o trace-output-file] [-ft] (command | -0 command argv0) [argument] ...\n", argv0);
+ fprintf(stderr, "usage: %s [-a byte-count] [-o trace-output-file] [-ft]"
+ " (command | -0 command argv0) [argument] ...\n", argv0);
exit(1);
}
@@ -123,7 +124,7 @@ handle_event(struct process *proc, int status)
proc->state = trace_event == PTRACE_EVENT_CLONE ? CloneParent : ForkParent;
handle_syscall(proc);
}
- tprintf(proc2, "\nTracing new process\n");
+ tprintf(proc2, "\nTracing new process with parent %ju\n", (uintmax_t)proc->pid);
proc2->state = trace_event == PTRACE_EVENT_FORK ? ForkChild :
trace_event == PTRACE_EVENT_VFORK ? VforkChild : CloneChild;
handle_syscall(proc2);
@@ -180,17 +181,29 @@ main(int argc, char **argv)
char *outfile = NULL;
FILE *outfp = stderr;
int status, exit_code = 0, with_argv0 = 0, multiprocess = 0, i;
+ char *arg;
struct process *proc, *proc2;
struct sigaction sa;
sigset_t sm;
/* TODO add option to trace signals with siginfo (-s) */
- /* TODO add option to truncate long syscall arguments and outputs (-a)
- * This should be useful if your program does a lot of I/O */
ARGBEGIN {
case '0':
with_argv0 = 1;
break;
+ case 'a':
+ arg = EARGF(usage());
+ if (!strcmp(arg, "inf")) {
+ abbreviate_memory = SIZE_MAX;
+ break;
+ }
+ if (!isdigit(arg[0]))
+ usage();
+ errno = 0;
+ abbreviate_memory = (size_t)strtoul(arg, &arg, 10);
+ if ((errno && errno != ERANGE) || *arg)
+ usage();
+ break;
case 'o':
if (outfile)
usage();
@@ -286,6 +299,7 @@ main(int argc, char **argv)
if (outfp != stderr)
fclose(outfp);
+ weprintf("Copying exit from %s\n", multiprocess ? "original tracee" : "tracee");
if (WIFSIGNALED(exit_code)) {
exit_code = WTERMSIG(exit_code);
raise(exit_code);