BinGoggles is a powerful static taint analysis framework for Binary Ninja. It tracks variable flow both within and across functions, supporting full inter/intraprocedural slicing, including globals, structs, and function parameters.
With 100+ modeled libc functions and support for custom function models, BinGoggles provides deep, accurate taint propagation for security research and vulnerability discovery.
Want to write your own analysis? Start with bingoggles/modules.py — it shows how UAF (Use-After-Free) detection was built using the core engine.
A complete slice traces a tainted variable's full journey through function calls, across boundaries, and deep into control/data paths. It's end-to-end propagation, made simple.
- Platform agnostic – Runs on Linux, macOS, and Windows
- Intraprocedural and interprocedural analysis – Track variable flow within and across functions
- 100+ modeled functions – Extensive libc/system call models with automatic taint propagation
- Imported function analysis – User defines any external libraries for deeper analysis
- Architecture/language agnostic (mostly) – Works with any binary that loads into Binary Ninja
- Supports all variable types – Local variables, struct members, globals, and function parameters
- Easy-to-use API – Designed for extensibility with plenty of usage examples
- Bidirectional taint analysis – Supports both forward and backward slicing
- Embedded-friendly – Well-suited for firmware and embedded target analysis
- Headless compatible – Supports both Hugsy's and Binary Ninja's headless modes
- Variadic function call resolution & patching – Automatically identifies, resolves, and patches function calls with variable-length arguments
- Vulnerability detection modules – Built-in Use-After-Free detection with extensible module framework
- Binary Ninja (Commercial or Personal license)
- Python 3.8+
- Binary Ninja Python API installed
python3 -m venv .bg
source .bg/bin/activate # On Windows: .bg\Scripts\activate# Install BinGoggles requirements
pip install -r requirements.txt
# Install Binary Ninja API in the virtual environment
# (Adjust path to your Binary Ninja installation)
/path/to/binaryninja/scripts/linux-setup.sh # Linux
# OR for macOS/Windows, follow Binary Ninja's API setup instructions
# Install BinGoggles in development mode
pip install -e .# Run a quick test to verify everything works
python3 -m pytest test/test_cases.py::test_fwd_slice_param -vfrom bingoggles.bingoggles_types import *
from bingoggles.bg import Analysis
# Initialize BinGoggles with a binary
test_bin_path = "/path/to/your/binary"
bg_init = BGInit(target_bin=test_bin_path)
bv, libraries_mapped = bg_init.init()
# Create analysis object
analysis = Analysis(
binaryview=bv,
verbose=True,
libraries_mapped=libraries_mapped
)
# Perform forward slice from a variable
tainted_locs, func_name, tainted_vars = analysis.tainted_slice(
target=TaintTarget(0x00401A6F, "buffer"),
var_type=SlicingID.FunctionVar,
slice_type=SliceType.Forward,
output=OutputMode.Returned
)
print(f"Found {len(tainted_locs)} tainted locations in {func_name}")# Trace a variable across multiple functions
slice_data = analysis.complete_slice(
target=TaintTarget(0x00401AA6, "rax"),
var_type=SlicingID.FunctionVar,
slice_type=SliceType.Forward
)
# slice_data is a dict: {(function_name, var): ([TaintedLOC], [TaintedVar])}
for (func, var), (locs, vars) in slice_data.items():
print(f"{func} -> {var}: {len(locs)} locations")# Trace backwards from a sink to find sources
sources, func_name, tainted_vars = analysis.tainted_slice(
target=TaintTarget(0x004018DC, "rdx_1"),
var_type=SlicingID.FunctionVar,
slice_type=SliceType.Backward,
output=OutputMode.Returned
)# Track specific struct member propagation
struct_locs, func_name, tainted_vars = analysis.tainted_slice(
target=TaintTarget(0x00401A6F, "ptr"),
var_type=SlicingID.StructMember,
slice_type=SliceType.Forward
)from bingoggles.modules import UseAfterFreeDetection
# Run complete slice on an allocation
slice_data = analysis.complete_slice(
target=TaintTarget(0x00401AA6, "buffer"),
var_type=SlicingID.FunctionVar,
slice_type=SliceType.Forward
)
# Detect UAF vulnerabilities
uaf_scanner = UseAfterFreeDetection(bv, slice_data)
vulnerabilities = uaf_scanner.analyzer()
for vuln in vulnerabilities:
print(f"UAF detected: {len(vuln.vulnerable_path_data)} locations")
for loc in vuln.vulnerable_path_data:
print(f" {hex(loc.addr)}: {loc.loc}")Using BinGoggles with Hugsy Headless
For RPyC-based headless mode (requires Hugsy setup):
from bingoggles.bingoggles_types import *
from bingoggles.bg import Analysis
# Use RPyC initialization
bg_init = BGInitRpyc(
target_bin="/path/to/binary",
host="127.0.0.1",
port=18812
)
bv, libraries_mapped = bg_init.init()
analysis = Analysis(binaryview=bv, verbose=True, libraries_mapped=libraries_mapped)
# ... rest of analysis code# Run all tests
python3 -m pytest test/test_cases.py -v
# Run specific test
python3 -m pytest test/test_cases.py::test_global_tracking_fwd_var -v
# Run with RPyC/Hugsy headless mode
python3 -m pytest test/test_cases.py::test_fwd_slice_param -v --rpyc
# Run with verbose output
python3 -m pytest test/test_cases.py -svBinGoggles uses Sphinx to generate comprehensive API documentation from docstrings.
# Install Sphinx dependencies (if not already installed)
pip install -r requirements-sphinx.txt# Navigate to docs directory
cd docs
# Generate HTML documentation
make html
# Open in browser (Linux)
xdg-open build/html/index.html
# Or for macOS
open build/html/index.html
# Or for Windows
start build/html/index.htmlcd docs
make clean # Remove old build files
make html # Generate fresh documentationcd docs
make latexpdf # Requires LaTeX installationThe generated documentation includes:
- Full API reference for all modules
- Class and function signatures
- Detailed parameter descriptions
- Usage examples from docstrings
- Module interdependencies
For the latest documentation, visit the BinGoggles Documentation (if hosted).
BinGoggles includes 100+ pre-built function models for common libc and system functions:
- Memory functions:
malloc,free,memcpy,memmove,realloc - String functions:
strcpy,strcat,strlen,strcmp,strdup - I/O functions:
fgets,fread,scanf,printf,read,write - File operations:
fopen,fclose,open,openat - Environment:
getenv,setenv,getcwd,realpath
Each model defines:
- Taint sources: Which parameters introduce taint
- Taint destinations: Which parameters receive taint
- Return value tainting: Whether the return value is tainted
- Variadic support: Handling for
printf/scanffamily functions
Extend BinGoggles with your own function models:
from bingoggles.bingoggles_types import FunctionModel
# Define a custom function model
custom_model = FunctionModel(
name="my_custom_copy",
taint_sources=[1], # param index 1 is the source
taint_destinations=[0], # param index 0 receives taint
taints_return=False # return value not tainted
)- Forward slicing: Trace from source to all possible sinks
- Backward slicing: Trace from sink back to all possible sources
- Complete slicing: Full interprocedural analysis across function boundaries
- FunctionVar: Local variables within a function
- FunctionParam: Function parameters (formal arguments)
- GlobalVar: Global variables and constants
- StructMember: Individual fields within struct types
Binary Ninja API not found:
# Make sure Binary Ninja's Python API is in your PYTHONPATH
export PYTHONPATH="/path/to/binaryninja/python:$PYTHONPATH"Tests failing:
# Ensure .bndb files are generated for test binaries
# BinGoggles will auto-create them on first run, but this takes timeHeadless mode errors:
# Verify Binary Ninja license supports headless operation
# Commercial licenses required for full headless functionalityWe welcome contributions from the community! Here's how you can help:
If you encounter a bug or have a feature request:
- Check existing issues to avoid duplicates
- Open a new issue with detailed reproduction steps
- Include Binary Ninja version, Python version, and OS
- Attach relevant code snippets or binaries (if possible)
Want to improve the code or documentation?
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-improvement) - Make your changes with clear commit messages
- Add tests for new functionality
- Update documentation as needed
- Submit a pull request with a detailed description
- Follow PEP 8 style guidelines
- Add docstrings to all public functions/classes
- Include type hints where appropriate
- Write meaningful commit messages (use conventional commits)
# Run the full test suite before submitting PRs
python3 -m pytest test/test_cases.py -v
# Ensure all tests pass- Star the repository
- Write blog posts or tutorials using BinGoggles!
- Share on social media (Twitter/X, LinkedIn, etc.)
- Join discussions in issues and pull requests
- Present at conferences or meetups
BinGoggles is released under the Apache License. See LICENSE for details.
- Built on top of Binary Ninja
- Supports Hugsy's headless mode
- Inspired by classic taint analysis research
If you use BinGoggles in your research, please cite:
@software{bingoggles,
title = {BinGoggles: A Variable Flow Engine for Binary Ninja},
author = {Pwnpope},
url = {https://github.com/pwnpope/BinGoggles}
}Thank you for helping make BinGoggles better!
