> For the complete documentation index, see [llms.txt](https://cajac.gitbook.io/ctf-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cajac.gitbook.io/ctf-notes/rev-eng/other-tools/strace.md).

# strace

**strace** is a useful diagnostic, instructional, and debugging tool.

System administrators, diagnosticians, and troubleshooters will find it invaluable for solving problems with programs for which source code is not readily available, as recompilation is not required for tracing.

Students, hackers, and the overly-curious will discover that a great deal can be learned about a system and its system calls by tracing even ordinary programs. Programmers will find that since system calls and signals occur at the user/kernel interface, a close examination of this boundary is very useful for bug isolation, sanity checking, and attempting to capture race conditions.

## Usage Examples

### General tracing

Execute the binary under `strace`

```bash
strace ./my_binary
```

Execute the binary under `strace` and `grep` the result

```bash
strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"
```

### Trace specific syscalls only

We can trace only a specific syscall with the `-e trace=<syscall>` parameter.

Example

```bash
strace -e trace=newfstatat ./robber
```

### Usage information

<details>

<summary>strace -h</summary>

```bash
┌──(kali㉿kali)-[~]
└─$ strace -h                         
Usage: strace [-ACdffhikqqrtttTvVwxxyyzZ] [-I N] [-b execve] [-e EXPR]...
              [-a COLUMN] [-o FILE] [-s STRSIZE] [-X FORMAT] [-O OVERHEAD]
              [-S SORTBY] [-P PATH]... [-p PID]... [-U COLUMNS] [--seccomp-bpf]
              { -p PID | [-DDD] [-E VAR=VAL]... [-u USERNAME] PROG [ARGS] }
   or: strace -c[dfwzZ] [-I N] [-b execve] [-e EXPR]... [-O OVERHEAD]
              [-S SORTBY] [-P PATH]... [-p PID]... [-U COLUMNS] [--seccomp-bpf]
              { -p PID | [-DDD] [-E VAR=VAL]... [-u USERNAME] PROG [ARGS] }

General:
  -e EXPR        a qualifying expression: OPTION=[!]all or OPTION=[!]VAL1[,VAL2]...
     options:    trace, abbrev, verbose, raw, signal, read, write, fault,
                 inject, status, quiet, kvm, decode-fds

Startup:
  -E VAR=VAL, --env=VAR=VAL
                 put VAR=VAL in the environment for command
  -E VAR, --env=VAR
                 remove VAR from the environment for command
  -p PID, --attach=PID
                 trace process with process id PID, may be repeated
  -u USERNAME, --user=USERNAME
                 run command as USERNAME handling setuid and/or setgid
                 USERNAME may be a user name or a UID:GID pair, where UID
                 and GID are numbers. In the latter case, strace does not
                 perform name lookups.
  --argv0=NAME   set PROG argv[0] to NAME

Tracing:
  -b execve, --detach-on=execve
                 detach on execve syscall
  -D, --daemonize[=grandchild]
                 run tracer process as a grandchild, not as a parent
  -DD, --daemonize=pgroup
                 run tracer process in a separate process group
  -DDD, --daemonize=session
                 run tracer process in a separate session
  -f, --follow-forks
                 follow forks
  -ff, --follow-forks --output-separately
                 follow forks with output into separate files
  -I INTERRUPTIBLE, --interruptible=INTERRUPTIBLE
     1, anywhere:   no signals are blocked
     2, waiting:    fatal signals are blocked while decoding syscall (default)
     3, never:      fatal signals are always blocked (default if '-o FILE PROG')
     4, never_tstp: fatal signals and SIGTSTP (^Z) are always blocked
                    (useful to make 'strace -o FILE PROG' not stop on ^Z)
  --kill-on-exit kill all tracees if strace is killed

Filtering:
  -e trace=[!][?]{{SYSCALL|GROUP|all|/REGEX}[@64|@32|@x32]|none},
   --trace=[!][?]{{SYSCALL|GROUP|all|/REGEX}[@64|@32|@x32]|none}
                 trace only specified syscalls.
     groups:     %clock, %creds, %desc, %file, %fstat, %fstatfs %ipc, %lstat,
                 %memory, %net, %process, %pure, %signal, %stat, %%stat,
                 %statfs, %%statfs
  -e signal=SET, --signal=SET
                 trace only the specified set of signals
                 print only the signals from SET
  -e status=SET, --status=SET
                 print only system calls with the return statuses in SET
     statuses:   successful, failed, unfinished, unavailable, detached
  -e trace-fds=SET, --trace-fds=SET
                 trace operations on file descriptors from SET
  -P PATH, --trace-path=PATH
                 trace accesses to PATH
  -z, --successful-only
                 print only syscalls that returned without an error code
  -Z, --failed-only
                 print only syscalls that returned with an error code

Output format:
  -a COLUMN, --columns=COLUMN
                 alignment COLUMN for printing syscall results (default 40)
  -e abbrev=SET, --abbrev=SET
                 abbreviate output for the syscalls in SET
  -e verbose=SET, --verbose=SET
                 dereference structures for the syscall in SET
  -e raw=SET, --raw=SET
                 print undecoded arguments for the syscalls in SET
  -e read=SET, --read=SET
                 dump the data read from the file descriptors in SET
  -e write=SET, --write=SET
                 dump the data written to the file descriptors in SET
  -e quiet=SET, --quiet=SET
                 suppress various informational messages
     messages:   attach, exit, path-resolution, personality, thread-execve
  -e kvm=vcpu, --kvm=vcpu
                 print exit reason of kvm vcpu
  -e decode-fds=SET, --decode-fds=SET
                 what kinds of file descriptor information details to decode
     details:    dev (device major/minor for block/char device files),
                 eventfd (associated eventfd object details for eventfds),
                 path (file path),
                 pidfd (associated PID for pidfds),
                 socket (protocol-specific information for socket descriptors),
                 signalfd (signal masks for signalfds)
  -i, --instruction-pointer
                 print instruction pointer at time of syscall
  -k, --stack-trace[=symbol]
                 obtain stack trace between each syscall
  --stack-trace-frame-limit=limit
                 obtain no more than this amount of frames
                 when backtracing a syscall (default 256)
  -n, --syscall-number
                 print syscall number
  -o FILE, --output=FILE
                 send trace output to FILE instead of stderr
  -A, --output-append-mode
                 open the file provided in the -o option in append mode
  --output-separately
                 output into separate files (by appending pid to file names)
  -q, --quiet=attach,personality
                 suppress messages about attaching, detaching, etc.
  -qq, --quiet=attach,personality,exit
                 suppress messages about process exit status as well.
  -qqq, --quiet=all
                 suppress all suppressible messages.
  -r, --relative-timestamps[=PRECISION]
                 print relative timestamp
     precision:  one of s, ms, us, ns; default is microseconds
  -s STRSIZE, --string-limit=STRSIZE
                 limit length of print strings to STRSIZE chars (default 32)
  --absolute-timestamps=[[format:]FORMAT[,[precision:]PRECISION]]
                 set the format of absolute timestamps
     format:     none, time, or unix; default is time
     precision:  one of s, ms, us, ns; default is seconds
  -t, --absolute-timestamps[=time]
                 print absolute timestamp
  -tt, --absolute-timestamps=[time,]us
                 print absolute timestamp with usecs
  -ttt, --absolute-timestamps=unix,us
                 print absolute UNIX time with usecs
  -T, --syscall-times[=PRECISION]
                 print time spent in each syscall
     precision:  one of s, ms, us, ns; default is microseconds
  -v, --no-abbrev
                 verbose mode: print entities unabbreviated
  --strings-in-hex=non-ascii-chars
                 use hex instead of octal in escape sequences
  -x, --strings-in-hex=non-ascii
                 print non-ASCII strings in hex
  -xx, --strings-in-hex[=all]
                 print all strings in hex
  -X FORMAT, --const-print-style=FORMAT
                 set the FORMAT for printing of named constants and flags
     formats:    raw, abbrev, verbose
  -y, --decode-fds[=path]
                 print paths associated with file descriptor arguments
  -yy, --decode-fds=all
                 print all available information associated with file
                 descriptors in addition to paths
  --decode-pids=pidns
                 print PIDs in strace's namespace, too
  -Y, --decode-pids=comm
                 print command names associated with PIDs
  --always-show-pid
                 show PID prefix also for the process started by strace

Statistics:
  -c, --summary-only
                 count time, calls, and errors for each syscall and report
                 summary
  -C, --summary  like -c, but also print the regular output
  -O OVERHEAD[UNIT], --summary-syscall-overhead=OVERHEAD[UNIT]
                 set overhead for tracing syscalls to OVERHEAD UNITs
     units:      one of s, ms, us, ns; default is microseconds
  -S SORTBY, --summary-sort-by=SORTBY
                 sort syscall counts by: time, min-time, max-time, avg-time,
                 calls, errors, name, nothing (default time)
  -U COLUMNS, --summary-columns=COLUMNS
                 show specific columns in the summary report: comma-separated
                 list of time-percent, total-time, min-time, max-time, 
                 avg-time, calls, errors, name
                 (default time-percent,total-time,avg-time,calls,errors,name)
  -w, --summary-wall-clock
                 summarise syscall latency (default is system time)

Stop condition:
  --syscall-limit=LIMIT
                 Detach all tracees after tracing LIMIT syscalls

Tampering:
  -e inject=SET[:error=ERRNO|:retval=VALUE][:signal=SIG][:syscall=SYSCALL]
            [:delay_enter=DELAY][:delay_exit=DELAY]
            [:poke_enter=@argN=DATAN,@argM=DATAM...]
            [:poke_exit=@argN=DATAN,@argM=DATAM...]
            [:when=WHEN],
  --inject=SET[:error=ERRNO|:retval=VALUE][:signal=SIG][:syscall=SYSCALL]
           [:delay_enter=DELAY][:delay_exit=DELAY]
           [:poke_enter=@argN=DATAN,@argM=DATAM...]
           [:poke_exit=@argN=DATAN,@argM=DATAM...]
           [:when=WHEN],
                 perform syscall tampering for the syscalls in SET
     delay:      microseconds or NUMBER{s|ms|us|ns}
     when:       FIRST[..LAST][+[STEP]]
  -e fault=SET[:error=ERRNO][:when=WHEN], --fault=SET[:error=ERRNO][:when=WHEN]
                 synonym for -e inject with default ERRNO set to ENOSYS.

Miscellaneous:
  -d, --debug    enable debug output to stderr
  -h, --help     print help message
  --seccomp-bpf  enable seccomp-bpf filtering
  --tips[=[[id:]ID][,[format:]FORMAT]]
                 show strace tips, tricks, and tweaks on exit
     id:         non-negative integer or random; default is random
     format:     none, compact, full; default is compact
  -V, --version  print version

```

</details>

## Resources

**strace** - Linux manual page: <https://man7.org/linux/man-pages/man1/strace.1.html>
