[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-1508":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":36,"readmeContent":37,"aiSummary":38,"trendingCount":15,"starSnapshotCount":15,"syncStatus":39,"lastSyncTime":40,"discoverSource":41},1508,"snoop","pandaadir05\u002Fsnoop","pandaadir05","A modern syscall tracer built on eBPF. Think strace, but with a real TUI, smart filters, TLS decryption, and output that's actually readable.","",null,"Rust",215,10,1,0,4,5,7,12,3.12,"MIT License",false,"main",true,[26,27,28,29,30,31,32,33,34,35],"analysis","cybersecurity","ebpf","linux","low-level","reverse-engineering","rust","syscall","tracer","tui","2026-06-12 02:00:28","# snoop\n\n[![CI](https:\u002F\u002Fgithub.com\u002Fpandaadir05\u002Fsnoop\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fpandaadir05\u002Fsnoop\u002Factions\u002Fworkflows\u002Fci.yml)\n[![License: MIT OR Apache-2.0](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE)\n\nA syscall tracer for Linux, built on eBPF. Like strace but with a live TUI,\nsmart filters, and argument decoding you can actually read.\n\n![snoop TUI demo](demo.gif)\n\n```text\n$ sudo snoop curl https:\u002F\u002Fexample.com\n[   0.001] curl(1234\u002F1234)  openat(AT_FDCWD, \"\u002Fetc\u002Fssl\u002Fcerts\u002Fca-certificates.crt\", O_RDONLY) = 4  \u003C0.031ms>\n[   0.002] curl(1234\u002F1234)  read(4, 0x7f3a1c000b20, 4096) = 4096  \u003C0.012ms>\n[   0.003] curl(1234\u002F1234)  socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 5  \u003C0.008ms>\n[   0.004] curl(1234\u002F1234)  connect(5, 93.184.216.34:443) = 0  \u003C42.187ms>\n[   0.046] curl(1234\u002F1234)  sendto(5, 0x55a3bc001b40, 78, MSG_NOSIGNAL) = 78  \u003C0.011ms>\n```\n\nOr run it without `--raw` and get a full-screen TUI:\n\n```text\n snoop  pid:1234  comm:curl  events:142  elapsed:0.341s\n┌── syscall stream ─────────────────────────────────────┐┌── top syscalls ─────────┐\n│ [  0.001] curl  openat(\"\u002Fetc\u002Fssl\u002F…\") = 4  \u003C0.031ms>  ││ syscall       count  pct│\n│ [  0.002] curl  read(4, …) = 4096                    ││ read            38  26.8%│\n│ [  0.003] curl  socket(AF_INET, …) = 5               ││ write           21  14.8%│\n│ [  0.004] curl  connect(5, 93.184.216.34:443) = 0    ││ openat          18  12.7%│\n│ [  0.046] curl  sendto(5, …) = 78                    ││ mmap            14   9.9%│\n└───────────────────────────────────────────────────────┘└─────────────────────────┘\n [q]uit  [Space]pause  [\u002F]search  [f]iles  [n]et  [c]lear  [↑↓]scroll  [G]bottom\n```\n\n## Why not just use strace?\n\nstrace uses ptrace, which stops your process on every syscall. snoop uses eBPF\ntracepoints instead -- your process keeps running at full speed with the tracing\nhappening in-kernel. Beyond performance, snoop decodes arguments into something\nyou can actually read, has a real-time TUI, and can save\u002Freplay\u002Fdiff traces.\n\n## What it does\n\n- **TUI** -- live scrollable syscall stream with a top-syscalls panel, search,\n  category filters, pause\u002Fresume. Falls back to strace-style line output when\n  stdout isn't a terminal.\n- **Output formats** -- `--raw` (strace-compatible), `--json` (JSON Lines for\n  jq), `--explain` (groups syscalls into high-level activity summaries)\n- **Filters** -- `--files`, `--net`, `--slow 10`, `--syscall openat`\n- **Arg decoding** for 60+ syscalls -- paths, flags, socket addresses, all the\n  stuff you'd normally have to look up in the man page\n- **Attach** to a running process (`-p PID`) or **spawn** one (`snoop \u003Ccmd>`)\n- `--follow` traces forked children too\n- **Containers** -- `--docker \u003Cname>` and `--pod \u003Cname>` trace everything\n  inside a container\n- **TLS capture** -- `--tls` hooks `SSL_write`\u002F`SSL_read` via uprobes to show\n  plaintext\n- **Heap tracing** -- `--ltrace` tracks `malloc`\u002F`free`\u002F`calloc`\u002F`realloc`\n- **Record & replay** -- `snoop record` saves to disk, `snoop view` replays\n  offline (no root needed)\n- **Diff** -- `snoop diff before.snoop after.snoop` shows what changed between\n  two runs\n- **Flamegraph** -- `--flamegraph out.svg`\n\nNo kernel modules, no C toolchain. The eBPF programs are pure Rust (aya) and\nship embedded in the binary.\n\n## Requirements\n\n- Linux 5.8+ (needs BPF ring buffer support)\n- x86_64 or aarch64\n- Root, or `CAP_BPF` + `CAP_PERFMON`\n\n## Installation\n\n### Pre-built binary\n\n```bash\ncurl -L https:\u002F\u002Fgithub.com\u002Fpandaadir05\u002Fsnoop\u002Freleases\u002Flatest\u002Fdownload\u002Fsnoop-x86_64-linux.tar.gz \\\n  | tar -xz\nsudo install -m755 snoop \u002Fusr\u002Flocal\u002Fbin\u002Fsnoop\n```\n\nFor aarch64, replace `x86_64` with `aarch64`.\n\n### From source\n\n```bash\ncargo install --git https:\u002F\u002Fgithub.com\u002Fpandaadir05\u002Fsnoop snoop\n```\n\nThis builds the eBPF programs automatically. No C toolchain or kernel headers\nneeded, just Rust.\n\n## Usage\n\n```bash\n# Trace a command\nsudo snoop ls \u002Fetc\nsudo snoop -- nginx -g 'daemon off;'\n\n# Attach to a running process\nsudo snoop -p $(pidof postgres)\nsudo snoop -p 1234 --follow        # trace forked children too\n\n# Containers\nsudo snoop --docker my-nginx\nsudo snoop --pod my-app-pod --namespace production\n\n# Filtering\nsudo snoop -p 1234 --files         # only file-system calls\nsudo snoop -p 1234 --net           # only network calls\nsudo snoop -p 1234 --slow 5        # only calls slower than 5ms\nsudo snoop -p 1234 --syscall openat --syscall read\n```\n\n### Explain mode\n\n`--explain` groups raw syscalls into high-level summaries instead of showing\nevery call individually:\n\n```bash\nsudo snoop -p 1234 --explain\n```\n\n```text\nREAD   \u002Fetc\u002Fpasswd          ↓1.2 KB   (2 calls, 0.80ms)\nNET    127.0.0.1:5432       ↑512 B ↓4.0 KB   (18.20ms)\nEXEC   \u002Fusr\u002Fbin\u002Fpython3\n```\n\n### TLS decryption\n\nHooks `SSL_write`\u002F`SSL_read` in OpenSSL to capture plaintext:\n\n```bash\nsudo snoop -p 1234 --tls\n```\n\n### Heap tracing\n\n```bash\nsudo snoop -p 1234 --ltrace\n```\n\n### Record and replay\n\nRecord a trace, then replay it later without root:\n\n```bash\nsudo snoop record -p 1234 -o trace.snoop\n\nsnoop view trace.snoop\nsnoop view trace.snoop --files --slow 5 --json | jq 'select(.name==\"read\")'\n```\n\n### Diff two traces\n\nUseful for spotting regressions after a deploy:\n\n```bash\nsudo snoop record -p 1234 -o before.snoop\n# ... deploy change ...\nsudo snoop record -p 1234 -o after.snoop\n\nsnoop diff before.snoop after.snoop\n```\n\n```text\nSYSCALL COUNTS\n  read      1200 → 1800  (+50.0%)  ▲\n  openat     340 →  210  (-38.2%)  ▼\n\nDURATION REGRESSIONS (median)\n  read      0.02ms → 0.08ms  (+300%)\n\nONLY IN after\n  statx (4x)\n```\n\n### JSON output\n\n```bash\nsudo snoop -p 1234 --json | jq 'select(.name == \"connect\")'\n```\n\n### Export a flamegraph\n\n```bash\nsudo snoop -p 1234 --flamegraph syscalls.svg\n```\n\n## Flags\n\n```text\n  -p, --pid \u003CPID>           Attach to a running process\n      --follow              Trace forked children (requires --pid)\n      --docker \u003CNAME|ID>    Trace all processes in a Docker container\n      --pod \u003CPOD>           Trace all processes in a Kubernetes pod\n  -n, --namespace \u003CNS>      Kubernetes namespace (default: default)\n\n      --raw                 One-line strace-compatible output\n      --json                JSON Lines — one object per syscall\n      --explain             Semantic activity summaries\n\n      --files               File-system syscalls only\n      --net                 Network syscalls only\n      --slow \u003CMILLIS>       Only calls slower than threshold\n      --syscall \u003CNAME>      Only this syscall (repeatable)\n      --no-decode           Raw hex arguments, no decoding\n\n      --tls                 Capture TLS plaintext via SSL_write\u002FSSL_read uprobes\n      --ltrace              Trace malloc\u002Ffree\u002Fcalloc\u002Frealloc\n\n      --flamegraph \u003CPATH>   Write flamegraph SVG on exit\n      --ebpf-obj \u003CPATH>     Override embedded eBPF object [$SNOOP_EBPF_OBJ]\n```\n\n## TUI keybindings\n\n| Key | Action |\n| --- | --- |\n| `q` | Quit |\n| `Space` | Pause \u002F resume |\n| `\u002F` | Incremental search |\n| `f` | Toggle file-system filter |\n| `n` | Toggle network filter |\n| `c` | Clear event list |\n| `Enter` | Show detail popup for selected event |\n| `↑` \u002F `k` | Scroll up |\n| `↓` \u002F `j` | Scroll down |\n| `G` \u002F `End` | Jump to latest event |\n| `g` \u002F `Home` | Jump to oldest event |\n\n## How it works\n\nTwo eBPF programs attach to `raw_syscalls\u002Fsys_enter` and `sys_exit`. On entry,\nthe syscall number and arguments go into a per-thread scratch map. On exit, the\nreturn value gets paired with the entry data and pushed to a ring buffer.\nUserspace drains the ring buffer over an async fd and runs everything through\nthe filter\u002Fdecode pipeline.\n\n```text\nkernel                               userspace\n──────                               ─────────\nraw_syscalls\u002Fsys_enter  ──►  SYSCALL_ENTER map (per-tid scratch)\nraw_syscalls\u002Fsys_exit   ──►  EVENTS ring buffer (4 MiB)\n                                  │\n                        poll consumer (tokio::spawn)\n                                  │\n                       ┌──────────┴──────────┐\n                   RawOutput             TuiApp\n                 (one line\u002Fsyscall)   (ratatui TUI)\n```\n\neBPF programs are written in Rust with [aya](https:\u002F\u002Fgithub.com\u002Faya-rs\u002Faya),\ncompiled to BPF bytecode at build time, and embedded in the binary. No runtime\ndependencies, no kernel headers.\n\n## Building from source\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fpandaadir05\u002Fsnoop\ncd snoop\n\n# Nightly is only needed for the BPF target\nrustup toolchain install nightly\nrustup component add rust-src --toolchain nightly\n\n# bpf-linker links the eBPF object (no system LLVM needed)\ncargo install bpf-linker --no-default-features\n\ncargo build --release\nsudo .\u002Ftarget\u002Frelease\u002Fsnoop -p $$\n```\n\nThe build script compiles the eBPF programs automatically. No separate step\nneeded.\n\nDuring development you can also use xtask:\n\n```bash\ncargo xtask run -- -p $$\n```\n\n## Stack\n\n| Layer | Crate |\n| --- | --- |\n| eBPF programs | `aya-ebpf` |\n| eBPF loader | `aya` |\n| TUI | `ratatui` + `crossterm` |\n| CLI | `clap` (derive) |\n| Async runtime | `tokio` |\n| Flamegraph | `inferno` |\n\n## License\n\nMIT or Apache-2.0, at your option.\n","snoop 是一个基于 eBPF 的现代系统调用追踪工具，旨在提供比 strace 更友好的用户体验。它具有实时 TUI 界面、智能过滤器和可读性强的输出格式，支持 TLS 解密等功能。核心功能包括：实时滚动显示系统调用流、多种输出格式（如 `--raw` 和 `--json`）、丰富的过滤选项（如文件、网络、慢速调用等），以及对 60 多个系统调用参数的解码。snoop 适合需要高效监控和分析 Linux 系统调用的应用场景，特别是在网络安全、逆向工程及低级调试等领域。",2,"2026-06-11 02:44:22","CREATED_QUERY"]