Skip to content

Commit dab7de5

Browse files
committed
Initial documentation for guided analysis feature. (skip-ci)
1 parent 750e6f6 commit dab7de5

File tree

5 files changed

+112
-4
lines changed

5 files changed

+112
-4
lines changed

docs/dev/guided_analysis.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Guided Analysis
2+
3+
## Overview
4+
5+
Guided Analysis provides granular control over which basic blocks are included or excluded from analysis. It is especially useful for analyzing obfuscated code, troubleshooting analysis issues, or focusing on specific execution paths while excluding irrelevant code.
6+
7+
## Modes of Operation
8+
9+
Guided Analysis operates in two primary modes:
10+
11+
**Automatic Mode**: Binary Ninja automatically enters guided analysis when encountering problems like invalid instructions. When this happens, direct branch targets are not followed and IL is generated only for the current set of blocks. If new information becomes available that resolves the original trigger condition, the function will reanalyze and may exit guided mode automatically.
12+
13+
**Manual Mode**: Manually enable guided analysis to precisely control analyzed blocks. Analysis begins with only the entry block, requiring explicit manual addition of further blocks.
14+
15+
## Enabling Guided Analysis
16+
17+
### Settings
18+
![Guided Analysis Settings](../img/guided-analysis-settings.png)
19+
20+
- **`analysis.guided.enable`**: Manually start function analysis in guided mode (default: false)
21+
- **`analysis.guided.triggers.invalidInstruction`**: Automatically enter guided mode when invalid instructions are encountered (default: true)
22+
23+
### Manual Activation
24+
25+
Set the `analysis.guided.enable` setting to `true` for a function. This will cause only the initial entry basic block to appear, requiring you to manually add additional blocks. It's also possible to enter guided mode by right-clicking on any existing block and using the Halt Disassembly action, discussed later.
26+
27+
## Working with Guided Analysis
28+
29+
### UI Indicators
30+
31+
When guided analysis is active, the UI will show a special indicator at the top of the function. This helps you identify when you are in guided mode and which blocks are available for analysis. The indicator includes a clickable link to exit guided mode, which disables the `analysis.guided.enable` setting and any trigger settings to prevent automatic re-entry into guided mode.
32+
33+
![Guided Analysis Status](../img/guided-analysis-status.png)
34+
35+
### Menu Actions
36+
37+
The guided analysis menu actions are only available in the **Disassembly** view. These actions control direct outgoing edges from basic blocks - indirect branches that use solvers and data flow analysis cannot be controlled through guided analysis.
38+
39+
- **Continue Disassembly**: Right-click on halted blocks to resume analysis of their branch targets
40+
- **Halt Disassembly**: Right-click on any existing block to stop analysis of its branch targets. This allows you to focus on specific blocks without automatic expansion.
41+
42+
![Guided Analysis Halt](../img/guided-analysis-halt.png)
43+
44+
### Typical Workflow
45+
46+
1. Enable guided analysis (automatically triggered or manually enabled)
47+
2. Use "Continue Disassembly" to add blocks whose branch targets should be analyzed
48+
3. Use "Halt Disassembly" to remove blocks from having their branch targets analyzed
49+
4. Iteratively refine which blocks have their branch targets analyzed based on your needs
50+
51+
## Key Use Cases
52+
53+
Guided Analysis is particularly valuable for:
54+
55+
### Obfuscated Code Analysis
56+
- **Control flow obfuscation**: Navigate through flattened control flow by manually selecting legitimate paths
57+
- **Junk code insertion**: Ignore irrelevant code branches that confuse automatic analysis
58+
- **Anti-analysis techniques**: Bypass detection mechanisms by avoiding trigger blocks
59+
60+
### Malware Analysis
61+
- **Anti-debugging evasion**: Avoid analysis-detection code paths
62+
- **Payload extraction**: Focus on malicious functionality while ignoring wrapper code
63+
- **Command & control**: Trace communication logic through specific execution paths
64+
65+
### Performance & Debugging
66+
- **Large binary analysis**: Reduce analysis time by focusing on critical sections
67+
- **Analysis issues**: Isolate problematic regions when Binary Ninja's automatic analysis fails
68+
- **Incremental analysis**: Gradually expand analysis scope as understanding improves
69+
70+
71+
## API Reference
72+
73+
Guided analysis can be controlled programmatically through a dedicated Python API, supporting custom analysis scripts and plugins. Refer to the Python API documentation for detailed usage instructions.

docs/img/guided-analysis-halt.png

92.6 KB
Loading
29.9 KB
Loading
14.6 KB
Loading

python/function.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,15 @@ def set_user_indirect_branches(
22942294
def set_guided_source_blocks(
22952295
self, addresses: List[Tuple['architecture.Architecture', int]]
22962296
) -> None:
2297+
"""
2298+
``set_guided_source_blocks`` sets the complete list of guided source blocks for this function.
2299+
Only blocks in this set will have their direct outgoing branch targets analyzed. This replaces
2300+
any existing guided source blocks and automatically enables or disables the ``analysis.guided.enable``
2301+
setting based on whether addresses are provided.
2302+
2303+
:param List[Tuple[architecture.Architecture, int]] addresses: List of (architecture, address) tuples
2304+
:rtype: None
2305+
"""
22972306
address_list = (core.BNArchitectureAndAddress * len(addresses))()
22982307
for i in range(len(addresses)):
22992308
address_list[i].arch = addresses[i][0].handle
@@ -2303,6 +2312,14 @@ def set_guided_source_blocks(
23032312
def add_guided_source_blocks(
23042313
self, addresses: List[Tuple['architecture.Architecture', int]]
23052314
) -> None:
2315+
"""
2316+
``add_guided_source_blocks`` adds blocks to the guided source block list for this function.
2317+
The specified blocks will have their direct outgoing branch targets analyzed. This automatically
2318+
enables the ``analysis.guided.enable`` setting if it is not already enabled.
2319+
2320+
:param List[Tuple[architecture.Architecture, int]] addresses: List of (architecture, address) tuples to add
2321+
:rtype: None
2322+
"""
23062323
address_list = (core.BNArchitectureAndAddress * len(addresses))()
23072324
for i in range(len(addresses)):
23082325
address_list[i].arch = addresses[i][0].handle
@@ -2312,6 +2329,14 @@ def add_guided_source_blocks(
23122329
def remove_guided_source_blocks(
23132330
self, addresses: List[Tuple['architecture.Architecture', int]]
23142331
) -> None:
2332+
"""
2333+
``remove_guided_source_blocks`` removes blocks from the guided source block list for this function.
2334+
The specified blocks will no longer have their direct outgoing branch targets analyzed.
2335+
This automatically enables the ``analysis.guided.enable`` setting if it is not already enabled.
2336+
2337+
:param List[Tuple[architecture.Architecture, int]] addresses: List of (architecture, address) tuples to remove
2338+
:rtype: None
2339+
"""
23152340
address_list = (core.BNArchitectureAndAddress * len(addresses))()
23162341
for i in range(len(addresses)):
23172342
address_list[i].arch = addresses[i][0].handle
@@ -2327,16 +2352,19 @@ def is_guided_source_block(
23272352
:param architecture.Architecture arch: Architecture of the address to check
23282353
:param int addr: Address to check
23292354
:rtype: bool
2330-
:Example:
2331-
2332-
>>> current_function.is_guided_source_block(arch, 0x400000)
2333-
True
23342355
"""
23352356
return core.BNIsGuidedSourceBlock(self.handle, arch.handle, addr)
23362357

23372358
def get_guided_source_blocks(
23382359
self
23392360
) -> List[Tuple['architecture.Architecture', int]]:
2361+
"""
2362+
``get_guided_source_blocks`` returns the current list of guided source blocks for this function.
2363+
These blocks have their direct outgoing branch targets analyzed.
2364+
2365+
:rtype: List[Tuple[architecture.Architecture, int]]
2366+
:return: List of (architecture, address) tuples representing current guided source blocks
2367+
"""
23402368
count = ctypes.c_ulonglong()
23412369
addresses = core.BNGetGuidedSourceBlocks(self.handle, count)
23422370
try:
@@ -2353,6 +2381,13 @@ def get_guided_source_blocks(
23532381
core.BNFreeArchitectureAndAddressList(addresses)
23542382

23552383
def has_guided_source_blocks(self) -> bool:
2384+
"""
2385+
``has_guided_source_blocks`` checks if this function has any guided source blocks configured.
2386+
This indicates whether guided analysis is active for this function.
2387+
2388+
:rtype: bool
2389+
:return: True if the function has guided source blocks, False otherwise
2390+
"""
23562391
return core.BNHasGuidedSourceBlocks(self.handle)
23572392

23582393
def get_indirect_branches_at(

0 commit comments

Comments
 (0)