[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EHTK51QWK1ABV63PET3NB4":3,"skill-same:01M6EHTK51QWK1ABV63PET3NB4":72},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":6,"ownerDescription":56,"updatedAt":57,"install":58,"resources":71},"01M6EHTK51QWK1ABV63PET3NB4","binary-re-dynamic-analysis",null,"Use when you need to run a binary, trace execution, or observe runtime behavior. Runtime analysis via QEMU emulation, GDB debugging, and Frida hooking - syscall tracing (strace), breakpoints, memory inspection, function interception. Keywords - \"run binary\", \"execute\", \"debug\", \"trace syscalls\", \"set breakpoint\", \"qemu\", \"gdb\", \"frida\", \"strace\", \"watch memory\"","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002F2389-research\u002Fbinary-re\u002Fdynamic-analysis\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"binary re dynamic analysis","dynamic analysis","binary","analysis","execute","via","watch","runtime","gdb","observe","use","memory","behavior","execution","SET","frida","tracing","run","debugging","debug","2026-11-10 10:12:30",false,"---\nname: binary-re-dynamic-analysis\ndescription: Use when you need to run a binary, trace execution, or observe runtime behavior. Runtime analysis via QEMU emulation, GDB debugging, and Frida hooking - syscall tracing (strace), breakpoints, memory inspection, function interception. Keywords - \"run binary\", \"execute\", \"debug\", \"trace syscalls\", \"set breakpoint\", \"qemu\", \"gdb\", \"frida\", \"strace\", \"watch memory\"\n---\n\n# Dynamic Analysis (Phase 4)\n\n## Purpose\n\nObserve actual runtime behavior. Verify hypotheses from static analysis. Capture data that's only visible during execution.\n\n## Human-in-the-Loop Requirement\n\n**CRITICAL: All execution requires human approval.**\n\nBefore running ANY binary:\n1. Confirm sandbox configuration is acceptable\n2. Verify network isolation if required\n3. Document what execution will attempt\n4. Get explicit approval\n\n## Platform Support Matrix\n\n| Host Platform | Target Arch | Method | Complexity |\n|---------------|-------------|--------|------------|\n| Linux x86_64 | ARM32\u002F64, MIPS | Native `qemu-user` | Low |\n| Linux x86_64 | x86-32 | Native or `linux32` | Low |\n| macOS (any) | ARM32\u002F64 | Docker + binfmt | Medium |\n| macOS (any) | x86-32 | Docker `--platform linux\u002Fi386` | Medium |\n| Windows | Any | WSL2 → Linux method | Medium |\n\n### macOS Docker Setup (One-Time)\n\n```bash\n# Start Docker runtime (Colima, Docker Desktop, etc.)\ncolima start\n\n# Register ARM emulation handlers (requires privileged mode)\ndocker run --rm --privileged --platform linux\u002Farm64 \\\n  tonistiigi\u002Fbinfmt --install arm\n```\n\n### Docker Mount Best Practices\n\n**CRITICAL:** On Colima, `\u002Ftmp` mounts often fail silently. Always use home directory paths:\n\n```bash\n# ✅ GOOD - use home directory\ndocker run -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro ...\n\n# ❌ BAD - \u002Ftmp mounts can fail on Colima\ndocker run -v \u002Ftmp\u002Fsamples:\u002Fwork:ro ...\n```\n\n---\n\n## Analysis Options\n\n| Method | Isolation | Granularity | Best For |\n|--------|-----------|-------------|----------|\n| QEMU -strace | High | Syscall level | Initial behavior mapping |\n| QEMU + GDB | High | Instruction level | Detailed debugging |\n| Docker | High | Process level | Cross-arch on macOS |\n| Frida | Medium | Function level | Hooking without recompilation |\n| On-device | Low | Full system | When emulation fails |\n\n## Option A: QEMU User-Mode with Syscall Trace\n\n**Safest approach - runs in isolation with syscall logging.**\n\n### Setup\n\n```bash\n# Verify sysroot exists\nls \u002Fusr\u002Farm-linux-gnueabihf\u002Flib\u002Flibc.so*\n\n# ARM 32-bit execution\nqemu-arm -L \u002Fusr\u002Farm-linux-gnueabihf -strace -- .\u002Fbinary\n\n# ARM 64-bit execution\nqemu-aarch64 -L \u002Fusr\u002Faarch64-linux-gnu -strace -- .\u002Fbinary\n```\n\n### Sysroot Selection\n\n| Binary ABI | Sysroot Path | QEMU Flag |\n|------------|--------------|-----------|\n| ARM glibc hard-float | `\u002Fusr\u002Farm-linux-gnueabihf` | `-L` |\n| ARM glibc soft-float | `\u002Fusr\u002Farm-linux-gnueabi` | `-L` |\n| ARM64 glibc | `\u002Fusr\u002Faarch64-linux-gnu` | `-L` |\n| ARM musl | Custom extraction needed | `-L` |\n\n### Environment Control\n\n```bash\n# Set environment variables\nqemu-arm -L \u002Fsysroot \\\n  -E HOME=\u002Ftmp \\\n  -E USER=nobody \\\n  -E LD_DEBUG=bindings \\\n  -- .\u002Fbinary\n\n# Unset dangerous variables\nqemu-arm -L \u002Fsysroot \\\n  -U LD_PRELOAD \\\n  -- .\u002Fbinary\n```\n\n### Syscall Analysis\n\nStrace output patterns to watch:\n\n```bash\n# Network activity\nopenat.*socket\nconnect(.*AF_INET\nsendto\\|send\\|write.*socket\nrecvfrom\\|recv\\|read.*socket\n\n# File access\nopenat.*O_RDONLY.*\"\u002Fetc\nopenat.*O_WRONLY\nstat\\|lstat.*\"\u002F\n\n# Process operations\nexecve\nfork\\|clone\n```\n\n## Option B: QEMU + GDB for Deep Debugging\n\n**Attach debugger for instruction-level control.**\n\n### Launch Binary Under GDB\n\n```bash\n# Start QEMU with GDB server\nqemu-arm -g 1234 -L \u002Fusr\u002Farm-linux-gnueabihf .\u002Fbinary &\n\n# Connect with gdb-multiarch\ngdb-multiarch -q \\\n  -ex \"set architecture arm\" \\\n  -ex \"target remote :1234\" \\\n  -ex \"source ~\u002F.gdbinit-gef.py\" \\\n  .\u002Fbinary\n```\n\n### GDB Commands for RE\n\n```gdb\n# Breakpoints\nbreak *0x8400              # Address\nbreak main                 # Symbol\nbreak *0x8400 if $r0 == 5  # Conditional\n\n# Execution control\ncontinue                   # Run until break\nstepi                      # Single instruction\nnexti                      # Step over calls\nfinish                     # Run until return\n\n# Inspection\ninfo registers             # All registers\nx\u002F20i $pc                  # Disassemble from PC\nx\u002F10wx $sp                 # Stack contents\nx\u002Fs 0x12345                # String at address\n\n# Memory\nfind 0x8000, 0x10000, \"pattern\"  # Search memory\ndump memory \u002Ftmp\u002Fmem.bin 0x8000 0x9000  # Extract region\n```\n\n### GEF Enhancements\n\nWith GEF loaded, additional commands:\n\n```gdb\ngef> vmmap                 # Memory layout\ngef> checksec              # Security features\ngef> context               # Full state display\ngef> hexdump qword $sp 10  # Better hex dump\ngef> pcustom               # Structure definitions\n```\n\n### Batch Debugging Script\n\n```bash\n# Create GDB script\ncat > analyze.gdb \u003C\u003C 'EOF'\nset architecture arm\ntarget remote :1234\nbreak main\ncontinue\ninfo registers\nx\u002F20i $pc\ncontinue\nquit\nEOF\n\n# Run batch\ngdb-multiarch -batch -x analyze.gdb .\u002Fbinary\n```\n\n## Option C: Frida for Function Hooking\n\n**Intercept function calls without modifying binary.**\n\n⚠️ **Architecture Constraint:** Frida requires native-arch execution. It **cannot** attach to QEMU-user targets.\n\n| Scenario | Works? | Alternative |\n|----------|--------|-------------|\n| Native binary (x86_64 on x86_64) | ✅ | - |\n| Cross-arch under QEMU-user | ❌ | Use on-device frida-server |\n| Docker native-arch container | ✅ | - |\n| Docker cross-arch (emulated) | ❌ | Use on-device frida-server |\n\nFor cross-arch Frida, deploy `frida-server` to the target device:\n```bash\n# On target device:\n.\u002Ffrida-server &\n\n# On host:\nfrida -H device:27042 -f .\u002Fbinary -l hook.js --no-pause\n```\n\n### Basic Hook\n\n```javascript\n\u002F\u002F hook_connect.js\nInterceptor.attach(Module.findExportByName(null, \"connect\"), {\n  onEnter: function(args) {\n    console.log(\"[connect] Called\");\n    var sockaddr = args[1];\n    var family = sockaddr.readU16();\n    if (family == 2) { \u002F\u002F AF_INET\n      var port = sockaddr.add(2).readU16();\n      var ip = sockaddr.add(4).readByteArray(4);\n      console.log(\"  Port: \" + ((port >> 8) | ((port & 0xff) \u003C\u003C 8)));\n      console.log(\"  IP: \" + new Uint8Array(ip).join(\".\"));\n    }\n  },\n  onLeave: function(retval) {\n    console.log(\"  Return: \" + retval);\n  }\n});\n```\n\n```bash\n# Run with Frida\nfrida -f .\u002Fbinary -l hook_connect.js --no-pause\n```\n\n### Tracing All Calls to Library\n\n```javascript\n\u002F\u002F trace_libcurl.js\nvar libcurl = Process.findModuleByName(\"libcurl.so.4\");\nif (libcurl) {\n  libcurl.enumerateExports().forEach(function(exp) {\n    if (exp.type === \"function\") {\n      Interceptor.attach(exp.address, {\n        onEnter: function(args) {\n          console.log(\"[\" + exp.name + \"] called\");\n        }\n      });\n    }\n  });\n}\n```\n\n### Memory Inspection\n\n```javascript\n\u002F\u002F dump_memory.js\nvar base = Module.findBaseAddress(\"binary\");\nconsole.log(\"Base: \" + base);\n\n\u002F\u002F Dump region\nvar data = base.add(0x1000).readByteArray(256);\nconsole.log(hexdump(data, { offset: 0, length: 256 }));\n```\n\n## Option D: Docker-Based Cross-Architecture (macOS)\n\n**Use Docker for cross-arch execution when native QEMU unavailable.**\n\n### ARM32 Binary on macOS\n\n```bash\ndocker run --rm --platform linux\u002Farm\u002Fv7 \\\n  -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro \\\n  arm32v7\u002Fdebian:bullseye-slim \\\n  sh -c '\n    # Fix linker path mismatch (common issue)\n    ln -sf \u002Flib\u002Fld-linux-armhf.so.3 \u002Flib\u002Fld-linux.so.3 2>\u002Fdev\u002Fnull || true\n\n    # Install dependencies if needed (check rabin2 -l output)\n    apt-get update -qq && apt-get install -qq -y libcap2 libacl1 2>\u002Fdev\u002Fnull\n\n    # Run with library debug output (strace alternative)\n    LD_DEBUG=libs \u002Fwork\u002Fbinary args\n  '\n```\n\n### ARM64 Binary on macOS\n\n```bash\ndocker run --rm --platform linux\u002Farm64 \\\n  -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro \\\n  arm64v8\u002Fdebian:bullseye-slim \\\n  sh -c 'LD_DEBUG=libs \u002Fwork\u002Fbinary args'\n```\n\n### x86 32-bit Binary on macOS\n\n```bash\ndocker run --rm --platform linux\u002Fi386 \\\n  -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro \\\n  i386\u002Fdebian:bullseye-slim \\\n  sh -c '\u002Fwork\u002Fbinary args'\n```\n\n### Tracing Limitations in Docker\u002FQEMU User-Mode\n\n| Method | Works? | Alternative |\n|--------|--------|-------------|\n| strace | ❌ (ptrace not implemented) | `LD_DEBUG=files,libs` |\n| ltrace | ❌ (same reason) | Direct observation or Frida |\n| gdb | ✓ (with QEMU `-g` flag) | N\u002FA |\n\n### LD_DEBUG Options (strace alternative)\n\n```bash\nLD_DEBUG=libs     # Library search and loading\nLD_DEBUG=files    # File operations during loading\nLD_DEBUG=symbols  # Symbol resolution\nLD_DEBUG=bindings # Symbol binding details\nLD_DEBUG=all      # Everything (verbose)\n```\n\n---\n\n## Option E: On-Device Analysis\n\n**When emulation fails or device-specific behavior needed.**\n\n### Remote GDB via gdbserver\n\n```bash\n# On target device (via SSH\u002FADB)\ngdbserver :1234 .\u002Fbinary\n\n# On host (with port forward)\nssh -L 1234:localhost:1234 user@device &\ngdb-multiarch -q \\\n  -ex \"target remote localhost:1234\" \\\n  .\u002Fbinary\n```\n\n### Remote strace (if available)\n\n```bash\n# On target device\nstrace -f -o \u002Ftmp\u002Ftrace.log .\u002Fbinary\n\n# Pull log\nscp user@device:\u002Ftmp\u002Ftrace.log .\n```\n\n## Sandbox Configuration\n\n### Minimal Sandbox (nsjail)\n\n```bash\nnsjail \\\n  --mode o \\\n  --chroot \u002Fsysroot \\\n  --user 65534 \\\n  --group 65534 \\\n  --disable_clone_newnet \\\n  --rlimit_as 512 \\\n  --time_limit 60 \\\n  -- \u002Fbinary\n```\n\n### QEMU with Resource Limits\n\n```bash\n# CPU time limit\ntimeout 60 qemu-arm -L \u002Fsysroot -strace .\u002Fbinary\n\n# Memory limit via cgroup (requires setup)\ncgexec -g memory:qemu_sandbox qemu-arm -L \u002Fsysroot .\u002Fbinary\n```\n\n## Anti-Analysis Detection\n\nBefore dynamic analysis, check for common anti-debugging\u002Fanti-analysis patterns:\n\n### Static Detection (Pre-Execution)\n\n```bash\n# Check for anti-debug strings\u002Fimports\nstrings -a binary | grep -Ei 'ptrace|anti|debugger|seccomp|LD_PRELOAD|\u002Fproc\u002Fself'\n\n# r2: Look for ptrace\u002Fprctl\u002Fseccomp imports\nr2 -q -c 'iij' binary | jq '.[].name' | grep -Ei 'ptrace|prctl|seccomp'\n\n# Common anti-analysis indicators:\n# - ptrace(PTRACE_TRACEME) - Prevent debugger attach\n# - prctl(PR_SET_DUMPABLE, 0) - Prevent core dumps\n# - seccomp - Syscall filtering\n# - \u002Fproc\u002Fself\u002Fstatus checks - Detect TracerPid\n```\n\n### Runtime Detection\n\n```bash\n# If native execution possible:\nstrace -f .\u002Fbinary 2>&1 | grep -E 'ptrace|prctl|seccomp|\u002Fproc\u002Fself'\n```\n\n### Mitigation Strategies\n\n| Pattern | Detection | Bypass |\n|---------|-----------|--------|\n| `ptrace(TRACEME)` | Returns EPERM if debugger attached | Patch call to NOP, use QEMU |\n| `\u002Fproc\u002Fself\u002Fstatus` check | Reads TracerPid field | Use QEMU (no \u002Fproc emulation) |\n| Timing checks | `gettimeofday`\u002F`rdtsc` loops | Single-step with GDB, patch checks |\n| Self-checksum | Reads own binary\u002Fmemory | Compute expected checksum, patch |\n\n**When anti-analysis detected:** Prefer QEMU-strace over GDB (fewer detection vectors), or patch checks in r2 before execution.\n\n---\n\n## Error Recovery\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| `Unsupported syscall` | QEMU limitation | Try Qiling or on-device |\n| `Invalid ELF image` | Wrong arch\u002Fsysroot | Verify `file` output |\n| `Segfault at 0x0` | Missing library | Check `ldd` equivalent |\n| `QEMU hangs` | Blocking on I\u002FO | Add timeout, check strace |\n| `Anti-debugging` | Detection code | Use Frida stalker mode |\n| `exec format error` in Docker | binfmt not registered | Run `tonistiigi\u002Fbinfmt --install arm` |\n| `ld-linux.so.3 not found` | Linker path mismatch | Create symlink in container |\n| `libXXX.so not found` | Missing dependency | `apt install` in container |\n| Empty mount in Docker | Colima \u002Ftmp issue | Use `~\u002F` path instead of `\u002Ftmp\u002F` |\n| `ptrace: Operation not permitted` | strace in QEMU | Use `LD_DEBUG` instead |\n\n## Output Format\n\nRecord observations as structured data:\n\n```json\n{\n  \"experiment\": {\n    \"id\": \"exp_001\",\n    \"method\": \"qemu_strace\",\n    \"command\": \"qemu-arm -L \u002Fusr\u002Farm-linux-gnueabihf -strace .\u002Fbinary\",\n    \"duration_secs\": 12,\n    \"exit_code\": 0\n  },\n  \"syscall_summary\": {\n    \"network\": {\n      \"socket\": 2,\n      \"connect\": 1,\n      \"send\": 5,\n      \"recv\": 3\n    },\n    \"file\": {\n      \"openat\": 4,\n      \"read\": 12,\n      \"close\": 4\n    }\n  },\n  \"network_connections\": [\n    {\n      \"family\": \"AF_INET\",\n      \"address\": \"192.168.1.100\",\n      \"port\": 8443,\n      \"protocol\": \"tcp\"\n    }\n  ],\n  \"files_accessed\": [\n    {\"path\": \"\u002Fetc\u002Fconfig.json\", \"mode\": \"read\"},\n    {\"path\": \"\u002Fvar\u002Flog\u002Fapp.log\", \"mode\": \"write\"}\n  ],\n  \"hypotheses_tested\": [\n    {\n      \"hypothesis_id\": \"hyp_001\",\n      \"result\": \"confirmed\",\n      \"evidence\": \"connect() to 192.168.1.100:8443 observed\"\n    }\n  ]\n}\n```\n\n## Knowledge Journaling\n\nAfter dynamic analysis, record findings for episodic memory:\n\n```\n[BINARY-RE:dynamic] {filename} (sha256: {hash})\n\nExecution method: {qemu-strace|qemu-gdb|frida|on-device}\nDECISION: Approved execution with {sandbox_config} (rationale: {why_safe})\n\nRuntime observations:\n  FACT: Binary reads {path} (source: strace openat)\n  FACT: Binary connects to {ip}:{port} (source: strace connect)\n  FACT: Binary writes to {path} (source: strace write)\n  FACT: Function {addr} receives args {values} at runtime (source: gdb)\n\nSyscall summary:\n  Network: {socket|connect|send|recv counts}\n  File: {open|read|write|close counts}\n  Process: {fork|exec|clone counts}\n\nHYPOTHESIS UPDATE: {confirmed or refined theory} (confidence: {new_value})\n  Confirmed by: {runtime observation}\n  Contradicted by: {if any}\n\nNew questions:\n  QUESTION: {runtime-discovered unknown}\n\nAnswered questions:\n  RESOLVED: {question} → {runtime evidence}\n```\n\n### Example Journal Entry\n\n```\n[BINARY-RE:dynamic] thermostat_daemon (sha256: a1b2c3d4...)\n\nExecution method: qemu-strace\nDECISION: Approved execution with network-blocked sandbox (rationale: static analysis shows outbound only, no server)\n\nRuntime observations:\n  FACT: Binary reads \u002Fetc\u002Fthermostat.conf at startup (source: strace openat)\n  FACT: Binary attempts connect to 93.184.216.34:443 (source: strace connect)\n  FACT: Binary writes to \u002Fvar\u002Flog\u002Fthermostat.log (source: strace openat O_WRONLY)\n  FACT: sleep(30) called between network attempts (source: strace nanosleep)\n\nSyscall summary:\n  Network: socket(2), connect(1-blocked), send(0), recv(0)\n  File: openat(4), read(12), write(8), close(4)\n  Process: none\n\nHYPOTHESIS UPDATE: Telemetry client confirmed - reads config, attempts HTTPS to thermco servers every 30s (confidence: 0.95)\n  Confirmed by: connect() to expected IP, sleep(30) timing, config file read\n  Contradicted by: none\n\nAnswered questions:\n  RESOLVED: \"Does it actually phone home?\" → Yes, connect() to 93.184.216.34:443 observed\n  RESOLVED: \"What files does it access?\" → \u002Fetc\u002Fthermostat.conf (read), \u002Fvar\u002Flog\u002Fthermostat.log (write)\n```\n\n## Next Steps\n\n→ `binary-re-synthesis` to compile findings into report\n→ Additional static analysis if new functions identified\n→ Repeat with different inputs if behavior varies\n","# Dynamic Analysis (Phase 4)\n\n## Purpose\n\nObserve actual runtime behavior. Verify hypotheses from static analysis. Capture data that's only visible during execution.\n\n## Human-in-the-Loop Requirement\n\n**CRITICAL: All execution requires human approval.**\n\nBefore running ANY binary:\n1. Confirm sandbox configuration is acceptable\n2. Verify network isolation if required\n3. Document what execution will attempt\n4. Get explicit approval\n\n## Platform Support Matrix\n\n| Host Platform | Target Arch | Method | Complexity |\n|---------------|-------------|--------|------------|\n| Linux x86_64 | ARM32\u002F64, MIPS | Native `qemu-user` | Low |\n| Linux x86_64 | x86-32 | Native or `linux32` | Low |\n| macOS (any) | ARM32\u002F64 | Docker + binfmt | Medium |\n| macOS (any) | x86-32 | Docker `--platform linux\u002Fi386` | Medium |\n| Windows | Any | WSL2 → Linux method | Medium |\n\n### macOS Docker Setup (One-Time)\n\n```bash\n# Start Docker runtime (Colima, Docker Desktop, etc.)\ncolima start\n\n# Register ARM emulation handlers (requires privileged mode)\ndocker run --rm --privileged --platform linux\u002Farm64 \\\n  tonistiigi\u002Fbinfmt --install arm\n```\n\n### Docker Mount Best Practices\n\n**CRITICAL:** On Colima, `\u002Ftmp` mounts often fail silently. Always use home directory paths:\n\n```bash\n# ✅ GOOD - use home directory\ndocker run -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro ...\n\n# ❌ BAD - \u002Ftmp mounts can fail on Colima\ndocker run -v \u002Ftmp\u002Fsamples:\u002Fwork:ro ...\n```\n\n---\n\n## Analysis Options\n\n| Method | Isolation | Granularity | Best For |\n|--------|-----------|-------------|----------|\n| QEMU -strace | High | Syscall level | Initial behavior mapping |\n| QEMU + GDB | High | Instruction level | Detailed debugging |\n| Docker | High | Process level | Cross-arch on macOS |\n| Frida | Medium | Function level | Hooking without recompilation |\n| On-device | Low | Full system | When emulation fails |\n\n## Option A: QEMU User-Mode with Syscall Trace\n\n**Safest approach - runs in isolation with syscall logging.**\n\n### Setup\n\n```bash\n# Verify sysroot exists\nls \u002Fusr\u002Farm-linux-gnueabihf\u002Flib\u002Flibc.so*\n\n# ARM 32-bit execution\nqemu-arm -L \u002Fusr\u002Farm-linux-gnueabihf -strace -- .\u002Fbinary\n\n# ARM 64-bit execution\nqemu-aarch64 -L \u002Fusr\u002Faarch64-linux-gnu -strace -- .\u002Fbinary\n```\n\n### Sysroot Selection\n\n| Binary ABI | Sysroot Path | QEMU Flag |\n|------------|--------------|-----------|\n| ARM glibc hard-float | `\u002Fusr\u002Farm-linux-gnueabihf` | `-L` |\n| ARM glibc soft-float | `\u002Fusr\u002Farm-linux-gnueabi` | `-L` |\n| ARM64 glibc | `\u002Fusr\u002Faarch64-linux-gnu` | `-L` |\n| ARM musl | Custom extraction needed | `-L` |\n\n### Environment Control\n\n```bash\n# Set environment variables\nqemu-arm -L \u002Fsysroot \\\n  -E HOME=\u002Ftmp \\\n  -E USER=nobody \\\n  -E LD_DEBUG=bindings \\\n  -- .\u002Fbinary\n\n# Unset dangerous variables\nqemu-arm -L \u002Fsysroot \\\n  -U LD_PRELOAD \\\n  -- .\u002Fbinary\n```\n\n### Syscall Analysis\n\nStrace output patterns to watch:\n\n```bash\n# Network activity\nopenat.*socket\nconnect(.*AF_INET\nsendto\\|send\\|write.*socket\nrecvfrom\\|recv\\|read.*socket\n\n# File access\nopenat.*O_RDONLY.*\"\u002Fetc\nopenat.*O_WRONLY\nstat\\|lstat.*\"\u002F\n\n# Process operations\nexecve\nfork\\|clone\n```\n\n## Option B: QEMU + GDB for Deep Debugging\n\n**Attach debugger for instruction-level control.**\n\n### Launch Binary Under GDB\n\n```bash\n# Start QEMU with GDB server\nqemu-arm -g 1234 -L \u002Fusr\u002Farm-linux-gnueabihf .\u002Fbinary &\n\n# Connect with gdb-multiarch\ngdb-multiarch -q \\\n  -ex \"set architecture arm\" \\\n  -ex \"target remote :1234\" \\\n  -ex \"source ~\u002F.gdbinit-gef.py\" \\\n  .\u002Fbinary\n```\n\n### GDB Commands for RE\n\n```gdb\n# Breakpoints\nbreak *0x8400              # Address\nbreak main                 # Symbol\nbreak *0x8400 if $r0 == 5  # Conditional\n\n# Execution control\ncontinue                   # Run until break\nstepi                      # Single instruction\nnexti                      # Step over calls\nfinish                     # Run until return\n\n# Inspection\ninfo registers             # All registers\nx\u002F20i $pc                  # Disassemble from PC\nx\u002F10wx $sp                 # Stack contents\nx\u002Fs 0x12345                # String at address\n\n# Memory\nfind 0x8000, 0x10000, \"pattern\"  # Search memory\ndump memory \u002Ftmp\u002Fmem.bin 0x8000 0x9000  # Extract region\n```\n\n### GEF Enhancements\n\nWith GEF loaded, additional commands:\n\n```gdb\ngef> vmmap                 # Memory layout\ngef> checksec              # Security features\ngef> context               # Full state display\ngef> hexdump qword $sp 10  # Better hex dump\ngef> pcustom               # Structure definitions\n```\n\n### Batch Debugging Script\n\n```bash\n# Create GDB script\ncat > analyze.gdb \u003C\u003C 'EOF'\nset architecture arm\ntarget remote :1234\nbreak main\ncontinue\ninfo registers\nx\u002F20i $pc\ncontinue\nquit\nEOF\n\n# Run batch\ngdb-multiarch -batch -x analyze.gdb .\u002Fbinary\n```\n\n## Option C: Frida for Function Hooking\n\n**Intercept function calls without modifying binary.**\n\n⚠️ **Architecture Constraint:** Frida requires native-arch execution. It **cannot** attach to QEMU-user targets.\n\n| Scenario | Works? | Alternative |\n|----------|--------|-------------|\n| Native binary (x86_64 on x86_64) | ✅ | - |\n| Cross-arch under QEMU-user | ❌ | Use on-device frida-server |\n| Docker native-arch container | ✅ | - |\n| Docker cross-arch (emulated) | ❌ | Use on-device frida-server |\n\nFor cross-arch Frida, deploy `frida-server` to the target device:\n```bash\n# On target device:\n.\u002Ffrida-server &\n\n# On host:\nfrida -H device:27042 -f .\u002Fbinary -l hook.js --no-pause\n```\n\n### Basic Hook\n\n```javascript\n\u002F\u002F hook_connect.js\nInterceptor.attach(Module.findExportByName(null, \"connect\"), {\n  onEnter: function(args) {\n    console.log(\"[connect] Called\");\n    var sockaddr = args[1];\n    var family = sockaddr.readU16();\n    if (family == 2) { \u002F\u002F AF_INET\n      var port = sockaddr.add(2).readU16();\n      var ip = sockaddr.add(4).readByteArray(4);\n      console.log(\"  Port: \" + ((port >> 8) | ((port & 0xff) \u003C\u003C 8)));\n      console.log(\"  IP: \" + new Uint8Array(ip).join(\".\"));\n    }\n  },\n  onLeave: function(retval) {\n    console.log(\"  Return: \" + retval);\n  }\n});\n```\n\n```bash\n# Run with Frida\nfrida -f .\u002Fbinary -l hook_connect.js --no-pause\n```\n\n### Tracing All Calls to Library\n\n```javascript\n\u002F\u002F trace_libcurl.js\nvar libcurl = Process.findModuleByName(\"libcurl.so.4\");\nif (libcurl) {\n  libcurl.enumerateExports().forEach(function(exp) {\n    if (exp.type === \"function\") {\n      Interceptor.attach(exp.address, {\n        onEnter: function(args) {\n          console.log(\"[\" + exp.name + \"] called\");\n        }\n      });\n    }\n  });\n}\n```\n\n### Memory Inspection\n\n```javascript\n\u002F\u002F dump_memory.js\nvar base = Module.findBaseAddress(\"binary\");\nconsole.log(\"Base: \" + base);\n\n\u002F\u002F Dump region\nvar data = base.add(0x1000).readByteArray(256);\nconsole.log(hexdump(data, { offset: 0, length: 256 }));\n```\n\n## Option D: Docker-Based Cross-Architecture (macOS)\n\n**Use Docker for cross-arch execution when native QEMU unavailable.**\n\n### ARM32 Binary on macOS\n\n```bash\ndocker run --rm --platform linux\u002Farm\u002Fv7 \\\n  -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro \\\n  arm32v7\u002Fdebian:bullseye-slim \\\n  sh -c '\n    # Fix linker path mismatch (common issue)\n    ln -sf \u002Flib\u002Fld-linux-armhf.so.3 \u002Flib\u002Fld-linux.so.3 2>\u002Fdev\u002Fnull || true\n\n    # Install dependencies if needed (check rabin2 -l output)\n    apt-get update -qq && apt-get install -qq -y libcap2 libacl1 2>\u002Fdev\u002Fnull\n\n    # Run with library debug output (strace alternative)\n    LD_DEBUG=libs \u002Fwork\u002Fbinary args\n  '\n```\n\n### ARM64 Binary on macOS\n\n```bash\ndocker run --rm --platform linux\u002Farm64 \\\n  -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro \\\n  arm64v8\u002Fdebian:bullseye-slim \\\n  sh -c 'LD_DEBUG=libs \u002Fwork\u002Fbinary args'\n```\n\n### x86 32-bit Binary on macOS\n\n```bash\ndocker run --rm --platform linux\u002Fi386 \\\n  -v ~\u002Fcode\u002Fsamples:\u002Fwork:ro \\\n  i386\u002Fdebian:bullseye-slim \\\n  sh -c '\u002Fwork\u002Fbinary args'\n```\n\n### Tracing Limitations in Docker\u002FQEMU User-Mode\n\n| Method | Works? | Alternative |\n|--------|--------|-------------|\n| strace | ❌ (ptrace not implemented) | `LD_DEBUG=files,libs` |\n| ltrace | ❌ (same reason) | Direct observation or Frida |\n| gdb | ✓ (with QEMU `-g` flag) | N\u002FA |\n\n### LD_DEBUG Options (strace alternative)\n\n```bash\nLD_DEBUG=libs     # Library search and loading\nLD_DEBUG=files    # File operations during loading\nLD_DEBUG=symbols  # Symbol resolution\nLD_DEBUG=bindings # Symbol binding details\nLD_DEBUG=all      # Everything (verbose)\n```\n\n---\n\n## Option E: On-Device Analysis\n\n**When emulation fails or device-specific behavior needed.**\n\n### Remote GDB via gdbserver\n\n```bash\n# On target device (via SSH\u002FADB)\ngdbserver :1234 .\u002Fbinary\n\n# On host (with port forward)\nssh -L 1234:localhost:1234 user@device &\ngdb-multiarch -q \\\n  -ex \"target remote localhost:1234\" \\\n  .\u002Fbinary\n```\n\n### Remote strace (if available)\n\n```bash\n# On target device\nstrace -f -o \u002Ftmp\u002Ftrace.log .\u002Fbinary\n\n# Pull log\nscp user@device:\u002Ftmp\u002Ftrace.log .\n```\n\n## Sandbox Configuration\n\n### Minimal Sandbox (nsjail)\n\n```bash\nnsjail \\\n  --mode o \\\n  --chroot \u002Fsysroot \\\n  --user 65534 \\\n  --group 65534 \\\n  --disable_clone_newnet \\\n  --rlimit_as 512 \\\n  --time_limit 60 \\\n  -- \u002Fbinary\n```\n\n### QEMU with Resource Limits\n\n```bash\n# CPU time limit\ntimeout 60 qemu-arm -L \u002Fsysroot -strace .\u002Fbinary\n\n# Memory limit via cgroup (requires setup)\ncgexec -g memory:qemu_sandbox qemu-arm -L \u002Fsysroot .\u002Fbinary\n```\n\n## Anti-Analysis Detection\n\nBefore dynamic analysis, check for common anti-debugging\u002Fanti-analysis patterns:\n\n### Static Detection (Pre-Execution)\n\n```bash\n# Check for anti-debug strings\u002Fimports\nstrings -a binary | grep -Ei 'ptrace|anti|debugger|seccomp|LD_PRELOAD|\u002Fproc\u002Fself'\n\n# r2: Look for ptrace\u002Fprctl\u002Fseccomp imports\nr2 -q -c 'iij' binary | jq '.[].name' | grep -Ei 'ptrace|prctl|seccomp'\n\n# Common anti-analysis indicators:\n# - ptrace(PTRACE_TRACEME) - Prevent debugger attach\n# - prctl(PR_SET_DUMPABLE, 0) - Prevent core dumps\n# - seccomp - Syscall filtering\n# - \u002Fproc\u002Fself\u002Fstatus checks - Detect TracerPid\n```\n\n### Runtime Detection\n\n```bash\n# If native execution possible:\nstrace -f .\u002Fbinary 2>&1 | grep -E 'ptrace|prctl|seccomp|\u002Fproc\u002Fself'\n```\n\n### Mitigation Strategies\n\n| Pattern | Detection | Bypass |\n|---------|-----------|--------|\n| `ptrace(TRACEME)` | Returns EPERM if debugger attached | Patch call to NOP, use QEMU |\n| `\u002Fproc\u002Fself\u002Fstatus` check | Reads TracerPid field | Use QEMU (no \u002Fproc emulation) |\n| Timing checks | `gettimeofday`\u002F`rdtsc` loops | Single-step with GDB, patch checks |\n| Self-checksum | Reads own binary\u002Fmemory | Compute expected checksum, patch |\n\n**When anti-analysis detected:** Prefer QEMU-strace over GDB (fewer detection vectors), or patch checks in r2 before execution.\n\n---\n\n## Error Recovery\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| `Unsupported syscall` | QEMU limitation | Try Qiling or on-device |\n| `Invalid ELF image` | Wrong arch\u002Fsysroot | Verify `file` output |\n| `Segfault at 0x0` | Missing library | Check `ldd` equivalent |\n| `QEMU hangs` | Blocking on I\u002FO | Add timeout, check strace |\n| `Anti-debugging` | Detection code | Use Frida stalker mode |\n| `exec format error` in Docker | binfmt not registered | Run `tonistiigi\u002Fbinfmt --install arm` |\n| `ld-linux.so.3 not found` | Linker path mismatch | Create symlink in container |\n| `libXXX.so not found` | Missing dependency | `apt install` in container |\n| Empty mount in Docker | Colima \u002Ftmp issue | Use `~\u002F` path instead of `\u002Ftmp\u002F` |\n| `ptrace: Operation not permitted` | strace in QEMU | Use `LD_DEBUG` instead |\n\n## Output Format\n\nRecord observations as structured data:\n\n```json\n{\n  \"experiment\": {\n    \"id\": \"exp_001\",\n    \"method\": \"qemu_strace\",\n    \"command\": \"qemu-arm -L \u002Fusr\u002Farm-linux-gnueabihf -strace .\u002Fbinary\",\n    \"duration_secs\": 12,\n    \"exit_code\": 0\n  },\n  \"syscall_summary\": {\n    \"network\": {\n      \"socket\": 2,\n      \"connect\": 1,\n      \"send\": 5,\n      \"recv\": 3\n    },\n    \"file\": {\n      \"openat\": 4,\n      \"read\": 12,\n      \"close\": 4\n    }\n  },\n  \"network_connections\": [\n    {\n      \"family\": \"AF_INET\",\n      \"address\": \"192.168.1.100\",\n      \"port\": 8443,\n      \"protocol\": \"tcp\"\n    }\n  ],\n  \"files_accessed\": [\n    {\"path\": \"\u002Fetc\u002Fconfig.json\", \"mode\": \"read\"},\n    {\"path\": \"\u002Fvar\u002Flog\u002Fapp.log\", \"mode\": \"write\"}\n  ],\n  \"hypotheses_tested\": [\n    {\n      \"hypothesis_id\": \"hyp_001\",\n      \"result\": \"confirmed\",\n      \"evidence\": \"connect() to 192.168.1.100:8443 observed\"\n    }\n  ]\n}\n```\n\n## Knowledge Journaling\n\nAfter dynamic analysis, record findings for episodic memory:\n\n```\n[BINARY-RE:dynamic] {filename} (sha256: {hash})\n\nExecution method: {qemu-strace|qemu-gdb|frida|on-device}\nDECISION: Approved execution with {sandbox_config} (rationale: {why_safe})\n\nRuntime observations:\n  FACT: Binary reads {path} (source: strace openat)\n  FACT: Binary connects to {ip}:{port} (source: strace connect)\n  FACT: Binary writes to {path} (source: strace write)\n  FACT: Function {addr} receives args {values} at runtime (source: gdb)\n\nSyscall summary:\n  Network: {socket|connect|send|recv counts}\n  File: {open|read|write|close counts}\n  Process: {fork|exec|clone counts}\n\nHYPOTHESIS UPDATE: {confirmed or refined theory} (confidence: {new_value})\n  Confirmed by: {runtime observation}\n  Contradicted by: {if any}\n\nNew questions:\n  QUESTION: {runtime-discovered unknown}\n\nAnswered questions:\n  RESOLVED: {question} → {runtime evidence}\n```\n\n### Example Journal Entry\n\n```\n[BINARY-RE:dynamic] thermostat_daemon (sha256: a1b2c3d4...)\n\nExecution method: qemu-strace\nDECISION: Approved execution with network-blocked sandbox (rationale: static analysis shows outbound only, no server)\n\nRuntime observations:\n  FACT: Binary reads \u002Fetc\u002Fthermostat.conf at startup (source: strace openat)\n  FACT: Binary attempts connect to 93.184.216.34:443 (source: strace connect)\n  FACT: Binary writes to \u002Fvar\u002Flog\u002Fthermostat.log (source: strace openat O_WRONLY)\n  FACT: sleep(30) called between network attempts (source: strace nanosleep)\n\nSyscall summary:\n  Network: socket(2), connect(1-blocked), send(0), recv(0)\n  File: openat(4), read(12), write(8), close(4)\n  Process: none\n\nHYPOTHESIS UPDATE: Telemetry client confirmed - reads config, attempts HTTPS to thermco servers every 30s (confidence: 0.95)\n  Confirmed by: connect() to expected IP, sleep(30) timing, config file read\n  Contradicted by: none\n\nAnswered questions:\n  RESOLVED: \"Does it actually phone home?\" → Yes, connect() to 93.184.216.34:443 observed\n  RESOLVED: \"What files does it access?\" → \u002Fetc\u002Fthermostat.conf (read), \u002Fvar\u002Flog\u002Fthermostat.log (write)\n```\n\n## Next Steps\n\n→ `binary-re-synthesis` to compile findings into report\n→ Additional static analysis if new functions identified\n→ Repeat with different inputs if behavior varies\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002F2389-research\u002Fbinary-re\u002Fdynamic-analysis",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":59,"prompt":69,"zipAvailable":70},[60,63,66],{"tool":61,"command":62},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill binary-re-dynamic-analysis",{"tool":64,"command":65},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill binary-re-dynamic-analysis",{"tool":67,"command":68},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill binary-re-dynamic-analysis","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002F2389-research\u002Fbinary-re\u002Fdynamic-analysis\u002FSKILL.md",true,[],[73,87,97,106,112,119],{"skillNo":74,"name":75,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":83,"publishedAt":44},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[84,85,86],"model","model hierarchy","model hierarchy skill",{"skillNo":88,"name":89,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":93,"publishedAt":44},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[92],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},[94,95,96],"MCP","zoom","zoom mcp",{"skillNo":98,"name":99,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":44},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[103,104,105,95],"sdk","zoom apps sdk","apps",{"skillNo":107,"name":108,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":44},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[108],{"skillNo":113,"name":114,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":118,"publishedAt":44},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[117],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},[114],{"skillNo":120,"name":121,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":44},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[121]]