本文へ移動
cccskills
無料GitHub で公開

binary-re:dynamic-analysis

Observes runtime behavior of binaries via QEMU emulation, GDB debugging, and Frida hooking — syscall tracing, breakpoints, memory inspection, and function interception. Use when running, tracing, or debugging a binary, verifying hypotheses from static analysis, or watching actual syscalls, network calls, or file access; requires human approval before any execution.

インストール方法を見る

含まれるファイル(4)

  • SKILL.md11.2 KB
  • references/docker-setup.md1.5 KB
  • references/frida-setup.md2.0 KB
  • references/on-device-setup.md471 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Dynamic Analysis (Phase 4)

Purpose

Observe actual runtime behavior. Verify hypotheses from static analysis. Capture data that's only visible during execution.

Human-in-the-Loop Requirement

CRITICAL: All execution requires human approval.

Before running ANY binary:

  1. Confirm sandbox configuration is acceptable
  2. Verify network isolation if required
  3. Document what execution will attempt
  4. Get explicit approval

Platform Support Matrix

Host PlatformTarget ArchMethodComplexity
Linux x86_64ARM32/64, MIPSNative qemu-userLow
Linux x86_64x86-32Native or linux32Low
macOS (any)ARM32/64Docker + binfmtMedium
macOS (any)x86-32Docker --platform linux/i386Medium
WindowsAnyWSL2 → Linux methodMedium

macOS Docker Setup (One-Time)

# Start Docker runtime (Colima, Docker Desktop, etc.)
colima start

# Register ARM emulation handlers (requires privileged mode)
docker run --rm --privileged --platform linux/arm64 \
  tonistiigi/binfmt --install arm

Docker Mount Best Practices

CRITICAL: On Colima, /tmp mounts often fail silently. Always use home directory paths:

# ✅ GOOD - use home directory
docker run -v ~/code/samples:/work:ro ...

# ❌ BAD - /tmp mounts can fail on Colima
docker run -v /tmp/samples:/work:ro ...

Analysis Options

MethodIsolationGranularityBest For
QEMU -straceHighSyscall levelInitial behavior mapping
QEMU + GDBHighInstruction levelDetailed debugging
DockerHighProcess levelCross-arch on macOS
FridaMediumFunction levelHooking without recompilation
On-deviceLowFull systemWhen emulation fails

Option A: QEMU User-Mode with Syscall Trace

Safest approach - runs in isolation with syscall logging.

Setup

# Verify sysroot exists
ls /usr/arm-linux-gnueabihf/lib/libc.so*

# ARM 32-bit execution
qemu-arm -L /usr/arm-linux-gnueabihf -strace -- ./binary

# ARM 64-bit execution
qemu-aarch64 -L /usr/aarch64-linux-gnu -strace -- ./binary

Sysroot Selection

Binary ABISysroot PathQEMU Flag
ARM glibc hard-float/usr/arm-linux-gnueabihf-L
ARM glibc soft-float/usr/arm-linux-gnueabi-L
ARM64 glibc/usr/aarch64-linux-gnu-L
ARM muslCustom extraction needed-L

Environment Control

# Set environment variables
qemu-arm -L /sysroot \
  -E HOME=/tmp \
  -E USER=nobody \
  -E LD_DEBUG=bindings \
  -- ./binary

# Unset dangerous variables
qemu-arm -L /sysroot \
  -U LD_PRELOAD \
  -- ./binary

Syscall Analysis

Strace output patterns to watch:

# Network activity
openat.*socket
connect(.*AF_INET
sendto\|send\|write.*socket
recvfrom\|recv\|read.*socket

# File access
openat.*O_RDONLY.*"/etc
openat.*O_WRONLY
stat\|lstat.*"/

# Process operations
execve
fork\|clone

Option B: QEMU + GDB for Deep Debugging

Attach debugger for instruction-level control.

Launch Binary Under GDB

# Start QEMU with GDB server
qemu-arm -g 1234 -L /usr/arm-linux-gnueabihf ./binary &

# Connect with gdb-multiarch
gdb-multiarch -q \
  -ex "set architecture arm" \
  -ex "target remote :1234" \
  -ex "source ~/.gdbinit-gef.py" \
  ./binary

GDB Commands for RE

# Breakpoints
break *0x8400              # Address
break main                 # Symbol
break *0x8400 if $r0 == 5  # Conditional

# Execution control
continue                   # Run until break
stepi                      # Single instruction
nexti                      # Step over calls
finish                     # Run until return

# Inspection
info registers             # All registers
x/20i $pc                  # Disassemble from PC
x/10wx $sp                 # Stack contents
x/s 0x12345                # String at address

# Memory
find 0x8000, 0x10000, "pattern"  # Search memory
dump memory /tmp/mem.bin 0x8000 0x9000  # Extract region

GEF Enhancements

With GEF loaded, additional commands:

gef> vmmap                 # Memory layout
gef> checksec              # Security features
gef> context               # Full state display
gef> hexdump qword $sp 10  # Better hex dump
gef> pcustom               # Structure definitions

Batch Debugging Script

# Create GDB script
cat > analyze.gdb << 'EOF'
set architecture arm
target remote :1234
break main
continue
info registers
x/20i $pc
continue
quit
EOF

# Run batch
gdb-multiarch -batch -x analyze.gdb ./binary

Option C: Frida for Function Hooking

For Frida setup, architecture constraints, hook examples, and platform-specific instrumentation guides, read references/frida-setup.md.

Option D: Docker-Based Cross-Architecture (macOS)

For Docker-based cross-architecture analysis on macOS including ARM32, ARM64, and x86-32 examples, read references/docker-setup.md.


Option E: On-Device Analysis

For on-device analysis via gdbserver and remote strace when emulation fails, read references/on-device-setup.md.

Sandbox Configuration

Minimal Sandbox (nsjail)

nsjail \
  --mode o \
  --chroot /sysroot \
  --user 65534 \
  --group 65534 \
  --disable_clone_newnet \
  --rlimit_as 512 \
  --time_limit 60 \
  -- /binary

QEMU with Resource Limits

# CPU time limit
timeout 60 qemu-arm -L /sysroot -strace ./binary

# Memory limit via cgroup (requires setup)
cgexec -g memory:qemu_sandbox qemu-arm -L /sysroot ./binary

Anti-Analysis Detection

Before dynamic analysis, check for common anti-debugging/anti-analysis patterns:

Static Detection (Pre-Execution)

# Check for anti-debug strings/imports
strings -a binary | grep -Ei 'ptrace|anti|debugger|seccomp|LD_PRELOAD|/proc/self'

# r2: Look for ptrace/prctl/seccomp imports
r2 -q -c 'iij' binary | jq '.[].name' | grep -Ei 'ptrace|prctl|seccomp'

# Common anti-analysis indicators:
# - ptrace(PTRACE_TRACEME) - Prevent debugger attach
# - prctl(PR_SET_DUMPABLE, 0) - Prevent core dumps
# - seccomp - Syscall filtering
# - /proc/self/status checks - Detect TracerPid

Runtime Detection

# If native execution possible:
strace -f ./binary 2>&1 | grep -E 'ptrace|prctl|seccomp|/proc/self'

Mitigation Strategies

PatternDetectionBypass
ptrace(TRACEME)Returns EPERM if debugger attachedPatch call to NOP, use QEMU
/proc/self/status checkReads TracerPid fieldUse QEMU (no /proc emulation)
Timing checksgettimeofday/rdtsc loopsSingle-step with GDB, patch checks
Self-checksumReads own binary/memoryCompute expected checksum, patch

When anti-analysis detected: Prefer QEMU-strace over GDB (fewer detection vectors), or patch checks in r2 before execution.


Error Recovery

ErrorCauseSolution
Unsupported syscallQEMU limitationTry Qiling or on-device
Invalid ELF imageWrong arch/sysrootVerify file output
Segfault at 0x0Missing libraryCheck ldd equivalent
QEMU hangsBlocking on I/OAdd timeout, check strace
Anti-debuggingDetection codeUse Frida stalker mode
exec format error in Dockerbinfmt not registeredRun tonistiigi/binfmt --install arm
ld-linux.so.3 not foundLinker path mismatchCreate symlink in container
libXXX.so not foundMissing dependencyapt install in container
Empty mount in DockerColima /tmp issueUse ~/ path instead of /tmp/
ptrace: Operation not permittedstrace in QEMUUse LD_DEBUG instead

Output Format

Record observations as structured data:

{
  "experiment": {
    "id": "exp_001",
    "method": "qemu_strace",
    "command": "qemu-arm -L /usr/arm-linux-gnueabihf -strace ./binary",
    "duration_secs": 12,
    "exit_code": 0
  },
  "syscall_summary": {
    "network": {
      "socket": 2,
      "connect": 1,
      "send": 5,
      "recv": 3
    },
    "file": {
      "openat": 4,
      "read": 12,
      "close": 4
    }
  },
  "network_connections": [
    {
      "family": "AF_INET",
      "address": "192.168.1.100",
      "port": 8443,
      "protocol": "tcp"
    }
  ],
  "files_accessed": [
    {"path": "/etc/config.json", "mode": "read"},
    {"path": "/var/log/app.log", "mode": "write"}
  ],
  "hypotheses_tested": [
    {
      "hypothesis_id": "hyp_001",
      "result": "confirmed",
      "evidence": "connect() to 192.168.1.100:8443 observed"
    }
  ]
}

Knowledge Journaling

After dynamic analysis, record findings for episodic memory:

[BINARY-RE:dynamic] {filename} (sha256: {hash})

Execution method: {qemu-strace|qemu-gdb|frida|on-device}
DECISION: Approved execution with {sandbox_config} (rationale: {why_safe})

Runtime observations:
  FACT: Binary reads {path} (source: strace openat)
  FACT: Binary connects to {ip}:{port} (source: strace connect)
  FACT: Binary writes to {path} (source: strace write)
  FACT: Function {addr} receives args {values} at runtime (source: gdb)

Syscall summary:
  Network: {socket|connect|send|recv counts}
  File: {open|read|write|close counts}
  Process: {fork|exec|clone counts}

HYPOTHESIS UPDATE: {confirmed or refined theory} (confidence: {new_value})
  Confirmed by: {runtime observation}
  Contradicted by: {if any}

New questions:
  QUESTION: {runtime-discovered unknown}

Answered questions:
  RESOLVED: {question} → {runtime evidence}

Example Journal Entry

[BINARY-RE:dynamic] thermostat_daemon (sha256: a1b2c3d4...)

Execution method: qemu-strace
DECISION: Approved execution with network-blocked sandbox (rationale: static analysis shows outbound only, no server)

Runtime observations:
  FACT: Binary reads /etc/thermostat.conf at startup (source: strace openat)
  FACT: Binary attempts connect to 93.184.216.34:443 (source: strace connect)
  FACT: Binary writes to /var/log/thermostat.log (source: strace openat O_WRONLY)
  FACT: sleep(30) called between network attempts (source: strace nanosleep)

Syscall summary:
  Network: socket(2), connect(1-blocked), send(0), recv(0)
  File: openat(4), read(12), write(8), close(4)
  Process: none

HYPOTHESIS UPDATE: Telemetry client confirmed - reads config, attempts HTTPS to thermco servers every 30s (confidence: 0.95)
  Confirmed by: connect() to expected IP, sleep(30) timing, config file read
  Contradicted by: none

Answered questions:
  RESOLVED: "Does it actually phone home?" → Yes, connect() to 93.184.216.34:443 observed
  RESOLVED: "What files does it access?" → /etc/thermostat.conf (read), /var/log/thermostat.log (write)

Next Steps

→ binary-re:synthesis to compile findings into report → Additional static analysis if new functions identified → Repeat with different inputs if behavior varies

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

binary-re

無料

Analyzes ELF binaries, executables, and firmware images to understand behavior without source code; coordinates sub-skills binary-re:triage, binary-re:static-analysis, binary-re:dynamic-analysis, binary-re:synthesis, and binary-re:tool-setup. Use when working with a binary, executable, or ELF file; asked to reverse engineer, disassemble, decompile, or figure out what something does; targeting ARM64, ARMv7, x86_64, or MIPS; or analyzing Python bytecode (.pyc, marshal). For Python bytecode analysis, see docs/python-bytecode-re.md.

日本語の概要は準備中です。原文の説明を表示しています。

2389-research/binary-re202026年9月26日 更新

Performs static analysis of binary code using radare2 and Ghidra — function enumeration, cross-reference tracing, decompilation, and control flow graphs without executing the binary. Use when disassembling or decompiling code, mapping functions, tracing data flow, or building hypotheses before dynamic verification.

日本語の概要は準備中です。原文の説明を表示しています。

2389-research/binary-re202026年9月26日 更新

Compiles binary analysis findings into structured reports — correlates facts from triage, static, and dynamic phases, validates hypotheses against evidence, and produces traceable documentation. Use when ready to summarize findings, generate a report, document what a binary does, or prepare results for handoff or archival.

日本語の概要は準備中です。原文の説明を表示しています。

2389-research/binary-re202026年9月26日 更新

Installs and configures reverse engineering tools including radare2, Ghidra, GDB, QEMU, Frida, and cross-compilation toolchains for ARM64, ARMv7, x86_64, and MIPS. Use when a tool command fails, a required tool is missing, or you need to set up a fresh analysis environment.

日本語の概要は準備中です。原文の説明を表示しています。

2389-research/binary-re202026年9月26日 更新

Fingerprints unknown binaries using rabin2 — detects architecture (ARM, x86, MIPS), ABI, libc, dependencies, and strings of interest. Use when first encountering an unknown binary, ELF file, or firmware blob, or when you need architecture or ABI information before committing to deeper analysis.

日本語の概要は準備中です。原文の説明を表示しています。

2389-research/binary-re202026年9月26日 更新

2389-research のスキルをすべて見る

このスキルの問題を報告する