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:
-ffollow child processes,-owrite to file,-e trace=filter,-s 200enlarge string display (default 32 bytes),-xnon-ASCII to hex,-y/-yyresolve fd to path,-csummary statistics,-pattach—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 | headoutput 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
-
strace -f full process tree tracing:
strace -f -o trace.log ./target args-fMust add: follow fork/vfork/clone child processes—without it all child process behavior is missed.-ttadd microsecond timestamps,-Tadd per-call duration (clues for network waits/slow calls);-s 200enlarge 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 # 退出时打印系统调用计数/耗时汇总(热点定位) -
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).
-
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 via
dlsym) will not appear in the static IAT, but will appear in ltrace output—complementary to [[re-imports]]. -
Save output as evidence:
strace -f -tt -o evidence/trace-$(date +%s).log ./target # 或 ltrace -f -o evidence/libcall.log ./targetEach 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]]).
-
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:
-pluginloads 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 scriptor 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 —
-fis 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-owrite to a file instead of the terminal - anti-debugging samples detect the trace environment:
ptracestate detection/LD_PRELOADtraces expose strace/ltrace — use in combination with the anti-debugging bypass in [[re-anti-analysis]] - ltrace by default only tracks PLT-level calls —
dlopenlibrary functions loaded afterward require adding-lto specify explicitly - For the command family quick reference and operation sequences, see [[commands]]; for tool-specific pitfalls and version differences, see [[gotchas]]