SuperAPI AI Directory

re-tracing

Coding & development

View repository

Updated 10-16 05:07

About this skill

System call/function call tracing

When to use / when not to use

  • Use: observe program runtime behavior (file/network/process operations); record system call and library call sequences as evidence; locate dynamically resolved APIs (after GetProcAddress/dlopen)
  • Don't use: when you only need memory contents (use [[re-memdump]]); when you only need static logic (decompilation skill)
  • Don't use: for Windows targets use APIMonitor/ProcMon (this skill is mainly Linux/macOS)

Tool preparation

Refer to [[re-analyze/platform-tips]] highest principle—tracing is dynamic execution, by default performed inside a sandbox, with network isolation.

strace(Linux)

  • Debian/Ubuntu: apt install strace
  • Fedora/RHEL: dnf install strace
  • Arch: pacman -S strace
  • WSL: Linux packages directly usable
  • Verify: strace -V
  • Common options:-f follow child processes,-o write to file,-e trace= filter,-s 200 enlarge string display (default 32 bytes),-x non-ASCII to hex,-y/-yy resolve fd to path,-c summary statistics,-p attach—for quick reference and combinations see [[commands]]

ltrace (Linux library calls)

  • Debian/Ubuntu: apt install ltrace
  • Fedora/RHEL: dnf install ltrace
  • Arch: pacman -S ltrace
  • Verify: ltrace -V

dtruss (macOS, DTrace version of strace)

  • Included with macOS (with Xcode CLT); requires root and is limited in some SIP scenarios
  • Verify: sudo dtruss -c ls / 2>&1 | head output deduplicated call statistics

APIMonitor / ProcMon(Windows)

  • APIMonitor: download zip from rohitab.com, unzip and use
  • ProcMon: Microsoft Sysinternals —— choco install sysinternals(or download from official site)
  • Verify: opening APIMonitor/ProcMon can list and attach to processes

Operation steps

  1. strace -f full process tree tracing:

    strace -f -o trace.log ./target args
    

    -f Must add: follow fork/vfork/clone child processes—without it all child process behavior is missed. -tt add microsecond timestamps,-T add per-call duration (clues for network waits/slow calls);-s 200 enlarge string display (default 32 bytes, must add when paths/arguments are not fully visible). For an already running target use attach (cannot see calls before attach):

    sudo strace -f -p <pid> -o attach.log     # attach 需要与目标同权限
    strace -f -c ./target                      # 退出时打印系统调用计数/耗时汇总(热点定位)
    
  2. Filtering (-e trace=...):

    strace -f -e trace=network,file ./target     # 只看网络与文件
    strace -f -e trace=write,read ./target       # 只看读写
    strace -f -e trace=execve,fork,clone ./target # 只看进程行为
    strace -f -e trace=!futex ./target           # 排除噪声(futex 高频)
    

    Filtering rules are whitelist first then blacklist, to control output volume (see pitfall 2).

  3. ltrace library calls:

    ltrace -f -o lib.log ./target
    ltrace -e malloc+free ./target        # 只跟踪指定库函数
    ltrace -l /path/libfoo.so ./target    # 跟踪 dlopen 动态加载的库
    ltrace -f -S ./target                 # 库调用 + 系统调用一起跟踪
    ltrace -f -c ./target                 # 退出时库调用汇总
    

    Dynamically resolved APIs (functions obtained viadlsym ) will not appear in the static IAT, but will appear in ltrace output—complementary to [[re-imports]].

  4. Save output as evidence:

    strace -f -tt -o evidence/trace-$(date +%s).log ./target
    # 或
    ltrace -f -o evidence/libcall.log ./target
    

    Each record carries pid and timestamp; after analysis, cite the file paths and hashes in notes (store sha256 for both sample and logs, see [[re-triage]]).

  5. On Windows use APIMonitor/ProcMon:

    • APIMonitor: run (as administrator) → select the target process → check the API categories to monitor (File/Network/Registry/Process) → attach, observe call arguments and return values
    • ProcMon: system-wide (file/registry/network/process events), first filter by process (Process Name filter to the target name), then filter by Operation
    • Suspicious point: consecutive call sequences to injection-type APIs (OpenProcess→VirtualAllocEx→WriteProcessMemory→CreateRemoteThread) are evidence of malicious behavior

Instruction-level tracing

One level deeper than system call level—instruction-granularity execution flow:

  • QEMU plugin:-plugin loads instruction-level trace plugins (instruction granularity, call/ret paths, guest code block events); use cases — restoring the real path after unpacking, deobfuscation (static obfuscation cannot hide actual execution)
  • Intel PT: hardware trace (perf record -e intel_pt) → decode (perf script or third-party parsing) → branch flow restoration; use cases — complete execution path with no instrumentation overhead
  • trace analysis: hotspots (sorted by execution frequency), path restoration (call chain reconstruction), and integration with [[re-deobfuscate]] (filter dead code by the real path)
  • output: instruction-level execution flow summary (for [[re-analyze/analysis-contract]] evidence archiving)

cross-domain combination

  • [[re-binary-core]]: workflow step 6 (behavior tracking)
  • [[re-malware]]: malicious behavior observation (callback/persistence/autostart)
  • [[re-cracking]]: monitoring validation/registration-related API call parameters
  • complements [[re-imports]] (dynamic API resolution); when anti-debugging is found, switch to [[re-anti-analysis]]
  • [[re-ebpf]]: BPF observation/trace forensics restoration — skb/kernel paths that strace cannot cover are complemented by BPF observation

common pitfalls and traps

  • not adding -f misses child processes: after the target forks, the parent process exits/execs, and all behavior of untracked child processes is lost —-f is standard practice
  • huge output: without filtering, logs from large programs can reach GB scale and drag down the disk — first -e trace= whitelist, and if necessary -o write to a file instead of the terminal
  • anti-debugging samples detect the trace environment:ptrace state detection/LD_PRELOAD traces expose strace/ltrace — use in combination with the anti-debugging bypass in [[re-anti-analysis]]
  • ltrace by default only tracks PLT-level calls —dlopen library functions loaded afterward require adding -l to specify explicitly
  • For the command family quick reference and operation sequences, see [[commands]]; for tool-specific pitfalls and version differences, see [[gotchas]]