NimGuard is a cross-platform binary analysis and patching toolkit written in Nim. It helps security researchers, reverse engineers, and vulnerability analysts inspect, modify, and instrument compiled ELF and PE binaries without source code access.
- Auditing third-party binaries: Scan a binary for dangerous function calls (strcpy, gets, sprintf, etc.) and apply rule-based patches to replace them, without touching source code.
- Triaging suspicious binaries: Inspect imports, parse headers, and disassemble the
.textsection before ever executing the file. - CTF and RE work: Patch stripped binaries quickly using JSON rule files, with optional emulator validation before writing anything to disk.
- Legacy binary maintenance: Apply reproducible, version-controlled patches to binaries where source code is lost or unavailable.
- Runtime monitoring of untrusted processes: Attach to a live process, set breakpoints on flagged imports, inject bytes, and trace syscalls, all without a debugger.
- Binary analysis: Parse ELF and PE headers in pure Nim. Detect architecture, sections, and dangerous function calls. No C libraries needed for this.
- Disassembly: Disassemble the full
.textsection via Capstone. Requires the Capstone C library. - Rule-based patching: Define patches in JSON and apply them statically. Keystone validates assembled patch bytes when available.
- Emulation testing: Run the
.textsection through Unicorn before committing a patch to disk. Catches crashes before they happen. - Live instrumentation (Linux): Attach via ptrace. Read and write process memory, inject breakpoints, trace syscalls.
- Live instrumentation (Windows): Attach via Win32 debug API. Same capabilities as Linux instrumentation.
- Graceful degradation: Builds and runs on Linux, Windows, and macOS. Flags that depend on optional C libraries report unavailability cleanly rather than crashing.
| Feature | Linux | Windows | macOS |
|---|---|---|---|
| Binary parsing (ELF/PE) | Yes | Yes | Yes |
| Disassembly (Capstone) | Yes | Yes | Yes |
| Assembly/patching (Keystone) | Yes | Yes | Yes |
| Emulation (Unicorn) | Yes | Yes | Yes |
| ptrace instrumentation | Yes | No | No |
| Win32 debug instrumentation | No | Yes | No |
On macOS, runtime instrumentation flags (--attach, --inject, --breakpoint, --trace) will report that the platform is not supported.
ARM target support: hookFunction and injectBreakpoint generate correct trampoline and breakpoint instructions for ARM32 and AArch64 target binaries when the target architecture is detected from the binary. Live testing of ARM instrumentation requires an ARM process (native hardware or QEMU user-mode emulation). Byte-sequence correctness is verified by unit tests that run on any host.
Use choosenim:
curl https://nim-lang.org/choosenim/init.sh -sSf | shVerify:
nim --versionThe C libraries are optional. NimGuard will still build and run without them; affected flags will report that the library is unavailable.
Capstone (required for --disasm and dangerous-call detection in --analyze):
# Debian/Ubuntu
sudo apt-get install libcapstone-dev
# macOS
brew install capstone
# Windows
# Download capstone.dll from https://www.capstone-engine.org/ and place it
# next to the nimguard executable.Keystone (required for patch assembly validation):
# Debian/Ubuntu
sudo apt-get install libkeystone-dev # or build from source
# macOS
brew install keystone
# Windows
# Download keystone.dll from https://www.keystone-engine.org/Unicorn (required for --emulate and --test-patch):
# Debian/Ubuntu
sudo apt-get install libunicorn-dev
# macOS
brew install unicorn
# Windows
# Download unicorn.dll from https://www.unicorn-engine.org/git clone https://github.com/will-bates11/nimguard.git
cd nimguard
nimble buildThe binary is placed at ./nimguard (Linux/macOS) or .\nimguard.exe (Windows).
nimble testReport format, architecture, sections, and dangerous function calls:
./nimguard target_binary --analyze./nimguard target_binary --disasmApply default rules:
./nimguard target_binary --patchApply custom rules from a JSON file:
./nimguard target_binary --patch --rules custom_rules.jsonWrite the patched binary to a specific output path:
./nimguard target_binary --patch --output patched_binaryRun the .text section through Unicorn (up to 256 instructions):
./nimguard target_binary --emulateApply a NOP patch at offset 0 in the emulator before writing it to disk:
./nimguard target_binary --test-patchRegister pre-execution hooks for functions flagged in analysis:
./nimguard target_binary --monitorAttach to a running process (Linux and Windows only):
Note (Linux): On most Linux distributions, ptrace is restricted by default. To attach to arbitrary processes, you may need to run:
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scopeor run NimGuard with
sudo. The restriction is enforced by the Yama security module (/proc/sys/kernel/yama/ptrace_scope). A value of0allows any process to be traced; a value of1(the common default) restricts ptrace to parent/child relationships.
./nimguard --attach <pid>Set a software breakpoint at a hex address:
./nimguard --attach <pid> --breakpoint 0x401000Write bytes into process memory:
./nimguard --attach <pid> --inject 0x401000:9090Trace syscalls:
./nimguard --attach <pid> --tracePatch rules are JSON:
{
"rules": [
{
"identifier": "disable_gets",
"description": "Replace unsafe gets() with an immediate return, preventing unbounded input reads",
"condition": "if gets is detected in the import table",
"patch": "xor eax, eax; ret"
}
]
}See docs/architecture.md for a full breakdown of the module structure.
nimble build # release build -> ./nimguard
nimble test # run all testsMIT. See LICENSE.
See CONTRIBUTING.md.