Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,27 @@ rule:
The [github.com/mandiant/capa-rules](https://github.com/mandiant/capa-rules) repository contains hundreds of standard rules that are distributed with capa.
Please learn to write rules and contribute new entries as you find interesting techniques in malware.

# IDA Pro plugin: capa explorer
# Disassembler plugins

## IDA Pro plugin: capa explorer
If you use IDA Pro, then you can use the [capa explorer](https://github.com/mandiant/capa/tree/master/capa/ida/plugin) plugin.
capa explorer helps you identify interesting areas of a program and build new capa rules using features extracted directly from your IDA Pro database.
It also uses your local changes to the .idb to extract better features, such as when you rename a global variable that contains a dynamically resolved API address.

![capa + IDA Pro integration](https://github.com/mandiant/capa/blob/master/doc/img/explorer_expanded.png)

## Binary Ninja plugin: capa explorer
If you use Binary Ninja, you can use the [capa explorer](https://github.com/mandiant/capa/tree/master/capa/binja/plugin) plugin.
capa explorer helps you identify interesting areas of a program using capa rule analysis directly within Binary Ninja.

The plugin provides:
- Interactive capa analysis within Binary Ninja
- Rule match exploration and navigation
- Background analysis processing
- Integration with Binary Ninja's UI

Check out [the plugin documentation](https://github.com/mandiant/capa/tree/master/capa/binja/plugin) for setup and usage instructions.

# Ghidra integration
If you use Ghidra, then you can use the [capa + Ghidra integration](/capa/ghidra/) to run capa's analysis directly on your Ghidra database and render the results in Ghidra's user interface.

Expand Down
13 changes: 13 additions & 0 deletions capa/binja/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
156 changes: 156 additions & 0 deletions capa/binja/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Binary Ninja helper utilities for capa explorer plugin
"""

import logging

try:
import binaryninja as binja
BINJA_AVAILABLE = True
except ImportError:
BINJA_AVAILABLE = False

logger = logging.getLogger(__name__)


def is_supported_file_type(bv=None):
"""Check if the current binary view is supported by capa"""
if not BINJA_AVAILABLE:
return False

if bv is None:
return False

# capa supports PE, ELF files primarily
supported_types = [
'PE',
'ELF',
'COFF',
'Raw' # For shellcode
]

view_type = bv.view_type
if view_type in supported_types:
return True

return False


def is_supported_arch_type(bv=None):
"""Check if the current architecture is supported by capa"""
if not BINJA_AVAILABLE:
return False

if bv is None:
return False

# capa primarily supports x86/x64
supported_archs = [
'x86',
'x86_64'
]

arch_name = bv.arch.name
if arch_name in supported_archs:
return True

return False


def get_binary_ninja_version():
"""Get Binary Ninja version string"""
if not BINJA_AVAILABLE:
return "Binary Ninja not available"

try:
core_version = binja.core_version()
return f"Binary Ninja {core_version}"
except:
return "Binary Ninja version unknown"


def is_supported_binja_version():
"""Check if Binary Ninja version is supported"""
if not BINJA_AVAILABLE:
return False

try:
# Basic check - if we can import binaryninja, it's probably new enough
# Binary Ninja plugin API has been fairly stable
return True
except:
return False


def get_function_name_at(bv, address):
"""Get function name at the given address"""
if not BINJA_AVAILABLE or not bv:
return None

functions = bv.get_functions_at(address)
if functions:
return functions[0].name
return None


def navigate_to_address(bv, address):
"""Navigate Binary Ninja to the given address"""
if not BINJA_AVAILABLE or not bv:
return False

try:
bv.navigate(bv.view, address)
return True
except:
return False


def get_current_address(bv):
"""Get the current address in Binary Ninja view"""
if not BINJA_AVAILABLE or not bv:
return None

try:
# This might vary depending on Binary Ninja version
# For now, return None as this requires UI context
return None
except:
return None


def log_info(message):
"""Log info message to Binary Ninja log"""
if BINJA_AVAILABLE:
binja.log_info(message)
else:
logger.info(message)


def log_error(message):
"""Log error message to Binary Ninja log"""
if BINJA_AVAILABLE:
binja.log_error(message)
else:
logger.error(message)


def log_warn(message):
"""Log warning message to Binary Ninja log"""
if BINJA_AVAILABLE:
binja.log_warn(message)
else:
logger.warning(message)
121 changes: 121 additions & 0 deletions capa/binja/plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
![capa explorer](../../../.github/capa-explorer-logo.png)

# capa explorer for Binary Ninja

capa explorer is a Binary Ninja plugin that integrates the FLARE team's open-source framework, capa, with Binary Ninja. capa is a framework that uses a well-defined collection of rules to identify capabilities in a program. You can run capa against a PE file, ELF file, or shellcode and it tells you what it thinks the program can do. For example, it might suggest that the program is a backdoor, can install services, or relies on HTTP to communicate.

capa explorer runs capa analysis on your Binary Ninja database without needing access to the original binary file. Once a database has been analyzed, capa explorer helps you identify interesting areas of a program by showing you which rules matched and where.

## Features

- **Program Analysis**: Run capa analysis directly within Binary Ninja
- **Interactive Results**: Click on results to navigate to relevant addresses in the disassembly
- **Rule Matching**: See which capa rules matched and why
- **Background Processing**: Analysis runs in background thread without blocking Binary Ninja

## Getting Started

### Installation

You can install capa explorer using the following steps:

1. Install capa and its dependencies using pip:
```
$ pip install flare-capa
```

2. Download and extract the [official capa rules](https://github.com/mandiant/capa-rules/releases) that match the version of capa you have installed
- Use the following command to view the version of capa you have installed:
```commandline
$ pip show flare-capa
OR
$ capa --version
```

3. Copy [capa_explorer.py](https://raw.githubusercontent.com/mandiant/capa/master/capa/binja/plugin/capa_explorer.py) to your Binary Ninja plugins directory
- Find your plugin directory via Binary Ninja's preferences or typically located at:
- Windows: `%APPDATA%\Binary Ninja\plugins`
- macOS: `~/Library/Application Support/Binary Ninja/plugins`
- Linux: `~/.binaryninja/plugins`

### Supported File Types

capa explorer is limited to the file types supported by capa, which include:

* Windows x86 (32- and 64-bit) PE files
* Windows x86 (32- and 64-bit) shellcode
* ELF files on various operating systems

### Usage

1. Open Binary Ninja and load a supported file type
2. Open capa explorer by navigating to `Tools > FLARE capa explorer`
3. Select the `Program Analysis` tab
4. Click the `Settings` button to specify your capa rules directory (first time only)
5. Click the `Analyze` button to run capa analysis

The first time you run capa explorer you will be asked to specify a local directory containing capa rules to use for analysis. We recommend downloading and extracting the [official capa rules](https://github.com/mandiant/capa-rules/releases) that match the version of capa you have installed.

#### Tips for Program Analysis

* Start analysis by clicking the `Analyze` button
* The plugin remembers your capa rules directory selection between sessions
* Reset the plugin by clicking the `Reset` button
* Change your local capa rules directory by clicking the `Settings` button
* Double-click on a result to navigate to the associated address in Binary Ninja
* Analysis runs in a background thread so you can continue using Binary Ninja

### Requirements

capa explorer supports Binary Ninja with Python 3.10+ and has been tested with recent versions of Binary Ninja. The plugin requires:

* Binary Ninja (recent versions with Python plugin support)
* Python 3.10 or later
* PySide2 or PySide6 (usually included with Binary Ninja)
* flare-capa package

If you encounter issues with your specific setup, please open a new [Issue](https://github.com/mandiant/capa/issues).

## Development

capa explorer is packaged with capa so you will need to install capa locally for development. You can install capa locally by following the steps outlined in `Method 3: Inspecting the capa source code` of the [capa installation guide](https://github.com/mandiant/capa/blob/master/doc/installation.md#method-3-inspecting-the-capa-source-code).

Once installed, copy [capa_explorer.py](https://raw.githubusercontent.com/mandiant/capa/master/capa/binja/plugin/capa_explorer.py) to your plugins directory to install capa explorer in Binary Ninja.

### Components

capa explorer consists of two main components:

* A [feature extractor](https://github.com/mandiant/capa/tree/master/capa/features/extractors/binja) built on top of Binary Ninja's analysis engine
* This component uses Binary Ninja's Python API to extract [capa features](https://github.com/mandiant/capa-rules/blob/master/doc/format.md#extracted-features) from your binaries such as strings, disassembly, and control flow; these extracted features are used by capa to find feature combinations that result in a rule match
* An [interactive user interface](https://github.com/mandiant/capa/tree/master/capa/binja/plugin) for displaying and exploring capa rule matches
* This component integrates the feature extractor and capa, providing an interactive user interface to explore rule matches found by capa using features extracted directly from your Binary Ninja analysis

## Differences from IDA Plugin

This Binary Ninja plugin focuses on the core exploration functionality:

* **Program Analysis**: Full capa analysis with rule matching and result exploration
* **Navigation**: Click results to jump to relevant addresses
* **Background Processing**: Non-blocking analysis

Currently **not implemented** (but may be added in future versions):
* Rule generation functionality
* Advanced rule editing capabilities
* Some advanced UI features from the IDA version

## Troubleshooting

**Plugin doesn't appear in Tools menu:**
- Verify Binary Ninja can import the `binaryninja` module in its Python environment
- Check that all dependencies (especially `flare-capa`) are installed in Binary Ninja's Python environment
- Look for error messages in Binary Ninja's log window

**Analysis fails:**
- Ensure you have a valid capa rules directory selected
- Verify the binary type is supported by capa
- Check Binary Ninja's log for detailed error messages

**UI issues:**
- Ensure your Binary Ninja version includes PySide2 or PySide6
- Try restarting Binary Ninja after installing the plugin
71 changes: 71 additions & 0 deletions capa/binja/plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging

logger = logging.getLogger(__name__)

try:
import binaryninja as binja
from capa.binja.plugin.form import CapaExplorerForm
from capa.binja.plugin.icon import ICON
from capa.binja import helpers

class CapaExplorerPlugin:
"""Main capa explorer plugin class"""

def __init__(self):
"""initialize plugin"""
self.form = None

def is_valid(self, view):
"""Check if the plugin can run on this binary view"""
if not isinstance(view, binja.BinaryView):
return False

# Check basic file type and architecture support
return (helpers.is_supported_file_type(view) and
helpers.is_supported_arch_type(view))

def run(self, view):
"""Run the capa explorer plugin"""
try:
if not self.form or self.form.bv != view:
self.form = CapaExplorerForm(view)

self.form.show()

except Exception as e:
logger.error(f"Error running capa explorer: {e}")
if hasattr(binja, 'show_message_box'):
binja.show_message_box("Capa Explorer Error",
f"Failed to run capa explorer: {str(e)}")

# Create plugin instance
plugin_instance = CapaExplorerPlugin()

# Register the plugin command
binja.PluginCommand.register(
"FLARE capa explorer",
"Identify capabilities in executable files using FLARE capa",
plugin_instance.run,
plugin_instance.is_valid
)

logger.info("FLARE capa explorer plugin registered successfully")

except ImportError as e:
# Binary Ninja not available, plugin will not be registered
logger.debug(f"Binary Ninja not available for capa plugin: {e}")
pass
Loading