summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/about/index.md2
-rw-r--r--docs/dev/annotation.md16
-rw-r--r--docs/dev/batch.md8
-rw-r--r--docs/dev/bnil-hlil.md32
-rw-r--r--docs/dev/bnil-llil.md16
-rw-r--r--docs/dev/bnil-mlil.md20
-rw-r--r--docs/dev/bnil-modifying.md215
-rw-r--r--docs/dev/bnil-overview.md14
-rw-r--r--docs/dev/concepts.md48
-rw-r--r--docs/dev/flags.md48
-rw-r--r--docs/dev/index.md2
-rw-r--r--docs/dev/plugins.md60
-rw-r--r--docs/dev/themes.md4
-rw-r--r--docs/dev/typelibraries.md4
-rw-r--r--docs/dev/uidf.md8
-rw-r--r--docs/dev/workflows.md4
-rw-r--r--docs/guide/enterprise/index.md2
-rw-r--r--docs/guide/firmwareninja.md2
-rw-r--r--docs/guide/index.md74
-rw-r--r--docs/guide/migration/migrationguideghidra.md10
-rw-r--r--docs/guide/migration/migrationguideida.md8
-rw-r--r--docs/guide/sharedcache.md9
-rw-r--r--docs/guide/troubleshooting.md10
-rw-r--r--docs/guide/types/attributes.md26
-rw-r--r--docs/guide/types/basictypes.md4
-rw-r--r--docs/guide/types/cpp.md14
-rw-r--r--docs/guide/types/debuginfo.md10
-rw-r--r--docs/guide/types/index.md2
-rw-r--r--docs/guide/types/platformtypes.md8
-rw-r--r--docs/guide/types/type.md6
-rw-r--r--docs/guide/types/typeimportexport.md18
-rw-r--r--docs/guide/warp.md28
32 files changed, 366 insertions, 366 deletions
diff --git a/docs/about/index.md b/docs/about/index.md
index eab75260..7516c0c1 100644
--- a/docs/about/index.md
+++ b/docs/about/index.md
@@ -1,6 +1,6 @@
# About
-Binary Ninja is a registered trademark of [Vector 35](https://vector35.com/) and is available under multiple licenses [licenses](license.md) depending on your purchase.
+Binary Ninja is a registered trademark of [Vector 35](https://vector35.com/) and is available under multiple [licenses](license.md) depending on your purchase.
Vector 35 is proud to both [use](open-source.md) and contribute to a number of open source products as well as release many components of Binary Ninja as [open source](https://github.com/orgs/Vector35/repositories?q=&type=source&language=&sort=) as well.
diff --git a/docs/dev/annotation.md b/docs/dev/annotation.md
index e83d1a2e..d350700f 100644
--- a/docs/dev/annotation.md
+++ b/docs/dev/annotation.md
@@ -308,7 +308,7 @@ Here's a few useful concepts when working Binary Ninja's type system.
In Binary Ninja the name of a class/struct/union or enumeration is separate from its type definition. This
is much like how it's done in C. The mapping between a structure's definition and its name is kept in the Binary View.
-Thus if we want to associate a name with our type we need an extra step.
+Thus, if we want to associate a name with our type we need an extra step.
```python
bv.define_user_type('Foo', Type.structure(members=[(Type.int(4), 'field_0')]))
@@ -356,7 +356,7 @@ struct Bas
#### Mutable Types
-As `Type` objects are immutable, the Binary Ninja API provides a pure python implementation of types to provide mutability, these all inherit from `MutableType` and keep the same names as their immutable counterparts minus the `Type` part. Thus `Structure` is the mutable version of `StructureType` and `Enumeration` is the mutable version of `MutableType`. `Type` objects can be converted to `MutableType` objects using the `Type.mutable_copy` API and, `MutableType` objects can be converted to `Type` objects through the `MutableType.immutable_copy` API. Generally speaking you shouldn't need the mutable type variants for anything except creation of structures and enumerations, mutable type variants are provided for convenience and consistency. Building and defining a new structure can be done in a few ways. The first way would be the two step process of creating the structure then defining it.
+As `Type` objects are immutable, the Binary Ninja API provides a pure python implementation of types to provide mutability, these all inherit from `MutableType` and keep the same names as their immutable counterparts minus the `Type` part. Thus, `Structure` is the mutable version of `StructureType` and `Enumeration` is the mutable version of `MutableType`. `Type` objects can be converted to `MutableType` objects using the `Type.mutable_copy` API and, `MutableType` objects can be converted to `Type` objects through the `MutableType.immutable_copy` API. Generally speaking you shouldn't need the mutable type variants for anything except creation of structures and enumerations, mutable type variants are provided for convenience and consistency. Building and defining a new structure can be done in a few ways. The first way would be the two-step process of creating the structure then defining it.
```python
s = StructureBuilder.create(members=[(IntegerType.create(4), 'field_0')])
@@ -373,7 +373,7 @@ s.append(IntegerType.create(4))
bv.define_user_type('Foo', s)
```
-Finally you can use the built-in context manager which automatically registers the created type with the provided `BinaryView` (`bv`) and name(`Foo`). Additionally when creating TypeLibraries a `Type` can be passed instead of a `BinaryView`
+Finally, you can use the built-in context manager which automatically registers the created type with the provided `BinaryView` (`bv`) and name(`Foo`). Additionally, when creating TypeLibraries a `Type` can be passed instead of a `BinaryView`
```python
with StructureBuilder.builder(bv, 'Foo') as s:
@@ -412,7 +412,7 @@ There are 3 categories of object which can have `Type` objects applied to them.
* Variables (i.e. local variables)
* DataVariables (i.e. global variables)
-As of the 3.0 API its much easier to apply types to Variables and DataVariables
+As of the 3.0 API it's much easier to apply types to Variables and DataVariables
#### Applying a type to a `Function`
@@ -463,13 +463,13 @@ Importing a header goes through the same code path as parsing source directly. Y
(<types: [...], variables: [...], functions: [...]>, [])
```
-Using these APIs will give you a Python object with all of the results, but won't actually apply them to the analysis in any way. If you want to replicate the importing behavior seen in the UI widget, there are a few additional steps you will need to take:
+Using these APIs will give you a Python object with all the results, but won't actually apply them to the analysis in any way. If you want to replicate the importing behavior seen in the UI widget, there are a few additional steps you will need to take:
1. Use `BinaryView.define_user_types()` to add all the created types to the analysis
-1. Update the function and data variable types
+2. Update the function and data variable types
1. Look up matching functions and symbols by using `BinaryView.get_symbol_by_raw_name`. Also look up potentially modified function names starting with `_` or `__`
- 1. Once you have found a function whose name matches one found in the header file, set its type using `Function.type = ftype`
- 1. Similarly for Data Variables, once one is found with a matching name, set its type using `DataVariable.type = dvtype`
+ 2. Once you have found a function whose name matches one found in the header file, set its type using `Function.type = ftype`
+ 3. Similarly for Data Variables, once one is found with a matching name, set its type using `DataVariable.type = dvtype`
#### Exporting a Header
diff --git a/docs/dev/batch.md b/docs/dev/batch.md
index 1448d34f..ab7e1830 100644
--- a/docs/dev/batch.md
+++ b/docs/dev/batch.md
@@ -2,7 +2,7 @@
An often asked question of Binary Ninja is "How do I enable batch-processing mode?". The answer is that we don't have one--but the good news is because it doesn't need it! We have an even better solution. BN is simply a library that is trivial to include in your own scripts for batch analysis. As long as you have a Commercial or Ultimate license (or a [headless](https://binary.ninja/purchase/#container:~:text=This%20works%20especially%20well%20with%20our,that%20are%20designed%20for%20headless%2Donly%20installs.) license), it's possible to invoke the core analysis library with all of its APIs without even launching the UI.
-This document describes some general tips and tricks for effective batch processing. In particular, because Binary Ninja is multi-threaded, some methods for faster processing like [multiprocessing](https://docs.python.org/3/library/multiprocessing.html) can have dangerous consequences.
+This document describes some general tips and tricks for effective batch processing. In particular, because Binary Ninja is multithreaded, some methods for faster processing like [multiprocessing](https://docs.python.org/3/library/multiprocessing.html) can have dangerous consequences.
## Dedicated Python
@@ -74,11 +74,11 @@ Opening /bin/ls which has 50 functions
...
```
-Notice that we have far fewer functions in `/bin/ls` this time. By shortcutting the analysis we've prevented further function identification but we've done so much more quickly.
+Notice that we have far fewer functions in `/bin/ls` this time. By shortcutting the analysis we've prevented further function identification, but we've done so much more quickly.
### Single Function Analysis
-A common workflow is to analyze a single (or small number) of functions in a particular binaries. This can be done using the analysis hold feature:
+A common workflow is to analyze a single (or small number) of functions in a particular binary. This can be done using the analysis hold feature:
```python
from binaryninja import load
@@ -127,7 +127,7 @@ To use this API, copy the contents of your license file into a string and pass i
## Parallelization
-Of course, one of the main reasons you might want to build some automation so to spin up a number of threads to process multiple files. Be aware though, that Binary Ninja itself is multithreaded. In fact, if the bottle neck for your analysis script is BN itself, you're almost certainly better off not using any parallelization because the multithreading BN does on its own will provide more benefit than you'd gain by extra parallelization.
+Of course, one of the main reasons you might want to build some automation so to spin up a number of threads to process multiple files. Be aware though, that Binary Ninja itself is multithreaded. In fact, if the bottleneck for your analysis script is BN itself, you're almost certainly better off not using any parallelization because the multithreading BN does on its own will provide more benefit than you'd gain by extra parallelization.
That said, there are certainly several good use cases where splitting your analysis makes sense. When processing many files for example, you might want to use multiple processes so that a single big slow file doesn't slow down the rest of the analysis as much. Or if you're working with potentially malformed files that may trigger bugs or crashes and you're worried about a single script failing.
diff --git a/docs/dev/bnil-hlil.md b/docs/dev/bnil-hlil.md
index 4829ad4a..b66081dc 100644
--- a/docs/dev/bnil-hlil.md
+++ b/docs/dev/bnil-hlil.md
@@ -16,7 +16,7 @@ The High Level Intermediate Language (HLIL) is Binary Ninja's decompiler output.
## Debug Report
-To observe the transformartions that occur from MLIL to HLIL, you can use the built-in [`debug report`](https://api.binary.ninja/binaryninja.function-module.html#binaryninja.function.Function.request_debug_report) API:
+To observe the transformations that occur from MLIL to HLIL, you can use the built-in [`debug report`](https://api.binary.ninja/binaryninja.function-module.html#binaryninja.function.Function.request_debug_report) API:
```py
> current_function.request_debug_report("hlil")
@@ -51,22 +51,22 @@ There are a number of properties that can be queried on the [`HighLevelILInstruc
* `HLIL_TAILCALL` - This instruction calls the expression `dest` using `params` as input and `output` for return values
not exist
* `HLIL_SYSCALL` - Make a system/service call with parameters `params` and output `output`
-* `HLIL_WHILE` -
-* `HLIL_DO_WHILE` -
-* `HLIL_FOR` -
-* `HLIL_SWITCH` -
-* `HLIL_CASE` -
-* `HLIL_BREAK` -
-* `HLIL_CONTINUE` -
+* `HLIL_WHILE` -
+* `HLIL_DO_WHILE` -
+* `HLIL_FOR` -
+* `HLIL_SWITCH` -
+* `HLIL_CASE` -
+* `HLIL_BREAK` -
+* `HLIL_CONTINUE` -
### Variable Reads and Writes
* `HLIL_VAR_DECLARE` - A declaration of `var`
* `HLIL_VAR_INIT` - Initializes `dest` to the result of an expression `src`
* `HLIL_ASSIGN` - Sets a variable `dest` to the result of an expression `src`
-* `HLIL_ASSIGN_UNPACK` -
+* `HLIL_ASSIGN_UNPACK` -
* `HLIL_VAR` - A variable expression `src`
-* `HLIL_VAR_PHI` - A `PHI` represents the combination of several prior versions of a variable when differnet basic blocks coalesce into a single destination and it's unknown which path was taken.
+* `HLIL_VAR_PHI` - A `PHI` represents the combination of several prior versions of a variable when different basic blocks coalesce into a single destination and it's unknown which path was taken.
* `HLIL_MEM_PHI` - A memory `PHI` represents memory modifications that could have occured down different source basic blocks similar to a `VAR_PHI`.
* `HLIL_ADDRESS_OF` - The address of variable `src`
* `HLIL_CONST` - A constant integral value `constant`
@@ -76,11 +76,11 @@ not exist
* `HLIL_FLOAT_CONST` - A floating point constant `constant`
* `HLIL_IMPORT` - A `constant` integral value representing an imported address
* `HLIL_LOW_PART` - `size` bytes from the low end of `src` expression
-* `HLIL_STRUCT_FIELD` -
-* `HLIL_ARRAY_INDEX` -
+* `HLIL_STRUCT_FIELD` -
+* `HLIL_ARRAY_INDEX` -
* `HLIL_SPLIT` - A split pair of variables `high`:`low` which can be used a single expression
* `HLIL_DEREF` - Dereferences `src`
-* `HLIL_DEREF_FIELD` -
+* `HLIL_DEREF_FIELD` -
### Arithmetic Operations
@@ -161,6 +161,6 @@ not exist
* `HLIL_UNDEF` - The expression performs undefined behavior
* `HLIL_UNIMPL` - The expression is not implemented
* `HLIL_UNIMPL_MEM` - The expression is not implemented but does access `src` memory
-* `HLIL_BLOCK` -
-* `HLIL_LABEL` -
-* `HLIL_UNREACHABLE` -
+* `HLIL_BLOCK` -
+* `HLIL_LABEL` -
+* `HLIL_UNREACHABLE` -
diff --git a/docs/dev/bnil-llil.md b/docs/dev/bnil-llil.md
index cf1cc5f6..e8b77a07 100644
--- a/docs/dev/bnil-llil.md
+++ b/docs/dev/bnil-llil.md
@@ -1,6 +1,6 @@
# Binary Ninja Intermediate Language: Low Level IL
-Make sure to checkout the [BNIL overview](bnil-overview.md) first if you haven't already. Or feel free to skip to [part 2](bnil-mlil.md) which covers MLIL, or [part 3](bnil-hlil.md) which covers HLIL. This developer guide is intended to cover some of the mechanics of the LLIL to distinguish it from the other ILs in the BNIL family.
+Make sure to checkout the [BNIL overview](bnil-overview.md) first if you haven't already. Or feel free to skip to [part 2](bnil-mlil.md) which covers MLIL, or [part 3](bnil-hlil.md) which covers HLIL. This developer guide is intended to cover some mechanics of LLIL to distinguish it from the other ILs in the BNIL family.
If you've already read the introduction, let's get right into the details of LLIL!
@@ -42,7 +42,7 @@ Next we get the [`lowlevelil.LowLevelILFunction`](https://api.binary.ninja/binar
Finally, we can print out the attributes of the instruction. We first print out `address` which is the address of the corresponding assembly language instruction. Next, we print the `instr_index`, this you can think of as the address of the IL instruction. Since translating assembly language is a many-to-many relationship, we may see multiple IL instructions needed to represent a single assembly language instruction, and thus each IL instruction needs to have its own index separate from its address. Finally, we print out the instruction text.
-In python, iterating over a class is a distinct operation from subscripting. This separation is used in the `LowLevelILFunction` class. If you iterate over a `LowLevelILFunction` you get a list of `LowLevelILBasicBlocks`, however if you subscript a `LowLevelILFunction` you actually get the `LowLevelILInstruction` whose `instr_index` corresponds to the subscript:
+In python, iterating over a class is a distinct operation from subscripting. This separation is used in the `LowLevelILFunction` class. If you iterate over a `LowLevelILFunction` you get a list of `LowLevelILBasicBlocks`, however if you subscript a `LowLevelILFunction` you actually get the `LowLevelILInstruction` whose `instr_index` corresponds to the subscript:
```
>>> list(current_function.low_level_il)
@@ -55,7 +55,7 @@ In python, iterating over a class is a distinct operation from subscripting. Th
```
## Low Level IL Instructions
-Now that we've established how to access LLIL Functions, Blocks, and Instructions, let's focus in on the instructions themselves. LLIL instructions are infinite length and structured as an expression tree. An expression tree means that instruction operands can be composed of operation. Thus we can have an IL instruction like this:
+Now that we've established how to access LLIL Functions, Blocks, and Instructions, let's focus in on the instructions themselves. LLIL instructions are infinite length and structured as an expression tree. An expression tree means that instruction operands can be composed of operation. Thus, we can have an IL instruction like this:
```
eax = eax + ecx * 4
@@ -159,7 +159,7 @@ Going into gross detail on all the instructions is out of scope of this article,
### Registers, Constants & Flags
-When parsing an instruction tree the terminals are registers, constants and flags. This provide the basis from which all instructions are built.
+When parsing an instruction tree the terminals are registers, constants and flags. This provides the basis from which all instructions are built.
* `LLIL_REG` - A register, terminal
* `LLIL_CONST` - A constant integer value, terminal
@@ -173,8 +173,8 @@ Reading and writing memory is accomplished through the following instructions.
* `LLIL_LOAD` - Load a value from memory.
* `LLIL_STORE` - Store a value to memory.
-* `LLIL_PUSH` - Store value to stack; adjusting stack pointer by sizeof(value) after the store.
-* `LLIL_POP` - Load value from stack; adjusting stack pointer by sizeof(value) after the store.
+* `LLIL_PUSH` - Store value to stack; adjusting stack pointer by `sizeof(value)` after the store.
+* `LLIL_POP` - Load value from stack; adjusting stack pointer by `sizeof(value)` after the store.
### Control Flow & Conditionals
@@ -206,7 +206,7 @@ As you can see from the above code, labels are really just used internally and a
* `LLIL_SYSCALL` - System call instruction
* `LLIL_TAILCALL ` - This instruction calls the expression `dest` using `params` as input and `output` for return values
* `LLIL_IF` - `If` provides conditional execution. If condition is true execution branches to the true label and false label otherwise.
-* `LLIL_GOTO` - `Goto` is used to branch to an IL label, this is different than jump since jump can only jump to addresses.
+* `LLIL_GOTO` - `Goto` is used to branch to an IL label, this is different from jump since jump can only jump to addresses.
* `LLIL_FLAG_COND` - Returns the flag condition expression for the specified flag condition.
* `LLIL_CMP_E` - equality
* `LLIL_CMP_NE` - not equal
@@ -275,7 +275,7 @@ The double precision instruction multiply, divide, modulus instructions are part
### Floating Point Conditionals
-These are identical to their native counterparts but are lifted separately so that the operations can impact different flags. See "Control FLow & Conditionals" above.
+These are identical to their native counterparts but are lifted separately so that the operations can impact different flags. See [Control Flow & Conditionals](#control-flow--conditionals) above.
* `LLIL_FCMP_E ` - See above
* `LLIL_FCMP_NE ` - See above
diff --git a/docs/dev/bnil-mlil.md b/docs/dev/bnil-mlil.md
index bdade82c..57cccb00 100644
--- a/docs/dev/bnil-mlil.md
+++ b/docs/dev/bnil-mlil.md
@@ -34,7 +34,7 @@ First, it's important to understand what we mean when we talk about a MLIL varia
<class 'binaryninja.function.Variable'>
```
-Variables in MLIL have a very specific meaning, that is not completely obvious at first. They represent a single storage location within the scope of a single function. To those not well versed in program analysis, a storage location is where a value is located at a given point in time. In the process of compilation a compiler conducts a step called _Register Allocation_; this is the process of figuring out how to map the potentially infinite number of variables specified in the original source code to a finite set of registers. When there are more variables and intermediate values than registers available, the compiler _spills_ them on to the stack. Thus a single high-level-language variable can be mapped across a number of storage locations. A variable can simultaneously be in multiple registers and on the stack at the same time. However, unlike high-level-language variables, MLIL variables represent one and only one storage location. Binary Ninja's High Level IL (HLIL) will be responsible for storing this mapping.
+Variables in MLIL have a very specific meaning, that is not completely obvious at first. They represent a single storage location within the scope of a single function. To those not well versed in program analysis, a storage location is where a value is located at a given point in time. In the process of compilation a compiler conducts a step called _Register Allocation_; this is the process of figuring out how to map the potentially infinite number of variables specified in the original source code to a finite set of registers. When there are more variables and intermediate values than registers available, the compiler _spills_ them on to the stack. Thus, a single high-level-language variable can be mapped across a number of storage locations. A variable can simultaneously be in multiple registers and on the stack at the same time. However, unlike high-level-language variables, MLIL variables represent one and only one storage location. Binary Ninja's High Level IL (HLIL) will be responsible for storing this mapping.
So let's look at the properties available on a [`Variable`](https://api.binary.ninja/binaryninja.variable-module.html#binaryninja.variable.Variable) object.
@@ -76,7 +76,7 @@ The `storage` property changes meaning depending on the [`VariableSourceType`](h
'-0x260'
```
-Given the above information it might now be intuitive how variable names are constructed. First we determine the `source_type` of the variable. If it's a `RegisterVariableSourceType` we just use the register's name directly. If it’s a `StackVariableSourceType` then we use `var_` + `hex(-storage)`. Finally, we append a count each time that that storage location is reused.
+Given the above information it might now be intuitive how variable names are constructed. First we determine the `source_type` of the variable. If it's a `RegisterVariableSourceType` we just use the register's name directly. If it’s a `StackVariableSourceType` then we use `var_` + `hex(-storage)`. Finally, we append a count each time that that storage location is reused.
### `index`
The `index` is an identifier chosen to be unique across different analysis passes.
@@ -128,7 +128,7 @@ A boolean type is an integer which has a value of False (0) or True (!0).
### IntegerTypeClass
-An integer type has a sign, a width (in bytes), and a display type. The display type determines how the integer should be displayed; the options are self explanatory:
+An integer type has a sign, a width (in bytes), and a display type. The display type determines how the integer should be displayed; the options are self-explanatory:
```
enum IntegerDisplayType
@@ -150,7 +150,7 @@ enum IntegerDisplayType
### FloatTypeClass
-The float type is a IEEE 754 variable precision type, and can represent floating point numbers up to 10 bytes in width. All floating point numbers are assumed to be signed.
+The float type is an IEEE 754 variable precision type, and can represent floating point numbers up to 10 bytes in width. All floating point numbers are assumed to be signed.
### WideCharTypeClass
@@ -163,7 +163,7 @@ A varargs type is used to indicate that a function is variadic and thus represen
### ValueTypeClass
-A value type is simply a constant value. It is used mainly in demangling for types which only have a have a name or value.
+A value type is simply a constant value. It is used mainly in demangling for types which only have a name or value.
### FunctionTypeClass
@@ -189,7 +189,7 @@ Array types function similarly to pointer types however the array type knows how
* `target`/`element_type` - the type of element this array is constructed of
* `count` - the count of array elements
-* `width` - the size of the array (count * target.width)
+* `width` - the size of the array (`count * target.width`)
### EnumerationTypeClass
@@ -243,7 +243,7 @@ From the code in [`mediumlevelil.py`](https://github.com/Vector35/binaryninja-ap
MediumLevelILOperation.MLIL_CALL: [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")],
```
-Thus we can query the call's `output` which is a list of variables:
+Thus, we can query the call's `output` which is a list of variables:
```
>>> inst.output
@@ -288,7 +288,7 @@ The parameter list can be accessed through the `params` property:
* `MLIL_IF` - Branch to the `true`/`false` MLIL instruction identifier depending on the result of the `condition` expression
* `MLIL_GOTO` - Branch to the `dest` expression id
* `MLIL_TAILCALL` - This instruction calls the expression `dest` using `params` as input and `output` for return values
-* `MLIL_TAILCALL_UNTYPED ` - A tailcall where the stack stack resolution could not be determined and thus a list of parameters and return values do not exist
+* `MLIL_TAILCALL_UNTYPED ` - A tailcall where the stack resolution could not be determined and thus a list of parameters and return values do not exist
* `MLIL_SYSCALL` - Make a system/service call with parameters `params` and output `output`
* `MLIL_SYSCALL_UNTYPED` - Makes a system/service call, but an exact set of parameters couldn't be determined.
@@ -308,8 +308,8 @@ The parameter list can be accessed through the `params` property:
* `MLIL_VAR_ALIASED_FIELD` -
* `MLIL_VAR_FIELD` - A variable and offset expression `src`, `offset`
* `MLIL_VAR_SPLIT` - A split pair of variables `high`:`low` which can be used a single expression
-* `MLIL_VAR_PHI` - A `PHI` represents the combination of several prior versions of a variable when differnet basic blocks coalesce into a single destination and it's unknown which path was taken.
-* `MLIL_MEM_PHI` - A memory `PHI` represents memory modifications that could have occured down different source basic blocks similar to a `VAR_PHI`.
+* `MLIL_VAR_PHI` - A `PHI` represents the combination of several prior versions of a variable when different basic blocks coalesce into a single destination and it's unknown which path was taken.
+* `MLIL_MEM_PHI` - A memory `PHI` represents memory modifications that could have occurred down different source basic blocks similar to a `VAR_PHI`.
* `MLIL_ADDRESS_OF` - The address of variable `src`
* `MLIL_ADDRESS_OF_FIELD` - The address and `offset` of the variable `src`
* `MLIL_CONST` - A constant integral value `constant`
diff --git a/docs/dev/bnil-modifying.md b/docs/dev/bnil-modifying.md
index ac521d4f..bcd02b5b 100644
--- a/docs/dev/bnil-modifying.md
+++ b/docs/dev/bnil-modifying.md
@@ -19,7 +19,7 @@ Key:
| Medium Level IL | ✅ | ✅ | ❌ |
| High Level IL | ⚠️* | ❌ | ❌ |
-\* Modifying High Level IL in C++, while some APIs exist, is incomplete and [certain more complicated operations are not possible yet](#notes-on-hlil).
+\* Modifying High Level IL in C++, while some APIs exist, is incomplete and [certain more complicated operations are not possible yet](#notes-on-hlil).
## Choosing A Level of IL To Modify
@@ -37,7 +37,7 @@ Notably, any `PossibleValueSet` calculations require MLIL or higher, so only `Re
There are certain ILs which you cannot modify, for a variety of reasons:
-- **SSA Forms** are generated by the core from the various Non-SSA Form ILs at each stage of analysis. You should not modify them, as they are considered analysis derived from the Non-SSA Form. They will likely be regenerated from the source Non-SSA Form without consulting any changes you might make to them.
+- **SSA Forms** are generated by the core from the various Non-SSA Form ILs at each stage of analysis. You should not modify them, as they are considered analysis derived from the Non-SSA Form. They will likely be regenerated from the source Non-SSA Form without consulting any changes you might make to them.
- **Disassembly** should be modified by changing the Architecture plugin if it is open source, or by using an Architecture Extension if it is not. A Workflow Activity cannot affect Disassembly.
- **Mapped MLIL** is lifted directly from LLIL SSA Form and not user-editable. Generally speaking, users and developers of Workflow Actions should not need to consult Mapped MLIL.
- **Pseudo-C** and other Language Representation forms are not a distinct level of IL, but are simply alternate renderings of HLIL.
@@ -48,7 +48,7 @@ Based on your IL of choice, there are a bunch of places you can insert your modi
- **Lifted IL** modification needs to happen before the `core.function.analyzeAndExpandFlags` stage, which translates Lifted IL into Low Level IL. After that stage, Lifted IL is never again consulted.
- Modifying flag definitions and usages is likely impossible, as the Semantic Flags system will consult the Architecture to determine what IL to generate when a flag is used, not your Workflow Action. There is currently no way to change this behavior.
-- **Low Level IL** modification is generally done right before the `core.function.generateMediumLevelIL` stage, after the final Low Level IL function is emitted. After Medium Level IL is generated, changes to the Low Level IL will have limited effects on the other ILs (because most things refer to MLIL).
+- **Low Level IL** modification is generally done right before the `core.function.generateMediumLevelIL` stage, after the final Low Level IL function is emitted. After Medium Level IL is generated, changes to the Low Level IL will have limited effects on the other ILs (because most things refer to MLIL).
- If you want to make changes to LLIL that can affect the stack pointer resolution, you will want to insert your action before `core.function.analyzeStackAdjustment` instead.
- **Medium Level IL** modification is generally done right after `core.function.generateMediumLevelIL` since (as of writing) the MLIL translation is all done in that one monolithic step and future steps are simply processing and annotations. This may change some time in the future.
- **High Level IL** modification is generally done right after `core.function.generateHighLevelIL` since HLIL generation is also monolithic. This also may change eventually.
@@ -63,12 +63,12 @@ Support for this is planned soon, but not implemented as of Binary Ninja 5.1.
- An **IL Function** is a collection of **IL Instructions**, grouped into **IL Basic Blocks**
- An **IL Basic Block** is a contiguous sequence of **IL Instructions** between a start and end **Instruction Index**, which only has incoming branches at the start and outgoing branches at the end.
- An **IL Expression** is a single-operation expression, which may have child expressions or be the child of another expression.
- - The `*LevelILInstruction` class represents a single **IL Expression**. The class name may be confusing since **IL Instructions** are a different concept.
+ - The `*LevelILInstruction` class represents a single **IL Expression**. The class name may be confusing since **IL Instructions** are a different concept.
- An **Expression Index** points to an **IL Expression** and may be used as an operand of another **IL Expression**.
- An **IL Instruction** is an **IL Expression** that has been added as a top-level instruction to the function with a call to `*LevelILFunction.append()` (C++: `*LevelILFunction::AddInstruction`)
- An **Instruction Index** is assigned to an **IL Expression** that is added as an **IL Instruction**. Child expressions of an **IL Instruction** do not inherently have an **Instruction Index**, though the API tries to provide this for you.
- A **Mutate Transformation** is a simple modification of **IL Instructions** in an **IL Function** as per [Replacing Trivial Instructions (Mutate Transformation)](#replacing-trivial-instructions-mutate-transformation) below.
-- A **Copy Transformation** is a more in-depth modification of an **IL Function** which involves copying its **IL Instructions** into a newly constructed **IL Function** with modifications made along the way, as per [Adding Instructions and Replacing Multiple Instructions (Copy Transformation)](#adding-instructions-and-replacing-multiple-instructions-copy-transformation) below.
+- A **Copy Transformation** is a more in-depth modification of an **IL Function** which involves copying its **IL Instructions** into a newly constructed **IL Function** with modifications made along the way, as per [Adding Instructions and Replacing Multiple Instructions (Copy Transformation)](#adding-instructions-and-replacing-multiple-instructions-copy-transformation) below.
## Writing a Transformation
@@ -79,24 +79,24 @@ Once you figure out which level of IL you want to modify, and where in the Workf
In order for your modifications to run, you need to register a Workflow Activity.
There are a couple of steps involved in this process:
-First, you need to make a clone of the default workflow, making it mutable and allowing you to insert your Activity.
+First, you need to make a clone of the default workflow, making it mutable and allowing you to insert your Activity.
You can either name the clone the same thing as the metaAnalysis workflow to make your Activity available by default,
or clone to a different name, which will require users to select that workflow in Open with Options.
Also note that, as of writing, Objective-C support registers its own workflow as `core.function.objectiveC`.
If you want your Workflow Activity to apply to Objective-C files, you will need to do this whole process twice, once for `core.function.metaAnalysis` and once for `core.function.objectiveC`.
-The same applies if any of your other plugins register a custom workflow that is not `core.function.metaAnalysis`.
+The same applies if any of your other plugins register a custom workflow that is not `core.function.metaAnalysis`.
=== "Python"
```py
- # This Workflow will replace metaAnalysis and be used by default
+ # This Workflow will replace metaAnalysis and be used by default
wf = Workflow("core.function.metaAnalysis").clone("core.function.metaAnalysis")
-
+
# Users will need to pick this Workflow in Open with Options
wf = Workflow("core.function.metaAnalysis").clone("MyCustomWorkflow")
-
+
# As of 5.1: To modify functions in binaries using the Objective-C workflow,
- # you need to do the entire rest of this section twice:
+ # you need to do the entire rest of this section twice:
# once as above, and once for the Objective-C workflow as shown here.
wf = Workflow("core.function.objectiveC").clone("core.function.objectiveC")
```
@@ -105,10 +105,10 @@ The same applies if any of your other plugins register a custom workflow that is
```c++
// This Workflow will replace metaAnalysis and be used by default
auto wf = Workflow::Instance("core.function.metaAnalysis")->Clone("core.function.metaAnalysis");
-
+
// Users will need to pick this Workflow in Open with Options
auto wf = Workflow::Instance("core.function.metaAnalysis")->Clone("MyCustomWorkflow");
-
+
// As of 5.1: To modify functions in binaries using the Objective-C workflow,
// you need to do the entire rest of this section twice:
// once as above, and once for the Objective-C workflow as shown here.
@@ -122,7 +122,7 @@ Then, define a new Activity on the Workflow, which allows you to run your code t
```py
def rewrite_action(context: AnalysisContext):
# Actual modification code goes here (documented below)...
-
+
# Define the custom activity configuration
wf.register_activity(Activity(
configuration=json.dumps({
@@ -137,7 +137,7 @@ Then, define a new Activity on the Workflow, which allows you to run your code t
}),
action=rewrite_action
))
-
+
# Add the new action to the workflow, with position as described above
wf.insert_after("core.function.generateMediumLevelIL", [
"extension.my_extension.do_the_thing"
@@ -152,11 +152,11 @@ Then, define a new Activity on the Workflow, which allows you to run your code t
{
// Actual modification code goes here (documented below)...
}
-
+
BINARYNINJAPLUGIN bool CorePluginInit()
{
// Rest of your plugin init here ...
-
+
// Define the custom activity configuration
wf->RegisterActivity(new Activity(R"~(
{
@@ -195,7 +195,7 @@ If you wish to replace more than one instruction, or replace an instruction with
### Adding Instructions and Replacing Multiple Instructions (Copy Transformation)
If you want to insert new instructions into a function, or want to replace an instruction with than one instruction, you will need to construct a new **IL Function** based on the original **IL Function**, and make your changes while copying the instructions.
-This is a rather cumbersome process and it can be easy to make mistakes.
+This is a rather cumbersome process, and it can be easy to make mistakes.
First, you need to construct a new **IL Function** based on the existing function.
Let's call the new function `new_func` and the existing function `old_func`.
@@ -206,16 +206,16 @@ Let's call the new function `new_func` and the existing function `old_func`.
# ... workflow boilerplate
def rewrite_action(context: AnalysisContext):
old_func = context.mlil
-
+
# Create a new IL Function based on the old one.
# Make sure you use the LLIL from the analysis context,
# and *do not* go through Function.llil (it will not have been updated yet)
new_func = MediumLevelILFunction(old_func.arch, low_level_il=context.llil)
-
- # Tell the new function that we are copying from an existing function
+
+ # Tell the new function that we are copying from an existing function
# (this transfers various metadata like some block labels)
new_func.prepare_to_copy_function(old_func)
-
+
# continues ...
```
@@ -231,14 +231,14 @@ Let's call the new function `new_func` and the existing function `old_func`.
// and *do not* go through Function::GetLowLevelIL (it will not have been updated yet)
// Also (C++ specific), make sure you use Ref<> to hold
- // a strong reference so the new function doesn't get deleted
+ // a strong reference so the new function doesn't get deleted
Ref<MediumLevelILFunction> newFunc = new MediumLevelILFunction(
oldFunc->GetArchitecture(),
oldFunc->GetFunction(),
context->GetLowLevelILFunction()
);
-
- // Tell the new function that we are copying from an existing function
+
+ // Tell the new function that we are copying from an existing function
// (this transfers various metadata like some block labels)
newFunc->PrepareToCopyFunction(oldFunc);
@@ -249,9 +249,9 @@ Let's call the new function `new_func` and the existing function `old_func`.
???+ Note "Note"
You may notice that the sample code above mentions always using `AnalysisContext.llil` (C++: `AnalysisContext::GetLowLevelIL()`) to access the relevant Low Level IL function,
and you may be wondering why the sample doesn't instead use `AnalysisContext.function.llil` (C++: `AnalysisContext::GetFunction()->GetLowLevelILFunction()`).
- This is because you must **always access IL Functions directly through `AnalysisContext`** when writing Workflow Activities, as that is where the current, up-to-date analysis information is stored.
+ This is because you must **always access IL Functions directly through `AnalysisContext`** when writing Workflow Activities, as that is where the current, up-to-date analysis information is stored.
During analysis, the `LowLevelILFunction` object stored in the `AnalysisContext` object contains the in-progress analysis information from the current run of the Workflow,
- whereas the `LowLevelILFunction` object stored on the Function object is from the previous run of the Workflow and contains stale analysis data.
+ whereas the `LowLevelILFunction` object stored on the Function object is from the previous run of the Workflow and contains stale analysis data.
Then, going block-by-block, copy the instructions from `old_func` to `new_func`.
When you reach a part where you want to insert new instructions (or replace instructions), do that instead of simply copying the old instructions.
@@ -260,22 +260,22 @@ When you reach a part where you want to insert new instructions (or replace inst
```py
# previous code...
-
+
# Copy each block in the old function to the new function
- for old_block in old_func.basic_blocks:
+ for old_block in old_func.basic_blocks:
# Copy some block labels and tell new IL instructions they came from this block
new_func.prepare_to_copy_block(old_block)
-
+
# Copy each instruction from the old block to the new function
# Blocks "contain" instructions by knowing their start and end instruction indices
# Any instructions in that range as in the block
for old_instr_index in range(old_block.start, old_block.end):
# Retrieve instruction from old function
old_instr: MediumLevelILInstruction = old_func[old_instr_index]
-
+
# Make sure the new instruction we insert has the correct location information
new_func.set_current_address(old_instr.address, old_block.arch)
-
+
# continues...
```
@@ -283,13 +283,13 @@ When you reach a part where you want to insert new instructions (or replace inst
```c++
// ... previous code
-
+
// Copy each block in the old function to the new function
for (auto& oldBlock: oldFunc->GetBasicBlocks())
{
// Copy some block labels and tell new IL instructions they came from this block
newFunc->PrepareToCopyBlock(oldBlock);
-
+
// Copy each instruction from the old block to the new function
// Blocks "contain" instructions by knowing their start and end instruction indices
// Any instructions in that range as in the block
@@ -297,39 +297,39 @@ When you reach a part where you want to insert new instructions (or replace inst
{
// Retrieve instruction from old function
auto oldInstr = oldFunc->GetInstruction(oldInstrIndex);
-
+
// Make sure the new instruction we insert has the correct location information
newFunc->SetCurrentAddress(oldBlock->GetArchitecture(), oldInstr.address);
-
+
// continues...
```
For each instruction, determine if you want to insert new instructions before it, or replace it with something else. You _probably_ want to do this step ahead of time and apply all the changes at once, but if your changes are simple enough you can get away with doing it inside the loop.
=== "Python"
-
+
```py
# previous code...
-
+
if want_changes:
# Create new instructions in the function for whatever changes you desire
-
+
# All ILs: Be sure to pass the location of the previous instruction
# when creating a new expression, so mappings work
new_expr = new_func.nop(ILSourceLocation.from_instruction(old_instr))
-
+
# MLIL and higher: pass the location of the previous instruction
# to append(), so cross-IL mappings are preserved
new_func.append(new_expr, ILSourceLocation.from_instruction(old_instr))
else:
# Copy the instruction as-is
-
+
# Copy the instruction from the old function to the new function
# using `copy_to` (deep copy)
# MLIL and higher: also pass the location of the previous instruction
# to append() so cross-IL mappings are preserved
new_func.append(old_instr.copy_to(new_func), ILSourceLocation.from_instruction(old_instr))
-
+
# continues ...
```
@@ -337,15 +337,15 @@ For each instruction, determine if you want to insert new instructions before it
```C++
// previous code...
-
+
if (wantChanges)
{
// Create new instructions in the function for whatever changes you desire
-
+
// All ILs: Be sure to pass the location of the previous instruction
// when creating a new expression, so mappings work
auto newExpr = newFunc->Nop(oldInstr);
-
+
// MLIL and higher: pass the location of the previous instruction
// to AddInstruction(), so cross-IL mappings are preserved
newFunc->AddInstruction(newExpr, oldInstr);
@@ -353,7 +353,7 @@ For each instruction, determine if you want to insert new instructions before it
else
{
// Copy the instruction as-is
-
+
// Copy the instruction from the old function to the new function
// using `CopyTo()` (deep copy)
// MLIL and higher: also pass the location of the previous instruction
@@ -368,16 +368,16 @@ For each instruction, determine if you want to insert new instructions before it
And finally, regenerate dataflow:
=== "Python"
-
+
```py
# previous code ...
-
+
# Create IL basic blocks
new_func.finalize()
-
+
# Do dataflow, etc
new_func.generate_ssa_form()
-
+
# Assign to the context to apply modifications
context.mlil = new_func
```
@@ -386,13 +386,13 @@ And finally, regenerate dataflow:
```C++
// previous code ...
-
+
// Create IL basic blocks
newFunc->Finalize();
-
+
// Do dataflow, etc
newFunc->GenerateSSAForm();
-
+
// Assign to the context to apply modifications
context->SetMediumLevelILFunction(newFunc);
}
@@ -408,15 +408,15 @@ Due to limitations currently in the Python bindings, IL mappings will only updat
```py
# previous code ...
-
+
# Need to commit this for mappings to work (as of 5.1 at least)
context.mlil = new_func
-
+
# Now we want to modify the function again...
-
+
# The newly created function is now our "old function"
old_func = new_func
-
+
# All of the rest of this is the same as before
new_func = MediumLevelILFunction(old_func.arch, low_level_il=context.llil)
new_func.prepare_to_copy_function(old_func)
@@ -426,15 +426,15 @@ Due to limitations currently in the Python bindings, IL mappings will only updat
```C++
// previous code ...
-
+
// Need to commit this for mappings to work (as of 5.1 at least)
context->SetMediumLevelILFunction(new_func);
-
+
// Now we want to modify the function again...
-
+
// The newly created function is now our "old function"
oldFunc = newFunc;
-
+
// All of the rest of this is the same as before
Ref<MediumLevelILFunction> newFunc = new MediumLevelILFunction(
oldFunc->GetArchitecture(),
@@ -471,11 +471,11 @@ Simply call `*LevelILFunction.get_label_for_source_instruction` (C++: `*LevelILF
new_func = MediumLevelILFunction(old_func.arch, low_level_il=context.llil)
# Calling prepare_to_copy_function creates labels in new_func
- # for all blocks in old_func, accessible via get_label_for_source_instruction
+ # for all blocks in old_func, accessible via get_label_for_source_instruction
new_func.prepare_to_copy_function(old_func)
for old_block in old_func.basic_blocks:
- # Calling prepare_to_copy_block populates the labels created by
+ # Calling prepare_to_copy_block populates the labels created by
# prepare_to_copy_function above.
new_func.prepare_to_copy_block(old_block)
@@ -494,10 +494,10 @@ Simply call `*LevelILFunction.get_label_for_source_instruction` (C++: `*LevelILF
# Emit MLIL_GOTO with the label for our target instruction
new_func.append(new_func.goto(label, ILSourceLocation.from_instruction(old_instr)), ILSourceLocation.from_instruction(old_instr))
continue
-
+
# Otherwise, copy the instruction as-is
new_func.append(old_instr.copy_to(new_func), ILSourceLocation.from_instruction(old_instr))
-
+
# Rest of function...
new_func.finalize()
new_func.generate_ssa_form()
@@ -518,12 +518,12 @@ Simply call `*LevelILFunction.get_label_for_source_instruction` (C++: `*LevelILF
);
// Calling PrepareToCopyFunction creates labels in newFunc
- // for all blocks in oldFunc, accessible via GetLabelForSourceInstruction
+ // for all blocks in oldFunc, accessible via GetLabelForSourceInstruction
newFunc->PrepareToCopyFunction(oldFunc);
-
+
for (auto& oldBlock: oldFunc->GetBasicBlocks())
{
- // Calling PrepareToCopyBlock populates the labels created by
+ // Calling PrepareToCopyBlock populates the labels created by
// PrepareToCopyFunction above.
newFunc->PrepareToCopyBlock(oldBlock);
@@ -540,21 +540,22 @@ Simply call `*LevelILFunction.get_label_for_source_instruction` (C++: `*LevelILF
// If the target is something else, see the section below.
auto oldTarget = indexOfSomeInstructionAtStartOfBlockInOldFunc;
BNMediumLevelILLabel* label = newFunc->GetLabelForSourceInstruction(oldTarget);
-
+
// Emit MLIL_GOTO with the label for our target instruction
newFunc->AddInstruction(newFunc->Goto(*label, oldInstr), oldInstr);
continue;
}
-
+
// Otherwise, copy the instruction as-is
newFunc->AddInstruction(oldInstr.CopyTo(newFunc), oldInstr);
}
}
-
+
// Rest of function...
newFunc->Finalize();
newFunc->GenerateSSAForm();
// ...
+ }
```
#### Jumping to New Blocks
@@ -574,7 +575,7 @@ If you want to have a `*LIL_GOTO` instruction target the middle of an existing *
4. Mark the label for your target
5. Now emit your target instruction and the rest of the block
-As mentioned previously, make sure to re-use the same `*LevelILLabel` object for your target in the call to `*LevelILFunction.goto`, `*LevelILFunction.mark_label`, and any other `*LIL_GOTO` instructions pointing at your target.
+As mentioned previously, make sure to re-use the same `*LevelILLabel` object for your target in the call to `*LevelILFunction.goto`, `*LevelILFunction.mark_label`, and any other `*LIL_GOTO` instructions pointing at your target.
## Useful Tools
@@ -642,9 +643,9 @@ Compare this to `current_il_instruction`, which only gives you the top-level ins
### IL Sidebar
Included in the [BN Inspectors plugin](https://github.com/CouleeApps/bn_inspectors) is a sidebar that lists all IL Expressions and IL Instructions.
-It shows you all the expressions' and instructions' indices in a big table, making it easier to determine where things are located.
+It shows you all the expressions' and instructions' indices in a big table, making it easier to determine where things are located.
It can be quite useful for determining the raw operand values of various expressions and finding dangling expressions that get lost after particularly messy calls to `replace_expr`.
-It also shows what types the expressions have (MLIL and higher).
+It also shows what types the expressions have (MLIL and higher).
![img](../img/il_inspector.png)
@@ -661,15 +662,15 @@ current_function.request_debug_report("my_report")
In your Activity, you can check for one of these requests and then, if detected, generate a Debug Report and present it to the user:
=== "Python"
-
+
```py
def rewrite_action(context: AnalysisContext):
report = None
if context.function.check_for_debug_report("my_report"):
report = ReportCollection()
-
+
# ... do changes and build report
-
+
if report is not None:
show_report_collection("My Debug Report", report)
```
@@ -684,9 +685,9 @@ In your Activity, you can check for one of these requests and then, if detected,
{
report = new ReportCollection();
}
-
+
// ... do changes and build report
-
+
if (report)
{
ShowReportCollection("My Debug Report", report);
@@ -697,13 +698,13 @@ In your Activity, you can check for one of these requests and then, if detected,
It can be exceedingly helpful to put your entire modification script inside a `try` block and present the report even on failure:
=== "Python"
-
+
```py
def rewrite_action(context: AnalysisContext):
report = None
if context.function.check_for_debug_report("my_report"):
report = ReportCollection()
-
+
try:
# ... do changes and build report
# and if this throws an exception, the report will be presented anyway,
@@ -715,7 +716,7 @@ It can be exceedingly helpful to put your entire modification script inside a `t
```
=== "C++"
-
+
```C++
void RewriteAction(Ref<AnalysisContext> context)
{
@@ -724,7 +725,7 @@ It can be exceedingly helpful to put your entire modification script inside a `t
{
report = new ReportCollection();
}
-
+
try
{
// ... do changes and build report
@@ -744,7 +745,7 @@ It can be exceedingly helpful to put your entire modification script inside a `t
}
// Rethrowing the exception here might abort the program (if it is uncaught)
- // So you probably want to just eat the exception and print an angry message
+ // So you probably want to just eat the exception and print an angry message
LogErrorWithStackTraceF("Got an exception"); // 5.2 and later
// throw;
}
@@ -753,7 +754,7 @@ It can be exceedingly helpful to put your entire modification script inside a `t
Then, you can build up the `ReportCollection` object by adding reports to it with the various Report APIs.
-**Note:** If you are making function graphs using the various `create_graph` APIs, make sure to use `create_graph_immediate` as it will construct the graph from the function as it existed when called, instead of lazily once the view is rendered (otherwise you will only see the end state of the function).
+**Note:** If you are making function graphs using the various `create_graph` APIs, make sure to use `create_graph_immediate` as it will construct the graph from the function as it existed when called, instead of lazily once the view is rendered (otherwise you will only see the end state of the function).
=== "Python"
@@ -761,10 +762,10 @@ Then, you can build up the `ReportCollection` object by adding reports to it wit
# For ReportCollection, create graph with the settings I want
settings = DisassemblySettings()
settings.set_option(DisassemblyOption.ShowAddress, True)
-
+
# Create graph *immediate* from the function
graph = old_func.create_graph_immediate(settings=settings)
-
+
# And add it to my debug report
report.append(FlowGraphReport("Initial", graph, context.view))
```
@@ -778,7 +779,7 @@ Then, you can build up the `ReportCollection` object by adding reports to it wit
// Create graph *immediate* from the function
auto graph = oldFunc->CreateFunctionGraphImmediate(settings);
-
+
// And add it to my debug report
report->AddGraphReport(context->GetBinaryView(), "Initial", graph);
```
@@ -786,20 +787,20 @@ Then, you can build up the `ReportCollection` object by adding reports to it wit
You can also use the various graph APIs to style the report and highlight nodes or instructions:
=== "Python"
-
+
```py
graph = old_func.create_graph_immediate(settings=settings)
-
+
# Go through the nodes in the graph and highlight some of them
for node in graph.nodes:
if some_condition:
node.highlight = HighlightStandardColor.RedHighlightColor
if other_condition:
node.highlight = HighlightStandardColor.GreenHighlightColor
-
+
# Update the graph with the highlighted node
graph.replace(node_index, node)
-
+
# And then you can add as normal
report.append(FlowGraphReport("Graph with Highlights", graph, context.view))
```
@@ -824,7 +825,7 @@ You can also use the various graph APIs to style the report and highlight nodes
}
auto graph = oldFunc->CreateFunctionGraphImmediate(settings);
-
+
// Go through the nodes in the graph and highlight some of them
auto nodes = graph->GetNodes();
for (size_t i = 0; i < nodes.size(); i++)
@@ -841,7 +842,7 @@ You can also use the various graph APIs to style the report and highlight nodes
// Update the graph with the highlighted node
graph->ReplaceNode(i, node);
}
-
+
// And then you can add as normal
report->AddGraphReport(context->GetBinaryView(), "Initial", graph);
```
@@ -852,31 +853,31 @@ You can also use the various graph APIs to style the report and highlight nodes
Due to the nature of Workflows, a custom Debug Report is only able to be triggered if your Activity gets run.
But what if you don't want to apply your changes yet?
This might be because you suspect your changes are buggy, or so you can introspect the unchanged function while still seeing diagnostics from your changes.
-Either way, sometimes it is helpful to have a variant of your Activity that does all of the logic _except_ for applying the updated analysis.
+Either way, sometimes it is helpful to have a variant of your Activity that does all the logic _except_ for applying the updated analysis.
There's no built-in solution for this, but you can model it pretty effectively by having two activities and a Dry Run switch.
First, modify your Activity function with another parameter for if this is a dry run:
=== "Python"
-
+
```py
def rewrite_action(context: AnalysisContext, dry_run: bool):
# ... logic here
- new_func = ...
-
+ new_func = ...
+
# Only update analysis if this is NOT a dry run
if not dry_run:
context.mlil = new_func
```
=== "C++"
-
+
```c++
void RewriteAction(Ref<AnalysisContext> context, bool dryRun)
{
// ... logic here
- auto newFunc = ...;
-
+ auto newFunc = ...;
+
// Only update analysis if this is NOT a dry run
if (!dryRun)
{
@@ -888,11 +889,11 @@ First, modify your Activity function with another parameter for if this is a dry
Then, when registering your Workflow Activity, make two copies of the Activity, having one be for the dry run:
=== "Python"
-
+
```py
# Workflow setup boilerplate
wf = Workflow("core.function.metaAnalysis").clone("core.function.metaAnalysis")
-
+
# Define your activity twice, once as a "dry run" enabled by default
wf.register_activity(Activity(
configuration=json.dumps({
@@ -907,7 +908,7 @@ Then, when registering your Workflow Activity, make two copies of the Activity,
}),
action=lambda context: rewrite_action(context, True) # Dry run
))
-
+
# ... and one that will actually apply changes, disabled by default
wf.register_activity(Activity(
configuration=json.dumps({
@@ -930,7 +931,7 @@ Then, when registering your Workflow Activity, make two copies of the Activity,
```c++
// Workflow setup boilerplate
auto wf = Workflow::Instance("core.function.metaAnalysis")->Clone("core.function.metaAnalysis");
-
+
// Define your activity twice, once as a "dry run" enabled by default
wf->RegisterActivity(new Activity(R"~(
{
@@ -946,7 +947,7 @@ Then, when registering your Workflow Activity, make two copies of the Activity,
)~", [](Ref<AnalysisContext> context) {
RewriteAction(context, true); // Dry run
}));
-
+
// ... and one that will actually apply changes, disabled by default
wf->RegisterActivity(new Activity(R"~(
{
@@ -970,7 +971,7 @@ Finally, insert both actions into the workflow at the same place.
Insert the dry run first, so that, even if the real action is enabled, the dry run still runs on the unchanged state.
=== "Python"
-
+
```py
wf.insert_after("core.function.generateMediumLevelIL", [
"extension.my_extension.do_the_thing.dry_run",
diff --git a/docs/dev/bnil-overview.md b/docs/dev/bnil-overview.md
index fd56d5d9..3903519f 100644
--- a/docs/dev/bnil-overview.md
+++ b/docs/dev/bnil-overview.md
@@ -1,6 +1,6 @@
# Binary Ninja Intermediate Language: Overview
-The Binary Ninja Intermediate Language (BNIL) is a semantic representation of the assembly language instructions for a native architecture in Binary Ninja. BNIL is actually a family of intermediate languages that work together to provide functionality at different abstraction layers.
+The Binary Ninja Intermediate Language (BNIL) is a semantic representation of the assembly language instructions for a native architecture in Binary Ninja. BNIL is actually a family of intermediate languages that work together to provide functionality at different abstraction layers.
BNIL is a [tree-based](https://raw.githubusercontent.com/withzombies/bnil-graph/master/images/graph.png), architecture-independent intermediate representation of machine code used throughout Binary Ninja.
@@ -16,7 +16,7 @@ This short introduction is a very brief guide to BNIL with much more details in
## Summary
-While the image above shows a bit of the logical relationships between each IL in terms of analysis, it's only an approximation. The actual analysis includes more edges than just those shown. That said, here's a short overview of some of the differences between each IL and when you might wish to use a given one:
+While the image above shows a bit of the logical relationships between each IL in terms of analysis, it's only an approximation. The actual analysis includes more edges than just those shown. That said, here's a short overview of some differences between each IL and when you might wish to use a given one:
- Lifted IL is intended to be a straight-forward translation from native instruction semantics to LLIL instructions. Note that Lifted IL and LLIL share the same instructions and are substantively similar with a few small differences.
- Low Level IL (LLIL) is converted from Lifted IL, LLIL removes NOP instructions and folds flags into conditional instructions but otherwise contains the same operations as Lifted IL.
@@ -29,7 +29,7 @@ While the image above shows a bit of the logical relationships between each IL i
## Reading IL
-All of the various ILs (with the exception of the SSA forms) are intended to be easily human-readable and look much like pseudo-code. There is some shorthand notation that is used throughout the ILs, though, explained below:
+All the various ILs (except the SSA forms) are intended to be easily human-readable and look much like pseudocode. There is some shorthand notation that is used throughout the ILs, though, explained below:
### Comparisons
@@ -97,7 +97,7 @@ It represents the lower 32-bits of variable `rax_2`, sign-extended into a 64-bit
## Using the API with ILs
-When you want to use the API to access BNIL instructions, here are a few tips that will help you with the task. First, if you want to learn what properties different instructions have, instead of manually using `dir()` or looking in the documentation ([1](https://docs.binary.ninja/dev/bnil-llil.html#the-instructions), [2](https://docs.binary.ninja/dev/bnil-mlil.html#the-instruction-set)) lists is to use the [BNIL Graph](https://github.com/Vector35/community-plugins#:~:text=BNIL%20Instruction%20Graph) plugin. Another very useful plugin is the [IL Hierarch](https://github.com/Vector35/community-plugins#:~:text=into%20Binary%20Ninja.-,ilhierarchy,-Fabian%20Freyer) plugin. This plugin is extremely useful for showing the _structure_ of IL instructions relative to one another. You can use several APIS ([1](https://api.binary.ninja/binaryninja.lowlevelil-module.html#binaryninja.lowlevelil.LowLevelILInstruction.show_llil_hierarchy), [2](https://api.binary.ninja/binaryninja.mediumlevelil-module.html#binaryninja.mediumlevelil.MediumLevelILInstruction.show_mlil_hierarchy), [3](https://api.binary.ninja/binaryninja.highlevelil-module.html#binaryninja.highlevelil.HighLevelILInstruction.show_hlil_hierarchy)) to see this overall structure, but the IL Hierarchy plugin lets you select a single IL instructions and see visually which categories of IL instructions it are in.
+When you want to use the API to access BNIL instructions, here are a few tips that will help you with the task. First, if you want to learn what properties different instructions have, instead of manually using `dir()` or looking in the documentation ([1](https://docs.binary.ninja/dev/bnil-llil.html#the-instructions), [2](https://docs.binary.ninja/dev/bnil-mlil.html#the-instruction-set)) lists is to use the [BNIL Graph](https://github.com/Vector35/community-plugins#:~:text=BNIL%20Instruction%20Graph) plugin. Another very useful plugin is the [IL Hierarch](https://github.com/Vector35/community-plugins#:~:text=into%20Binary%20Ninja.-,ilhierarchy,-Fabian%20Freyer) plugin. This plugin is extremely useful for showing the _structure_ of IL instructions relative to one another. You can use several APIs ([1](https://api.binary.ninja/binaryninja.lowlevelil-module.html#binaryninja.lowlevelil.LowLevelILInstruction.show_llil_hierarchy), [2](https://api.binary.ninja/binaryninja.mediumlevelil-module.html#binaryninja.mediumlevelil.MediumLevelILInstruction.show_mlil_hierarchy), [3](https://api.binary.ninja/binaryninja.highlevelil-module.html#binaryninja.highlevelil.HighLevelILInstruction.show_hlil_hierarchy)) to see this overall structure, but the IL Hierarchy plugin lets you select a single IL instruction and see visually which categories of IL instructions it is in.
![LLIL Hierarchy](../img/llil-hierarchy.png)
@@ -115,9 +115,9 @@ Here's what that instruction might look like when selected with the IL Hierarchy
![HLIL Hierarchy Call Instruction](../img/hlil-hierarchy-call.png)
-Be warned though! HLIL in particular is very tree-based. LLIL and MLIL are much safer to use the above paradigm of simply iterating through top-level instructions.
+Be warned though! HLIL in particular is very tree-based. LLIL and MLIL are much safer to use the above paradigm of simply iterating through top-level instructions.
-Make sure to also check out the specifics of each IL level for more details: [LLIL](bnil-llil.md), [MLIL](bnil-mlil.md), [HLIL](bnil-hlil.md)
+Make sure to also check out the specifics of each IL level for more details: [LLIL](bnil-llil.md), [MLIL](bnil-mlil.md), [HLIL](bnil-hlil.md)
## Visitors
@@ -139,7 +139,7 @@ The visitor receives 4 operands:
... match inst:
... case Arithmetic(right=Constant()):
... print(f"{inst.address:#x} {inst}")
-...
+...
>>> current_hlil.root.visit(visitor)
0x4012a0 arg1 + 0x1404
0x4012b0 edx_1 u>> 3
diff --git a/docs/dev/concepts.md b/docs/dev/concepts.md
index 376f485b..8e70dba7 100644
--- a/docs/dev/concepts.md
+++ b/docs/dev/concepts.md
@@ -16,7 +16,7 @@ When you are interacting in the UI with an executable file, you can access `bv`
???+ Info "Tip"
Note the use of `bv` here as a shortcut to the currently open BinaryView. For other "magic" variables, see the [user guide](../guide/index.md#magic-console-variables)
-If you want to start writing a plugin, most top-level methods will exist off of the BinaryView. Conceptually, you can think about the organization as a hierarchy starting with a BinaryView, then functions, then basic blocks, then instructions. There are of course lots of other ways to access parts of the binary but this is the most common organization. Check out the tab completion in the scripting console for `bv.get<TAB>` for example (a common prefix for many APIs):
+If you want to start writing a plugin, most top-level methods will exist off of the BinaryView. Conceptually, you can think about the organization as a hierarchy starting with a BinaryView, then functions, then basic blocks, then instructions. There are of course lots of other ways to access parts of the binary, but this is the most common organization. Check out the tab completion in the scripting console for `bv.get<TAB>` for example (a common prefix for many APIs):
![Tab Completion ><](../img/getcompletion.png "Tab Completion")
@@ -24,7 +24,7 @@ Some BinaryViews have parent views. The view used for decompilation includes mem
## REPL versus Scripts
-When you're interacting with the Binary Ninja [scripting console](../guide/index.md#script-python-console), it's important to realize that every time you run a command, the UI is automatically going to update analysis. You can see this by even running a simply command like:
+When you're interacting with the Binary Ninja [scripting console](../guide/index.md#script-python-console), it's important to realize that every time you run a command, the UI is automatically going to update analysis. You can see this by even running a simple command like:
```
print("test")
@@ -36,17 +36,17 @@ To achieve the same results when writing a stand-alone plugin, you'd need to use
Another difference in the REPL / scripting console is that the scripting console is not executing on the main thread. This means that if you wish to interact with the UI via QT or BN UI APIs from the console (for example, to [trigger an action via string](https://gist.github.com/psifertex/6fbc7532f536775194edd26290892ef7#file-trigger_actions-py)), you'd need to use [`mainthread.execute_on_main_thread_and_wait()`](https://api.binary.ninja/binaryninja.mainthread-module.html#binaryninja.mainthread.execute_on_main_thread_and_wait) or similar.
-![Scriping Console ><](../img/console.png "Python Scripting Console")
+![Scripting Console ><](../img/console.png "Python Scripting Console")
## Auto vs User
-In the Binary Ninja API, there are often two parallel sets of functions with `_auto_` and `_user_` in their names. For example: [add_user_segment](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.add_user_segment) and [add_auto_segment](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.add_auto_segment). So what's the difference? Auto functions are those that are expected to be run _automatically_, every time the file is loaded. So for example, if you're writing a [custom file loader](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/nsf.py) that will parse a particular binary format, you would use `_auto_` functions because each time the file is opened your loader will be used. The results of auto functions are saved in a `.bndb` database, but will be cleared if re-running auto-analysis (which happens when updating the version of the database due to updating Binary Ninja in some instances). This is because it's expected that whatever produced them originally will again when the file is re-analyzed (you can use the [`analysis.database.suppressReanalysis`](../guide/settings.md#analysis.database.suppressReanalysis) setting to avoid this, but it's generally discouraged). This means that even if you're writing a plugin to make changes on a file during analysis, you likely want to use the `_user_` set of APIs so that the changes your plugin causes will separately be saved to the database as if they were done by a user. User actions are also added to the undo serialization and can be undone by the user which is not true of auto actions.
+In the Binary Ninja API, there are often two parallel sets of functions with `_auto_` and `_user_` in their names. For example: [add_user_segment](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.add_user_segment) and [add_auto_segment](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.add_auto_segment). So what's the difference? Auto functions are those that are expected to be run _automatically_, every time the file is loaded. So for example, if you're writing a [custom file loader](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/nsf.py) that will parse a particular binary format, you would use `_auto_` functions because each time the file is opened your loader will be used. The results of auto functions are saved in a `.bndb` database, but will be cleared if re-running auto-analysis (which happens when updating the version of the database due to updating Binary Ninja in some instances). This is because it's expected that whatever produced them originally will again when the file is re-analyzed (you can use the [`analysis.database.suppressReanalysis`](../guide/settings.md#analysis.database.suppressReanalysis) setting to avoid this, but it's generally discouraged). This means that even if you're writing a plugin to make changes on a file during analysis, you likely want to use the `_user_` set of APIs so that the changes your plugin causes will separately be saved to the database as if they were done by a user. User actions are also added to the undo serialization and can be undone by the user which is not true of auto actions.
## Concepts for ILs
### Walking ILs
-Because our ILs are tree-based, some naive plugins that walk IL looking for specific operations will miss instructions that are part of nested expressions. While there is generally less folding in [MLIL](https://docs.binary.ninja/dev/bnil-mlil.html), making it better target for simple loops like:
+Because our ILs are tree-based, some naive plugins that walk IL looking for specific operations will miss instructions that are part of nested expressions. While there is generally less folding in [MLIL](https://docs.binary.ninja/dev/bnil-mlil.html), making it the better target for simple loops like:
```python
for i in bv.mlil_instructions:
@@ -54,7 +54,7 @@ for i in bv.mlil_instructions:
print(i.params)
```
-it's still possible to miss instructions with this approach. Additionally, in HLIL it's even easier to miss instructions as there is significantly more nesting. Accordingly we created [`traverse`](https://api.binary.ninja/binaryninja.highlevelil-module.html#binaryninja.highlevelil.HighLevelILFunction.traverse) APIs to walk these tree-based ILs and match whatever property you're interested in. Here are several examples:
+it's still possible to miss instructions with this approach. Additionally, in HLIL it's even easier to miss instructions as there is significantly more nesting. Accordingly, we created [`traverse`](https://api.binary.ninja/binaryninja.highlevelil-module.html#binaryninja.highlevelil.HighLevelILFunction.traverse) APIs to walk these tree-based ILs and match whatever property you're interested in. Here are several examples:
```python
def find_strcpy(i, t) -> str:
@@ -70,7 +70,7 @@ t = [
# Find the first call to a builtin:
for result in current_hlil.traverse(find_strcpy, t):
# Any logic should live here, not inside the callable which is just for
- # matching. Because this is a generator, it can fail fast when used for
+ # matching. Because this is a generator, it can fail fast when used for
# search!
print(result)
break
@@ -153,11 +153,11 @@ It is easy to confuse ExpressionIndex and InstructionIndex properties in the API
Our [BNIL Overview](bnil-overview.md) mentions Static Single Assignment (SSA) without explaining what it is. You can of course always check out [Wikipedia](https://en.wikipedia.org/wiki/Static_single-assignment_form), but here's a quick summary of what it is, why we expose multiple SSA forms of our ILs and how you can use it to improve your plugin writing with BNIL.
-At it's simplest, SSA forms of an Intermediate Language or Intermediate Representation are those in which variables are read only. They can be set when created, but not modified. Instead of modifying them, when you make a change, a new "version" of the variable is created denoting that the value has changed in some way. While this certainly makes the form less readable to humans, this means it's actually really easy to walk back and see how a variable has been modified by simply looking at the definition site for a given variable or all possible versions before it. Any time the variable is modified, a new version of that variable will be created (you'll see `#` followed by a number indicating that this is a new version).
+At it's simplest, SSA forms of an Intermediate Language or Intermediate Representation are those in which variables are read only. They can be set when created, but not modified. Instead of modifying them, when you make a change, a new "version" of the variable is created denoting that the value has changed in some way. While this certainly makes the form less readable to humans, this means it's actually really easy to walk back and see how a variable has been modified by simply looking at the definition site for a given variable or all possible versions before it. Any time the variable is modified, a new version of that variable will be created (you'll see `#` followed by a number indicating that this is a new version).
But what if the code takes multiple paths and could have different values depending on the path that was taken? SSA forms use a `Φ` (pronounced either as "fee" or "fi" like "fly" depending on which mathematician or Greek speaker you ask!) function to solve this ambiguity. All a `Φ` function does is aggregate different versions of a variable when entering a basic block with multiple paths. So a basic block with two incoming edges where `eax` is modified might have something like: `eax#3 = Φ(eax#1, eax#2)` denoting that the new version of the variable could have come from either of those sources.
-Binary Ninja uses this capability internally for its own value set analysis and constant dataflow propagation but plugins can also leverage this information to great effect. For example, want to find an uninitialized value? Simply look for an SSA variable being read from with a version of zero that isn't in the list of arguments to the function. Want to implement your own inter-procedural data-flow system? Binary Ninja does not for performance reasons, but in instances where you can prevent the state space explosion problem, you can build on top of the existing SSA forms to implement exactly this. A simple example might look for vulnerable function calls like printf() where the first argument is user-data. While most trivial cases of this type of flaw tend to be found quickly, it's often the case that subtler versions with functions that wrap functions that wrap functions that call a printf with user data are more tedious to identify. However, using an SSA-based script, it's super easy to see that, for example, the first parameter to a `printf` call originated in a calling function as the second parameter, and THAT function was called with input that came directly from some sort of user input. While one or two layers might be easy to check by hand with few cross-references, with a large embedded firmware, there might be hundreds or thousands of potential locations to check out, and a script using SSA can dramatically reduce the number of cases to investigate.
+Binary Ninja uses this capability internally for its own value set analysis and constant dataflow propagation but plugins can also leverage this information to great effect. For example, want to find an uninitialized value? Simply look for an SSA variable being read from with a version of zero that isn't in the list of arguments to the function. Want to implement your own inter-procedural data-flow system? Binary Ninja does not for performance reasons, but in instances where you can prevent the state space explosion problem, you can build on top of the existing SSA forms to implement exactly this. A simple example might look for vulnerable function calls like `printf()` where the first argument is user-data. While most trivial cases of this type of flaw tend to be found quickly, it's often the case that subtler versions with functions that wrap functions that wrap functions that call a `printf` with user data are more tedious to identify. However, using an SSA-based script, it's super easy to see that, for example, the first parameter to a `printf` call originated in a calling function as the second parameter, and THAT function was called with input that came directly from some sort of user input. While one or two layers might be easy to check by hand with few cross-references, with a large embedded firmware, there might be hundreds or thousands of potential locations to check out, and a script using SSA can dramatically reduce the number of cases to investigate.
### When IL APIs Return None
@@ -195,11 +195,11 @@ Binary Ninja utilizes two distinct data flow systems that are influenced by memo
The distinction between readable and writable values affects how data flow analysis is performed:
- **Readable Values:** Variables marked as readable are analyzed primarily for the flow of data without modification, aiding in tracking data dependencies.
-- **Writable Values:** Writable variables are treated as mutable and thus no assumptions are made about the values being the same in a given function.
+- **Writable Values:** Writable variables are treated as mutable and thus no assumptions are made about the values being the same in a given function.
By overriding variable annotations or memory flags, you can alter Binary Ninja's assumptions about data:
-- Marking a writable variable as **`const`** forces the analysis to treat its value as immutable, potentially simplifying the data flow but risking misinterpretation if the assumption is incorrect.
+- Marking a writable variable as **`const`** forces the analysis to treat its value as immutable, potentially simplifying the data flow but risking misinterpretation if the assumption is incorrect.
- Marking a constant variable as **`volatile`** forces the analysis to treat its value as mutable, safeguarding against data flow making assumptions about the value, this is particularly useful when dealing with data variables in sections marked with [ReadOnlyDataSectionSemantics](https://api.binary.ninja/binaryninja.enums-module.html#binaryninja.enums.SectionSemantics).
## Permissions Impact on Linear Sweep
@@ -214,7 +214,7 @@ By modifying memory permissions, you can guide Binary Ninja's linear sweep analy
## UI Elements
-There are several ways to create UI elements in Binary Ninja. The first is to use the simplified [interaction](https://api.binary.ninja/binaryninja.interaction-module.html) API which lets you make simple UI elements for use in GUI plugins in Binary Ninja. As an added bonus, they all have fallbacks that will work in headless console-based applications as well. Plugins that use these API include the [angr](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/angr_plugin.py) and [nampa](https://github.com/kenoph/nampa) plugins.
+There are several ways to create UI elements in Binary Ninja. The first is to use the simplified [interaction](https://api.binary.ninja/binaryninja.interaction-module.html) API which lets you make simple UI elements for use in GUI plugins in Binary Ninja. As an added bonus, they all have fallbacks that will work in headless console-based applications as well. Plugins that use these APIs include the [angr](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/angr_plugin.py) and [nampa](https://github.com/kenoph/nampa) plugins.
The second and more powerful (but more complicated) mechanism is to leverage the _binaryninjaui_ module. Additional documentation is forthcoming, but there are several examples ([1](https://github.com/Vector35/kaitai), [2](https://github.com/Vector35/snippets), [3](https://github.com/Vector35/binaryninja-api/tree/dev/python/examples/triage)), and most of the APIs are backed by the [documented C++ headers](https://api.binary.ninja/cpp). Additionally, the generated _binaryninjaui_ module is shipped with each build of binaryninja and the usual python `dir()` instructions are helpful for exploring its capabilities.
@@ -226,21 +226,21 @@ When calling native UI methods, please make sure to use the [execute_on_main_thr
One of the common questions asked of a binary analysis platform is "how big is a function?". This is a deceptively simple question without a simple answer. There are rather several equally valid definitions you could give for what is the size of a function:
- - the total sum of all basic blocks?
- - the highest virtual address in the function minus the lowest virtual address?
- - the address of return instruction subtracted from the entry point
+ - The total sum of all basic blocks?
+ - The highest virtual address in the function minus the lowest virtual address?
+ - The address of return instruction subtracted from the entry point
-Except that last one is a trick of course. Because not only can functions have multiple return instructions, but they may have multiple entry points (as is often the case with error handling).
+Except that last one is a trick of course. Because not only can functions have multiple return instructions, but they may have multiple entry points (as is often the case with error handling).
-Basic blocks have, by definition, a start, and an end. Basic Blocks can therefore have consistent sizes that all binary analysis tools would agree upon (though more formal analysis might stop basic blocks on call instructions while for convenience sake, most reverse engineering tools do not).
+Basic blocks have, by definition, a start, and an end. Basic Blocks can therefore have consistent sizes that all binary analysis tools would agree upon (though more formal analysis might stop basic blocks on call instructions while for convenience's sake, most reverse engineering tools do not).
-Summing up the basic blocks of a function is one way to produce a consistent size for a function, but how do you handle bytes that overlap standard function definitions, for example, via a tail call? Or via a mis-aligned jump where a byte is in two basic blocks? Different tools may resolve those ambiguous situations in different ways, so again, it is difficult to compare the "size" of any one binary analysis tool to another.
+Summing up the basic blocks of a function is one way to produce a consistent size for a function, but how do you handle bytes that overlap standard function definitions, for example, via a tail call? Or via a misaligned jump where a byte is in two basic blocks? Different tools may resolve those ambiguous situations in different ways, so again, it is difficult to compare the "size" of any one binary analysis tool to another.
In Binary Ninja, there is no explicit `.size` property of functions. Rather, you can choose to calculate it one of two ways:
```
function_size = current_function.total_bytes
-# or
+# or
function_size = current_function.highest_address - current_function.lowest_address
```
@@ -248,14 +248,14 @@ Total bytes is similar to the first proposed definition above. It merely sums up
### When does a Function stop?
-One reason that having an "end" might be useful in a function (as opposed to the `.highest_address` in Binary Ninja), would be to make it a property that controls the analysis for a function. Unlike some other systems where it's possible to define the start and end of a function, in Binary Ninja, you merely define the start and allow analysis to occur naturally. The end results when all basic blocks terminate either in:
+One reason that having an "end" might be useful in a function (as opposed to the `.highest_address` in Binary Ninja), would be to make it a property that controls the analysis for a function. Unlike some other systems where it's possible to define the start and end of a function, in Binary Ninja, you merely define the start and allow analysis to occur naturally. The end results when all basic blocks terminate either in:
- an invalid instruction
- a return instruction
- a call to a function marked as `__noreturn__`
- a branch to a block already in the function
- any other instruction such as an interrupt that by its definition stops analysis
-
+
So how do you tell Binary Ninja how big a function is? The answer is you don't directly, but you can instead direct its analysis. For example, if a function is improperly not marked as a noreturn function, edit the function properties via the right-click menu and set the property and all calls to it will end analysis at that point in any callees.
Likewise, you can do things like change memory permissions, patch in invalid instructions, [change an indirect branch's targets](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/jump_table.py), or use [UIDF](https://binary.ninja/2020/09/10/user-informed-dataflow.html) to influence analysis such that it ends where desired.
@@ -264,7 +264,7 @@ Likewise, you can do things like change memory permissions, patch in invalid ins
### Unicode Support
-If you're opening a file with non-ascii string encodings, make sure to use one of the "open with options" [methods](../guide/index.md#loading-files) and choose the appropriate code pages. These settings are under the `analysis` / `unicode` section of the settings dialog. If you're not sure which code page you should be enabling, consider using a library like [chardet](https://chardet.readthedocs.io/en/latest/usage.html). For example, here's a file both with and without the "CJK Unified Ideographs" block being enabled:
+If you're opening a file with non-ASCII string encodings, make sure to use one of the "open with options" [methods](../guide/index.md#loading-files) and choose the appropriate code pages. These settings are under the `analysis` / `unicode` section of the settings dialog. If you're not sure which code page you should be enabling, consider using a library like [chardet](https://chardet.readthedocs.io/en/latest/usage.html). For example, here's a file both with and without the "CJK Unified Ideographs" block being enabled:
![Sample Binary Without CJK Unified Ideographs](../img/hanyu-no-codepage.png "Sample Binary Without CJK Unified Ideographs")
@@ -272,10 +272,10 @@ If you're opening a file with non-ascii string encodings, make sure to use one o
???+ Info "Tip"
Note that there is a small bug and some string length calculations will be off with certain characters as shown above.
-
+
### Wide Strings in the UI
-Many Windows applications use wide (UTF-16 or UTF-32) strings. By default these should be identified during initial string analysis as long as the default settings are still enabled.
+Many Windows applications use wide (UTF-16 or UTF-32) strings. By default, these should be identified during initial string analysis as long as the default settings are still enabled.
![Unicode settings](../img/unicode-settings.png "Unicode Settings")
diff --git a/docs/dev/flags.md b/docs/dev/flags.md
index e87c6a2d..8474e73e 100644
--- a/docs/dev/flags.md
+++ b/docs/dev/flags.md
@@ -7,7 +7,7 @@ This guide is broken up into three sections.
- Part 3 covers advanced topics like custom roles
-## Binja Architecture Flags Part 1: The Basics
+## Binary Ninja Architecture Flags Part 1: The Basics
Think of flags as global boolean variables, set and cleared by observers who monitor the result of instructions from a distance:
@@ -28,11 +28,11 @@ flag_v = ...
Now the problem is that tons of instructions affect tons of flags, so a lot of noise is generated.
-Binja tries to reduce the noise by displaying only the flags between producer and consumer that are relevant. For example, ADD affects many flags, but if none are read until ADC (add with carry) then only the carry flag is shown.
+Binary Ninja tries to reduce the noise by displaying only the flags between producer and consumer that are relevant. For example, ADD affects many flags, but if none are read until ADC (add with carry) then only the carry flag is shown.
-Writing effective flag code in architectures requires this understanding, and there's a bit of an art in "helping" Binja connect flag producers and consumers.
+Writing effective flag code in architectures requires this understanding, and there's a bit of an art in "helping" Binary Ninja connect flag producers and consumers.
-But this is about basics! So what are the basic ways in which an architecture author informs Binja of flags? The following is python architecture code for Z80.
+But this is about basics! So what are the basic ways in which an architecture author informs Binary Ninja of flags? The following is python architecture code for Z80.
### 1) declare the flags
@@ -53,7 +53,7 @@ That's simple, it's just a list of strings.
'c': FlagRole.CarryFlagRole
}
-Map each flag to a role from [api/python/enum.py](https://api.binary.ninja/_modules/binaryninja/enums.html) if possible. This informs Binja to generate IL for the basic, textbook behavior of a flag. For example, the `ZeroFlagRole` will generate IL that sets the flag when an arithmetic result is zero.
+Map each flag to a role from [api/python/enum.py](https://api.binary.ninja/_modules/binaryninja/enums.html) if possible. This informs Binary Ninja to generate IL for the basic, textbook behavior of a flag. For example, the `ZeroFlagRole` will generate IL that sets the flag when an arithmetic result is zero.
If a flag's behavior does not fit the textbook behavior, use `SpecialFlagRole` and in a future article we'll implement a callback for its custom IL. For example, `PV` here in Z80 acts as both a parity flag and an overflow flag. It's meaning at any given time depends on the last instruction that set it.
@@ -77,13 +77,13 @@ Think of `flag_write_types` as custom named groups for your convenience. When yo
In fact, the `flag` keyword parameter for the IL constructing functions does not accept individual flag names, it accepts only these group names!
-## Binja Architecture Flags Part 2: Flag Producer/Consumer
+## Binary Ninja Architecture Flags Part 2: Flag Producer/Consumer
-In the last installment, we informed Binja of our architecture's flags by defining a list of flag names, a mapping from flag names to `flag roles`, and groups of flags commonly set together called `flag write types`.
+In the last installment, we informed Binary Ninja of our architecture's flags by defining a list of flag names, a mapping from flag names to `flag roles`, and groups of flags commonly set together called `flag write types`.
-Let's remind ourselves briefly that these are terms within an imagined protocol between architecture author and Binja. The protocol's purpose is to communicate to Binja what flags are present and how they behave. As we accumulate architectures that stretch the protocol's limits (eg: PowerPC with its flag banks), it's possible the protocol gets adjusted to more generally accommodate architectures.
+Let's remind ourselves briefly that these are terms within an imagined protocol between architecture author and Binary Ninja. The protocol's purpose is to communicate to Binary Ninja what flags are present and how they behave. As we accumulate architectures that stretch the protocol's limits (eg: PowerPC with its flag banks), it's possible the protocol gets adjusted to more generally accommodate architectures.
-In Part 1, we said Binja tries to reduce the noise in displayed IL by showing only the flags between producer and consumer that are relevant. Consider this simplified flags definition for Z80:
+In Part 1, we said Binary Ninja tries to reduce the noise in displayed IL by showing only the flags between producer and consumer that are relevant. Consider this simplified flags definition for Z80:
```python
flags = ['c']
@@ -92,7 +92,7 @@ flag_write_types = ['none', 'only_carry']
flags_written_by_flag_write_type = { 'none': [], 'only_carry': ['c'], }
```
-We have one flag named 'c', we tell Binja that it's the textbook carry flag, and we define a flag group called "only_carry" which sets just this flag.
+We have one flag named 'c', we tell Binary Ninja that it's the textbook carry flag, and we define a flag group called "only_carry" which sets just this flag.
At lifting time, we mark certain IL instructions as a **producer** using the `flags` keyword. Remember to pass the _group_ or _flag write type_ that contains `c`, **not** `c` itself:
@@ -121,7 +121,7 @@ unsigned char add(unsigned char a, unsigned char b)
Recap: the C function is named `add()` which will produce a Z80 instruction `ADD` (among others) which we lift to LLIL `ADD` that is a **producer** of the `c` flag.
-Binja gives this LLIL, after compilation with [SDCC](http://sdcc.sourceforge.net):
+Binary Ninja gives this LLIL, after compilation with [SDCC](http://sdcc.sourceforge.net):
```
_add:
@@ -137,7 +137,7 @@ _add:
WHERE'S THE CARRY!?
-This is the lesson that was non-intuitive to me. Binja knows from the architecture-supplied _lifted IL_ that `ADD` sets `c`, but it doesn't produce any `c` setting _low level_ IL because it failed to detect anyone using `c`.
+This is the lesson that was non-intuitive to me. Binary Ninja knows from the architecture-supplied _lifted IL_ that `ADD` sets `c`, but it doesn't produce any `c` setting _low level_ IL because it failed to detect anyone using `c`.
#### Example B
@@ -173,7 +173,7 @@ _add:
16 @ 00000225 <return> jump(pop)
```
-With `ADC` present, Binja detects the relationship, and produces the IL `flag:c = temp0.b + temp1.b u< temp0.b`.
+With `ADC` present, Binary Ninja detects the relationship, and produces the IL `flag:c = temp0.b + temp1.b u< temp0.b`.
This also means that you can mark instructions as producers of a group of many flags, and LLIL will contain the flag calculating code for those flags consumed further along.
@@ -181,18 +181,18 @@ This also means that you can mark instructions as producers of a group of many f
You, the architecture author:
-* inform Binja of your architecture's flags by defining:
+* inform Binary Ninja of your architecture's flags by defining:
* flag names
* flag "roles" which are just their textbook behavior, if they qualify
* flag "write types" which groups of flags often set together
* assign instructions as flag **producers** by passing `flag=` keyword parameter during lifting
* assign instructions as flag **consumers** by passing IL flag expressions as operands during lifting
-With the defined variables and lifted IL, Binja decides when to generate flag-affecting low level IL.
+With the defined variables and lifted IL, Binary Ninja decides when to generate flag-affecting low level IL.
-## Binja Architecture Flags Part 3: Flag Roles
+## Binary Ninja Architecture Flags Part 3: Flag Roles
-The previous sections said that flag roles were the textbook behavior of flags. If you can assign a flag to a role, there's a chance Binja will have that default behavior and you won't have to implement it yourself. For example, the carry flag is so common among architectures and its behavior is (to my knowledge) non-varying during addition, that we have it hardcoded into Binja:
+The previous sections said that flag roles were the textbook behavior of flags. If you can assign a flag to a role, there's a chance Binary Ninja will have that default behavior and you won't have to implement it yourself. For example, the carry flag is so common among architectures and its behavior is (to my knowledge) non-varying during addition, that we have it hard-coded into Binary Ninja:
```
5 @ 0000021b temp0.b = A
@@ -201,9 +201,9 @@ The previous sections said that flag roles were the textbook behavior of flags.
8 @ 0000021b flag:c = temp0.b + temp1.b u< temp0.b <-- HERE
```
-The `c` flag was declared to have CarryFlagRole so the `flag:c = ...` was produced by Binja and the architecture author is not responsible.
+The `c` flag was declared to have CarryFlagRole so the `flag:c = ...` was produced by Binary Ninja and the architecture author is not responsible.
-The hardcoded flag code is in the `get_flag_write_low_level_il()` method of the Architecture class and (at the time of this writing) supports:
+The hard-coded flag code is in the `get_flag_write_low_level_il()` method of the Architecture class and (at the time of this writing) supports:
| | ADD | ADC | SUB | NEG | FSUB | OTHERS |
| -------------------- | ---- | ---- | ---- | ---- | ---- | ------ |
@@ -215,9 +215,9 @@ The hardcoded flag code is in the `get_flag_write_low_level_il()` method of the
| UnorderedFlagRole | | | | | yes | |
| ZeroFlagRole | yes | yes | yes | yes | yes | yes |
-If a cell has "yes" it means that for the instruction at the column header, there's an built-in **attempt** at producing the flag in the row. It is not a guarantee that the flag semantics match your architecture's.
+If a cell has "yes" it means that for the instruction at the column header, there's a built-in **attempt** at producing the flag in the row. It is not a guarantee that the flag semantics match your architecture's.
-So for any instructions that are not ADD, ADC, SUB, NEG, or FSUB, you can try and see if Binja's built-in for calculating negative, positive, or zero flags are accurate for your architecture. If you want carry, ordered, overflow, or unordered, you will need to implement it yourself.
+So for any instructions that are not ADD, ADC, SUB, NEG, or FSUB, you can try and see if Binary Ninja's built-in for calculating negative, positive, or zero flags are accurate for your architecture. If you want carry, ordered, overflow, or unordered, you will need to implement it yourself.
What happens when you mark an instruction the producer of a certain flag, but no implementation exists?
@@ -229,9 +229,9 @@ What happens when you mark an instruction the producer of a certain flag, but no
Here, `sbb` is an `s` producer and a `pv` producer.
-Flag `s` is mapped to FlagRole.NegativeSignRole which is "yes" in the table, so Binja emits the default LLIL to set it.
+Flag `s` is mapped to FlagRole.NegativeSignRole which is "yes" in the table, so Binary Ninja emits the default LLIL to set it.
-Flag `pv` is mapped to FlagRole.OverflowFlagRole which is not "yes", so Binja doesn't have an implementation and emits LLIL_UNIMPLEMENTED.
+Flag `pv` is mapped to FlagRole.OverflowFlagRole which is not "yes", so Binary Ninja doesn't have an implementation and emits LLIL_UNIMPLEMENTED.
If you need to define your own flag setting code, set the flag role to SpecialFlagRole and override `get_flag_write_low_level_il()`. There are two contraints you must work around:
@@ -260,7 +260,7 @@ def get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
return il.not_expr(0, self.get_default_flag_write_low_level_il(op, size, FlagRole.CarryFlagRole, operands, il))
# Other operations use a normal carry flag
return self.get_default_flag_write_low_level_il(op, size, FlagRole.CarryFlagRole, operands, il)
- ...
+ ...
```
This is nice and convenient: the normal behavior is simply wrapped in a `not`. See [the source](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/nes.py) for the full code.
diff --git a/docs/dev/index.md b/docs/dev/index.md
index 7407d7bb..01c355a4 100644
--- a/docs/dev/index.md
+++ b/docs/dev/index.md
@@ -24,7 +24,7 @@ The Core API is designed to only be used as a shim from other languages and is n
### C++ API
-The C++ API is what the Binary Ninja UI itself is built using so it's a robust and fully feature-complete interface to the core, however, it does not have the same level of detail in the documentation.
+The C++ API is what the Binary Ninja UI itself uses, so it's a robust and fully feature-complete interface to the core, however, it does not have the same level of detail in the documentation.
- [C++ Header](https://github.com/Vector35/binaryninja-api/blob/dev/binaryninjaapi.h) (along with the rest of the [repository](https://github.com/Vector35/binaryninja-api))
- [Build Instructions](https://github.com/Vector35/binaryninja-api#building)
diff --git a/docs/dev/plugins.md b/docs/dev/plugins.md
index 5e69fd88..7f0b1901 100644
--- a/docs/dev/plugins.md
+++ b/docs/dev/plugins.md
@@ -5,13 +5,13 @@
### Creating the Plugin
-First, take a look at some of the [example](https://github.com/Vector35/binaryninja-api/tree/dev/python/examples) plugins, or some of the [community](https://github.com/Vector35/community-plugins) plugins to get a feel for different APIs you might be interested in. Of course, the full [API](https://api.binary.ninja/) docs are online and available offline via the `Help`/`Open Python API Reference...`.
+First, take a look at some [example](https://github.com/Vector35/binaryninja-api/tree/dev/python/examples) plugins, or some of the [community](https://github.com/Vector35/community-plugins) plugins to get a feel for different APIs you might be interested in. Of course, the full [API](https://api.binary.ninja/) docs are online and available offline via the `Help`/`Open Python API Reference...`.
-To start, we suggest you download the [sample plugin](https://github.com/Vector35/sample_plugin) as a template since it contains all of the elements you're likely to need.
+To start, we suggest you download the [sample plugin](https://github.com/Vector35/sample_plugin) as a template since it contains all the elements you're likely to need.
- Begin by editing the `plugin.json` file
- Next, update the `LICENSE`
-- For small scripts, you can include all the code inside of `__init__.py`, though we recommend for most larger scripts that init just act as an initializer and call into functions organized appropriately in other files.
+- For small scripts, you can include all the code inside `__init__.py`, though we recommend for larger scripts that `__init__.py` just act as an initializer and calls into functions organized appropriately in other files.
- If you have python dependencies, create a [requirements.txt](https://pip.pypa.io/en/latest/cli/pip_freeze/) listing any python dependencies.
### Submitting to the Plugin Manager
@@ -33,7 +33,7 @@ The [`add_repository`](https://api.binary.ninja/binaryninja.pluginmanager-module
### Testing
-It's useful to be able to reload your plugin during testing. On the Commercial or Ultimate editions of Binary Ninja, this is easily accomplished with a stand-alone headless install using `import binaryninja` after [installing the API](https://github.com/Vector35/binaryninja-api/blob/dev/scripts/install_api.py). (install_api.py is included in each platforms respective [installation folder](../guide/index.md#binary-path))
+It's useful to be able to reload your plugin during testing. On the Commercial or Ultimate editions of Binary Ninja, this is easily accomplished with a stand-alone headless install using `import binaryninja` after [installing the API](https://github.com/Vector35/binaryninja-api/blob/dev/scripts/install_api.py). (install_api.py is included in each platform's respective [installation folder](../guide/index.md#binary-path))
Additionally, some plugin types like Architectures or BinaryViews are only loaded at launch and cannot be reloaded during a running session.
@@ -45,7 +45,7 @@ import importlib
importlib.reload(pluginname);pluginname.callbackmethod(bv)
```
-Then just `[UP] [ENTER]` to trigger the reload when the plugin has changed.
+Then just `[UP] [ENTER]` to trigger a reload when the plugin has changed.
## Writing plugins using other IDEs (tab completion)
@@ -83,14 +83,14 @@ Binary Ninja UI plugins should always `import binaryninjaui` before an `import P
UI plugins can take many forms. Some, like [Snippets](https://github.com/vector35/snippets) create their own UI elements and interact via UIActions. Others extend the UI via existing UI elements such as [Triage](https://github.com/Vector35/binaryninja-api/tree/dev/python/examples/triage), [Kaitai](https://github.com/Vector35/kaitai), [hellosidebar](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/hellosidebar.py), or [helloglobalarea](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/helloglobalarea.py).
-Many other [third-party](https://github.com/vector35/community-plugins/) plugins also implement UI based examples, such as [BNIL Graph](https://github.com/withzombies/bnil-graph) using the FlowGraph APIs.
+Many other [third-party](https://github.com/vector35/community-plugins/) plugins also implement UI based examples, such as [BNIL Graph](https://github.com/withzombies/bnil-graph) using the FlowGraph APIs.
Unfortunately, due to a PySide documentation generation issue, the best and most reliable documentation on the UI system is not in the regular [python](https://api.binary.ninja/) API docs, but in the [C++ documentation](https://api.binary.ninja/cpp/) which translates fairly cleanly to their python equivalent.
## Writing Native Plugins
-Writing native plugins allows for higher performance code and lower level access to the Binary Ninja API, but comes with a couple more hurdles than Python.
+Writing native plugins allows for higher performance code and lower level access to the Binary Ninja API, but comes with a couple more hurdles than Python.
Notably, native plugins are built against a specific version of the API, cannot be hot-reloaded, and require more sophisticated build setups.
### Supported Toolchains
@@ -112,16 +112,16 @@ although it is recommended to use the latest version.
### Project Setup
-The first things to specify in your CMake file are a couple boilerplate options for building C++:
+The first things to specify in your CMake file are a couple boilerplate options for building C++:
# Pick whatever version you have
cmake_minimum_required(VERSION 3.24)
# Name your plugin
project(TestPlugin CXX)
-
+
set(CMAKE_CXX_STANDARD 20)
-
+
# Unless you are writing a plugin that needs Qt's UI, specify this
set(HEADLESS 1)
@@ -135,14 +135,14 @@ and reference it directly in your plugin. If you're using git, this can be accom
git submodule add https://github.com/Vector35/binaryninja-api.git binaryninjaapi
cd binaryninjaapi
# Pick the revision from api_REVISION.txt
- git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514
+ git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514
If you're not using git, you can clone the repository elsewhere:
git clone https://github.com/Vector35/binaryninja-api.git binaryninjaapi
- cd binaryninjaapi
+ cd binaryninjaapi
# Pick the revision from api_REVISION.txt
- git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514
+ git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514
Now that you have the correct copy of the api, you need to point CMake at it and include it for use.
Include something like the following in your CMake script and either add the path of your clone
@@ -162,18 +162,18 @@ Be sure to create a shared library and link against the Binary Ninja api. Also,
when you use `cmake install`.
# Use whichever sources and plugin name you want
- add_library(TestPlugin SHARED TestPlugin.cpp)
-
+ add_library(TestPlugin SHARED TestPlugin.cpp)
+
# Link with Binary Ninja
target_link_libraries(TestPlugin PUBLIC binaryninjaapi)
-
+
# Tell `cmake --install` to copy your plugin to the plugins directory
bn_install_plugin(TestPlugin)
From there you can write the rest of your plugin's CMake configuration, including any other dependencies or
options that you want. When you want to run your plugin, you can use `cmake --build` and `cmake --install`
to compile and copy your plugin to your Binary Ninja plugins directory, or set up an IDE to do that for you.
-You could also copy the plugin manually if you are using a different plugins directory location.
+You could also copy the plugin manually if you are using a different plugins directory location.
In the source code of your plugin, you will need to export some functions that Binary Ninja uses to load your plugin
at runtime:
@@ -182,7 +182,7 @@ at runtime:
extern "C" {
// Tells Binary Ninja which version of the API you compiled against
BN_DECLARE_CORE_ABI_VERSION
-
+
// Function run on plugin startup, do simple initialization here (Settings, BinaryViewTypes, etc)
BINARYNINJAPLUGIN bool CorePluginInit()
{
@@ -206,7 +206,7 @@ class, and you should only ever handle Refs or bare pointers. When in doubt, fee
### Automated GitHub CI
-Managing build infrastructure to build cross-platform native plugins can be a headache even for stables, let alone
+Managing build infrastructure to build cross-platform native plugins can be a headache even for stables, let alone
trying to track all dev releases. To help with that, we've published an [example plugin](https://github.com/Vector35/sample_plugin_cpp) that includes GitHub
actions to build on MacOS, Linux, and Windows. Combining this with something like a [plugin loader](https://github.com/rikodot/binja_native_sigscan_loader) can simplify
both publishing and using native plugins.
@@ -225,10 +225,10 @@ you can amend your CMake file to make a UI plugin. You will need the following C
# If you are using Qt MOC (i.e. use Q_OBJECT/Q_SIGNALS/Q_SLOTS)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
-
+
# Locate Qt installation for linking
find_package(Qt6 COMPONENTS Core Gui Widgets REQUIRED)
-
+
# Add MOCS to your build
add_library(TestPlugin SHARED library.cpp ${MOCS})
@@ -240,11 +240,11 @@ Then, in your plugin code, instead of using the exported functions for a core pl
#include "binaryninjaapi.h"
#include "uitypes.h"
#include "uicontext.h"
-
+
extern "C" {
// Tells Binary Ninja which version of the API you compiled against
BN_DECLARE_UI_ABI_VERSION
-
+
// Function run on plugin startup, do simple initialization here (ViewTypes, SidebarWidgetTypes, etc)
BINARYNINJAPLUGIN bool UIPluginInit()
{
@@ -252,7 +252,7 @@ Then, in your plugin code, instead of using the exported functions for a core pl
}
// (Optional) Function to add other plugin dependencies in case your plugin requires them
- // Historically, these have never actually been used
+ // Historically, these have never actually been used
BINARYNINJAPLUGIN void UIPluginDependencies()
{
// For example, if you require triage view to be loaded before your plugin
@@ -277,16 +277,16 @@ are no cookie-cutter solutions to this problem, but there is a general strategy:
Again, I'm going to point out [the debugger](https://github.com/vector35/debugger) as a fantastic example of how to
implement this. Generally speaking, you will either need to write both sides of the FFI in a similar way, or you may
-be able to find a library that does that for you. Possibly [libffi](https://sourceware.org/libffi/), although there
+be able to find a library that does that for you. Possibly [libffi](https://sourceware.org/libffi/), although there
aren't any examples of using it for Binary Ninja specifically. If you manage to get something working, let us know!
-We would love to see more complex plugins with extensible behavior!
+We would love to see more complex plugins with extensible behavior!
## IDE Setup
### CLion
CLion is generally pretty good at handling CMake projects. Given the above CMake configuration, it can
-automatically detect the plugin target and will compile and install correctly. Here are a a few steps to finish
+automatically detect the plugin target and will compile and install correctly. Here are a few steps to finish
setup for building and live debugging your plugin:
1. If you installed Binary Ninja somewhere other than the default, add an environment variable in your CMake Profile pointing at the installation, e.g.: `BN_INSTALL_DIR=/Applications/Binary Ninja.app`
@@ -294,7 +294,7 @@ setup for building and live debugging your plugin:
3. In your Run Configuration's Before Launch steps, add an Install step. This will copy the updated version of your plugin before starting, so you don't have to run Install manually.
4. Set the Executable of your Run Configuration to point to the Binary Ninja executable. This allows you to compile your plugin and start Binary Ninja automatically.
i. On macOS, you will need the full path to /Applications/Binary Ninja.app/Contents/MacOS/binaryninja
-5. (Optionally) Add the `-e` flag to the Program Arguments to get error logs printed to your console
+5. (Optionally) Add the `-e` flag to the Program Arguments to get error logs printed to your console
6. (Optionally) Add the `-e -d` flags to the Program Arguments to get debug logs printed to your console. This may slow down Binary Ninja (and CLion) due to the large volume of logs produced.
7. (Optionally) Add the `-l /tmp/bn_out.txt` flags to the Program Arguments so your logs also get printed to a text file when you inevitably fill up the Console buffer in CLion and want to see what happened.
8. (Optionally on macOS) Add the Environment Variables `MallocScribble=1` and `MallocPreScribble=1` to make memory errors easier to spot.
@@ -317,7 +317,7 @@ You need to set up a task in `.vscode/tasks.json` to build and install your plug
"detail": "CMake template install task",
"options": {
"environment": {
- // You will need this if your Binary Ninja installation is not in the default location
+ // You will need this if your Binary Ninja installation is not in the default location
"BN_INSTALL_DIR": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja",
// You will need this if you are writing a UI plugin
"PATH": "C:\\Users\\User\\Qt\\6.8.2\\msvc2019_64\\bin"
@@ -377,6 +377,6 @@ Several native plugin examples exist:
## Contributing to Official Plugins
-There are many many official plugins released as open source. Python ones are included in the [official plugin repository](https://github.com/vector35/official-plugins), [native architectures](https://github.com/vector35/?q=arch-&type=all&language=&sort=) are available on GitHub along with several others that are included with the default product such as the [debugger](https://github.com/Vector35/debugger), the [views](https://github.com/vector35/?q=view-&type=public&language=&sort=), [platforms](https://github.com/vector35/?q=platform&type=public&language=&sort=), and some [rust plugins](https://github.com/Vector35/binaryninja-api/tree/dev/rust/examples).
+There are many official plugins released as open source. Python ones are included in the [official plugin repository](https://github.com/vector35/official-plugins), [native architectures](https://github.com/vector35/?q=arch-&type=all&language=&sort=) are available on GitHub along with several others that are included with the default product such as the [debugger](https://github.com/Vector35/debugger), the [views](https://github.com/vector35/?q=view-&type=public&language=&sort=), [platforms](https://github.com/vector35/?q=platform&type=public&language=&sort=), and some [rust plugins](https://github.com/Vector35/binaryninja-api/tree/dev/rust/examples).
The first time you contribute, you'll be asked to sign a [CLA](https://gist.github.com/psifertex/a207c2e070f4e342554dc011e920b341) automatically by [cla-assistant](https://cla-assistant.io/). Further commits after the first should not require any changes.
diff --git a/docs/dev/themes.md b/docs/dev/themes.md
index 8f005b0e..1ca13bf1 100644
--- a/docs/dev/themes.md
+++ b/docs/dev/themes.md
@@ -117,7 +117,7 @@ Colors marked "*required*" must be specified. Unmarked colors will hold default
3. `numberColor` (*required*) - Used to color number literals (e.g. `0xf0`)
4. `codeSymbolColor` (*required*) - Used to color local function names (e.g. `sub_100003c50`)
5. `dataSymbolColor` (*required*) - Used to color data symbols (e.g. `data_100003e2c`)
-6. `stackVariableColor` (*required*) - Used to color stack variables (e.g `var_8`) in disassembly and LLIL (the stack [does not exist](bnil-mlil.md) in MLIL and above)
+6. `stackVariableColor` (*required*) - Used to color stack variables (e.g. `var_8`) in disassembly and LLIL (the stack [does not exist](bnil-mlil.md) in MLIL and above)
7. `importColor` (*required*) - Used to color imported function names (e.g. `printf`)
8. `annotationColor` (*required*) - Used to color annotations (e.g. hints), not shown in picture above
9. `commentColor` - Used to color code comments
@@ -223,7 +223,7 @@ Both the graph background and individual graph nodes are actually painted as a g
1. `featureMapBaseColor` - Used to color the background
2. `featureMapNavLineColor` - Used to color the line(s) that represent where you are in the binary
-3. `featureMapNavHighlightColor` - Used as a highlight outside of the navigation line(s)
+3. `featureMapNavHighlightColor` - Used as a highlight outside the navigation line(s)
4. `featureMapDataVariableColor` - Used to highlight any area containing data variables
5. `featureMapAsciiStringColor` - Used to highlight any area containing ASCII strings
6. `featureMapUnicodeStringColor` - Used to highlight any area containing Unicode strings
diff --git a/docs/dev/typelibraries.md b/docs/dev/typelibraries.md
index 7302d967..5623e087 100644
--- a/docs/dev/typelibraries.md
+++ b/docs/dev/typelibraries.md
@@ -38,7 +38,7 @@ Therefore, without any alternative names, `libc.so.bntl` will not be loaded by B
We recommend and use the following convention:
-Type libraries should be named for the filename from which they were generated with the phrase ".bntl" added. When the source library contains additional minor and release number, like `libfoo.so.1.2.3` Binary Ninja would not load the resulting type library `libfoo.so.1.2.3.bntl` for an ELF requesting soname `libfoo.so.1`. Therefore the alternative names list should include the most specific version numbers, incrementally stripped down to the soname, and finally a linkname for good measure.
+Type libraries should be named for the filename from which they were generated with the phrase ".bntl" added. When the source library contains additional minor and release number, like `libfoo.so.1.2.3` Binary Ninja would not load the resulting type library `libfoo.so.1.2.3.bntl` for an ELF requesting soname `libfoo.so.1`. Therefore, the alternative names list should include the most specific version numbers, incrementally stripped down to the soname, and finally a linkname for good measure.
Example:
@@ -285,4 +285,4 @@ When a binary is loaded and its external symbols is processed, the symbol names
type library test.bntl found hit for _DoSuperComputation
```
-At this moment, there is no built in functionality to apply named objects to an existing Binary Ninja database.
+At this moment, there is no built-in functionality to apply named objects to an existing Binary Ninja database.
diff --git a/docs/dev/uidf.md b/docs/dev/uidf.md
index 33c4c27f..817bbef7 100644
--- a/docs/dev/uidf.md
+++ b/docs/dev/uidf.md
@@ -6,11 +6,11 @@ Binary Ninja now implements User-Informed DataFlow (UIDF) to improve the static
For the purpose of demonstration, we are going to use a simple [crackme](https://github.com/Vector35/uidf-example).
-It is a fairly simple challenge but we can use it to demonstrate how UIDF can be used to progressively simplify the problem through branch elimination. First, we'll show how to use this new feature and then we'll discuss some of the design decisions that went into the implementation.
+It is a fairly simple challenge, but we can use it to demonstrate how UIDF can be used to progressively simplify the problem through branch elimination. First, we'll show how to use this new feature, then we'll discuss some of the design decisions that went into the implementation.
Let's start by looking at the `main` function. Note that the `rax_*` variables contain values returned from the computation of `check_*` functions. These values are used for determining whether control would flow to the satisfying or failure conditions of the crackme.
-Let's first look at `rax_2`. We see that the conditional at Medium Level IL (MLIL) instruction 8 uses a field access into `rax` and checks its value against 0. If it evaluates to true, control-flow jumps to `0x004010a4` and outputs "Incorrect". However if it evaluates to false, we continue down the chain of conditionals which determine if the output is "Correct". To confirm our understanding and simplify the process further, we can inform the dataflow analysis engine with the value for `rax_2` and see how it impacts the control flow of the binary.
+Let's first look at `rax_2`. We see that the conditional at Medium Level IL (MLIL) instruction 8 uses a field access into `rax` and checks its value against 0. If it evaluates to true, control-flow jumps to `0x004010a4` and outputs "Incorrect". However, if it evaluates to false, we continue down the chain of conditionals which determine if the output is "Correct". To confirm our understanding and simplify the process further, we can inform the dataflow analysis engine with the value for `rax_2` and see how it impacts the control flow of the binary.
First, note the definition site of `rax_2` is instruction 7 and then right click there to see "Set User Variable Value...". Users can also bind the action to a hotkey or access it via the command palette.
@@ -107,7 +107,7 @@ We believe that UIDF is great for experimenting around with during the initial p
### Jump-Table Example
-Another example of using UIDF would be to construct jump-tables with known bounds. There are several other ways to achieve this same goal that it may be helpful to review. First, as our old [example plugin](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/jump_table.py#L81) demonstrates, you can use the [`set_user_indirect_branches`](https://api.binary.ninja/binaryninja.function-module.html#binaryninja.function.Function.set_user_indirect_branches) API, though this is probably the least easy method to use. Next, you can create an appropriately sized array of pointers at the base of a jump table reference, and the jump table recovery will automatically create all of the appropriate targets.
+Another example of using UIDF would be to construct jump-tables with known bounds. There are several other ways to achieve this same goal that it may be helpful to review. First, as our old [example plugin](https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/jump_table.py#L81) demonstrates, you can use the [`set_user_indirect_branches`](https://api.binary.ninja/binaryninja.function-module.html#binaryninja.function.Function.set_user_indirect_branches) API, though this is probably the least easy method to use. Next, you can create an appropriately sized array of pointers at the base of a jump table reference, and the jump table recovery will automatically create all the appropriate targets.
Now, with the introduction of UIDF, there's another easy way to help inform the jump-table analysis. Consider the MLIL representation for an indirect jump as shown below:
@@ -130,6 +130,6 @@ A jump table will be created with a base of `0x804891c` with 14 possible targets
Static-only reverse engineering limits the ability to test hypotheses formulated during the initial analysis phase. To that end, analysts usually turn to emulation/debugging to experiment with a binary. This can often be time-consuming if the focus is on checking dependencies between program variables or for verifying the dataflow, or worse, may be impossible for some platforms that are difficult to dynamically analyze. With UIDF, we aim to provide our users with the ability to interact with the dataflow engine more richly and partly achieve the same results without leaving the flow graph or linear analysis window. UIDF could also aid in better understanding targets of indirect jumps or fixing jump tables. Research [[1](https://acmccs.github.io/papers/p347-shoshitaishviliA.pdf),[2](https://dl.acm.org/doi/fullHtml/10.1145/3290607.3313040)] shows that it is imperative that binary analysis tools adopt a more user-guided approach to solve RE/VR tasks and UIDF tries to be a step up that slope. We aim to continue work in this direction!
-UIDF primarily operates on the MLIL layer. Binary Ninja performs constant propagation, resolves call parameters and lifts stack load/stores into a variables. However, the UI can apply a UIDF constraint on an HLIL variable or MLIL variable and apply it appropriately. This combined with the SSA form enables an effective dataflow analysis pipeline. MLIL also provides control over dead-code elimination and allows us to prevent removal of redundant instructions (eg. variable definitions for informed variables) and basic blocks (removed due to the resulting dataflow). Binary Ninja's tiered IL representation allows the higher layers to benefit from simplifying transformations at the lower layers. Through fixing jump tables or branch elimination, UIDF influences HLIL output as a user would expect without having drastic changes to the MLIL representation.
+UIDF primarily operates on the MLIL layer. Binary Ninja performs constant propagation, resolves call parameters, and lifts stack load/stores into variables. However, the UI can apply a UIDF constraint on an HLIL variable or MLIL variable and apply it appropriately. This combined with the SSA form enables an effective dataflow analysis pipeline. MLIL also provides control over dead-code elimination and allows us to prevent removal of redundant instructions (e.g. variable definitions for informed variables) and basic blocks (removed due to the resulting dataflow). Binary Ninja's tiered IL representation allows the higher layers to benefit from simplifying transformations at the lower layers. Through fixing jump tables or branch elimination, UIDF influences HLIL output as a user would expect without having drastic changes to the MLIL representation.
Looking towards the future, improvements to the dataflow solver engine would inherently increase the efficacy of UIDF. This could include support for more operations on the complex [`PossibleValueSet`](https://api.binary.ninja/binaryninja.variable-module.html#binaryninja.variable.PossibleValueSet) containers or the ability to play well with program structure such as loops.
diff --git a/docs/dev/workflows.md b/docs/dev/workflows.md
index d923dd05..61d6b77f 100644
--- a/docs/dev/workflows.md
+++ b/docs/dev/workflows.md
@@ -608,8 +608,8 @@ current_function.workflow.show_topology()
These commands build upon the static view by incorporating real-time dynamic state information. It provides additional insights such as the current eligibility of activities, override states, and other runtime data. This enhanced view offers a more detailed and interactive perspective, making it invaluable for monitoring and debugging during execution.
!!! note
- Using the dynamic view, the eligibility of activities can be toggled interactively. Currently, this behavior is tied to the double-click event on an activity node. This feature allows you to quickly cycle through different eligibility states, enabling rapid testing and validation of activity configurations.
+ Using the dynamic view, the eligibility of activities can be toggled interactively. Currently, this behavior is tied to the double click event on an activity node. This feature allows you to quickly cycle through different eligibility states, enabling rapid testing and validation of activity configurations.
## Advanced Topics (Coming Soon)
-This section covers advanced topics related to Workflows, Activities, and the Workflow Machine. It explores emerging concepts, best practices, and strategies for optimizing and extending the analysis pipeline. \ No newline at end of file
+This section covers advanced topics related to Workflows, Activities, and the Workflow Machine. It explores emerging concepts, best practices, and strategies for optimizing and extending the analysis pipeline.
diff --git a/docs/guide/enterprise/index.md b/docs/guide/enterprise/index.md
index cb568434..4f2e8bc2 100644
--- a/docs/guide/enterprise/index.md
+++ b/docs/guide/enterprise/index.md
@@ -150,7 +150,7 @@ In any open file from a shared project, the Describe Changes Dialog will appear
![Describe Changes Dialog](../../img/enterprise/describe-changes.png){: style="max-width:335px; display: block; margin: auto;"}
### File Changelog
-The File Changelog can be accessed via `File/Collaboration/File Changelog...`. It shows a list of changes that have been made to the current file, along with what user made those changes, when, and a description of those changes. Items in this list are *sets* of changes (typically all of the changes before a user clicked the sync button), rather than every snapshot in the database.
+The File Changelog can be accessed via `File/Collaboration/File Changelog...`. It shows a list of changes that have been made to the current file, along with what user made those changes, when, and a description of those changes. Items in this list are *sets* of changes (typically all the changes before a user clicked the sync button), rather than every snapshot in the database.
![File Changelog](../../img/enterprise/file-changelog.png){: style="max-width:901px; display: block; margin: auto;"}
diff --git a/docs/guide/firmwareninja.md b/docs/guide/firmwareninja.md
index db49e99f..239ccb51 100644
--- a/docs/guide/firmwareninja.md
+++ b/docs/guide/firmwareninja.md
@@ -139,7 +139,7 @@ contained in the current project. To specify that the secondary entity is in an
If the current binary is not part of a Binary Ninja project, the `External File` button will be disabled, providing
only the option to define internal relationships.
-Click populated the cells in the `Primary` or `Secondary` columns to navigate between related items. If the related
+Click populated cells in the `Primary` or `Secondary` columns to navigate between related items. If the related
item is in an external bndb, the external bndb will be opened in a new tab and the UI will navigate to the location of
the item.
diff --git a/docs/guide/index.md b/docs/guide/index.md
index 1632e891..1d776968 100644
--- a/docs/guide/index.md
+++ b/docs/guide/index.md
@@ -16,7 +16,7 @@ Binaries are installed in the following locations by default:
- Windows (user install): `%LOCALAPPDATA%\Vector35\BinaryNinja`
???+ Tip "Tip"
- If you want a silent install on Windows, because we use the [NSIS](https://nsis.sourceforge.io/Docs/) installer, simply use: `BinaryNinjaInstaller.exe /S`
+ If you want a silent installation on Windows, because we use the [NSIS](https://nsis.sourceforge.io/Docs/) installer, simply use: `BinaryNinjaInstaller.exe /S`
???+ Danger "Warning"
Do not put any user content in the install-path of Binary Ninja. The auto-update process of Binary Ninja WILL remove any files included in these locations.
@@ -31,7 +31,7 @@ While the default user folders are listed below, you can override these paths on
The contents of the user folder includes:
-- `lastrun`: A text file containing the directory of the last Binary Ninja binary path -- very useful for plugins to resolve the install locations in non-default settings or on Linux
+- `lastrun`: A text file containing the directory of the last Binary Ninja binary path -- very useful for plugins to resolve the installation locations in non-default settings or on Linux
- `license.dat`: License file
- `plugins/`: Folder containing all manually installed user plugins
- `repositories/`: Folder containing files and plugins managed by the [Plugin Manager API](https://api.binary.ninja/binaryninja.pluginmanager-module.html)
@@ -55,7 +55,7 @@ The following files and folders may be created in the user folder but are not cr
Some settings such as window locations, saved checkboxes, recent file lists, disassembly settings, dialog histories are stored in `QSettings`. Note that the `BN_QSETTINGS_POSTFIX` environment variable can be used to temporarily use a different QSetting file which is useful for different profiles or testing purposes.
-If you ever have the need to flush these, you can find the install locations as described in the [QT documentation](https://doc.qt.io/qt-6/qsettings.html#platform-specific-notes).
+If you ever have the need to flush these, you can find the installation locations as described in the [QT documentation](https://doc.qt.io/qt-6/qsettings.html#platform-specific-notes).
## License
@@ -67,7 +67,7 @@ Once the license key is installed, you can change it, back it up, or otherwise i
## Linux Setup
-Because Linux install locations can vary widely, we do not assume that Binary Ninja has been installed in any particular folder on Linux. Rather, you can simply run `binaryninja/scripts/linux-setup.sh` after extracting the zip and various file associations, icons, and other settings will be set up. Run it with `-h` to see the customization options.
+Because Linux installation locations can vary widely, we do not assume that Binary Ninja has been installed in any particular folder on Linux. Rather, you can simply run `binaryninja/scripts/linux-setup.sh` after extracting the zip and various file associations, icons, and other settings will be set up. Run it with `-h` to see the customization options.
## Loading Files
@@ -99,7 +99,7 @@ There are five menu items that can be used to save some combination of a raw fil
### 1. Save
-This option is the only one bound to a hotkey by default and it is intended to be the "do what I probably want" option.
+This option is the only one bound to a hotkey by default, and it is intended to be the "do what I probably want" option.
- If you have edited the contents of a file and have not yet confirmed the file name to save over, this will ask you to save the file contents and prompt for a file name (check the save dialog title text to confirm this).
- If you have edited the file contents and _have_ previously specified the file name, this option will save those changes to that file without a prompt.
@@ -130,9 +130,9 @@ This menu allows for saving a `.bndb` without additional undo information, or by
## New Files
-When you create a new file, you're given the [hex view](index.md#hex-view) of an empty file. From here you can manually type in hexadecimal or ascii values, or paste in data in a variety of ways. To type in hex, make sure the left-side is focused, to type in ascii, just focus the right-side using the mouse or the "tab" key. The only way to enter a tab character into the ascii section is to enter "09" in the hex side.
+When you create a new file, you're given the [hex view](index.md#hex-view) of an empty file. From here you can manually type in hexadecimal or ASCII values, or paste in data in a variety of ways. To type in hex, make sure the left-side is focused, to type in ASCII, just focus the right-side using the mouse or the "tab" key. The only way to enter a tab character into the ASCII section is to enter "09" in the hex side.
-To paste, right click anywhere in the view, select "Paste From," and choose whichever option matches the data you copied. For example, the string `\x01\x02\x03\x04` can be pasted as an Escape String, while `01020304` is Raw Hex.
+To paste, right click anywhere in the view, select "Paste From", and choose whichever option matches the data you copied. For example, the string `\x01\x02\x03\x04` can be pasted as an Escape String, while `01020304` is Raw Hex.
From here, you can save the contents of your new binary to disk and reopen it for auto-analysis. Of course, you could also switch out of hex view into linear view and start creating functions directly.
@@ -161,13 +161,13 @@ The status of currently installed plugins will be displayed in the bottom right.
![plugin status ><](../img/plugin-status-widget.png "Plugin Status Widget"){ width="400" }
-Pressing each of the icons will navigate you to the the Plugin Manager with the corresponding filter:
+Pressing each of the icons will navigate you to the Plugin Manager with the corresponding filter:
- Green Circle: `@installed`
- Error Symbol: `@failed_to_load`
- Update Icon: `@update_available`
-Pressing the gear or using the hotkeys (macOS: `[CMD+SHIFT] + M` , Windows/Linux: `[CTRL+SHIFT] + M`) will open the plugin manager with no filters so you can browse available plugins.
+Pressing the gear or using the hotkeys (macOS: `[CMD+SHIFT] + M`, Windows/Linux: `[CTRL+SHIFT] + M`) will open the plugin manager with no filters, so you can browse available plugins.
### Commercial/Ultimate Features
@@ -227,7 +227,7 @@ There's also [many](#using-the-keyboard) keyboard-based navigation options.
Switching views happens multiple ways. In some instances, it is automatic, such as clicking a data reference from graph view. This will navigate to linear view as data is not shown in the graph view. While navigating, you can use the [view hotkeys](#default-hotkeys) to switch to a specific view at the same location as the current selection. Next you can use the [command palette](#command-palette). Additionally, the view menu in the header at the top of each pane can be used to change views without navigating to any given location. Finally, you can also use the `View` application menu.
???+ Tip "Tip"
- Any loaded BinaryView will show up in the upper-left of the main pane. You can switch between (for example), `ELF` and `Raw` to switch between multiple loaded [BinaryViews](../dev/concepts.md#binary-views).
+ Any loaded `BinaryView` will show up in the upper-left of the main pane. You can switch between (for example), `ELF` and `Raw` to switch between multiple loaded [`BinaryView`s](../dev/concepts.md#binary-views).
## The Sidebar
@@ -259,7 +259,7 @@ The Symbol List shows the following columns by default:
- `Name`: the [short name](https://api.binary.ninja/binaryninja.types-module.html#binaryninja.types.CoreSymbol) of the symbol (can be changed to the [raw name](https://api.binary.ninja/binaryninja.types-module.html#binaryninja.types.CoreSymbol) in the menu icon for the Symbol List)
- `Address`: the virtual address for the symbol
-- `Kind`: may be one of "Folder", Function", "Data", and "Bare Symbol"
+- `Kind`: may be one of "Folder", "Function", "Data", and "Bare Symbol"
- `Section`: the section of the binary the symbol appears in
Additionally, the following columns are hidden by default and can be enabled by right-clicking the header:
@@ -298,7 +298,7 @@ The Types View can be used as a sidebar panel or as a pane in the main view. The
![tags ><](../img/tags.png "Tags"){ width="600" }
-The tags panel allows you to both change existing tag categories, add your own categories, and also review any existing tags or bookmarks. Bookmarks are just tags with default hotkeys bound to them for both setting them and navigating them. The default keybinding to set a bookmark is `[CTRL-ALT] 1` through `[CTRL-ALT] 0` representing Bookmarks 1-10. The default hotkeys for navigating them are `[CTRL] 1` through `[CTRL] 0`. See the [keybindings](#custom-hotkeys) section for information on changing the default keybindings.
+The Tags panel allows you to change existing tag categories, add your own categories, and also review any existing tags or bookmarks. Bookmarks are just tags with default hotkeys bound to them for both setting them and navigating them. The default keybinding to set a bookmark is `[CTRL-ALT] 1` through `[CTRL-ALT] 0` representing Bookmarks 1-10. The default hotkeys for navigating them are `[CTRL] 1` through `[CTRL] 0`. See the [keybindings](#custom-hotkeys) section for information on changing the default keybindings.
### Memory Map
@@ -306,7 +306,7 @@ The tags panel allows you to both change existing tag categories, add your own c
The "Memory Map" pane and sidebar widget show segments and sections currently present in the binary, allows some modification of automatically added sections, and allows adding, modifying, and deleting user segments and sections.
-Double clicking an address in the "start" or "end" column will navigate in the address in the current view. If an address in the "Data Offset" column is double clicked, that address will always be navigated to in the `Raw` view which may be confusing at first.
+Double-clicking an address in the "start" or "end" column will navigate in the address in the current view. If an address in the "Data Offset" column is double-clicked, that address will always be navigated to in the `Raw` view which may be confusing at first.
![memory map icon <](../img/memory-map-icon.png "Memory Map Icon")
@@ -426,7 +426,7 @@ The Stack sidebar panel shows the currently selected function's stack layout. Yo
The History sidebar panel shows all annotations made during the history of a database. Note that even changes made prior to the introduction of the UI will be shown. This not only makes it easier to see what changes have been made, but allows you to right-click and revert to a particular point in analysis. Additionally, the right-click menu includes a toggle to hide or show the date of the change.
-Note that when plugins or the UI batch multiple changes in one action, they wil be summarized with a count of actions but no further details are possible.
+Note that when plugins or the UI batch multiple changes in one action, they will be summarized with a count of actions but no further details are possible.
There is currently no support for branching/forking style of history at this time.
@@ -457,7 +457,7 @@ The search types are available from a drop-down next to the text input field and
![Logs](../img/logs.png "Logs"){ width="700" }
-The log window lets you search and filter through logs. You can search by text or filter by loggers to identify messages of interest. By default, only the logs for a specific BinaryView that's open as well as any Global logs will show up but this setting can either be changed through the right-click menu or the drop down menu in the upper-right of the log window.
+The log window lets you search and filter through logs. You can search by text or filter by loggers to identify messages of interest. By default, only the logs for a specific `BinaryView` that's open as well as any Global logs will show up, but this setting can either be changed through the right-click menu or the drop-down menu in the upper-right of the log window.
### Hidden Sidebar Icons
@@ -538,7 +538,7 @@ To search in the keybindings list, just click to make sure it's focused and star
- `a` : Change the data type to an ASCII string
- `[SHIFT] a` : Change the data type to a `wchar_t` string
- `[OPT-SHIFT] a` (macOS) : Change the data type to a `wchar32_t` string
- - `[CTRL-SHIFT] a` (Windows/Linux) : Change the data type to a `wchar32_t` string
+ - `[CTRL-SHIFT] a` (Windows/Linux) : Change the data type to a `wchar32_t` string
- `1`, `2`, `4`, `8` : Change type directly to a data variable of the indicated widths
- `f` : Switch data variable between floating point types of varying precision
- `d` : Switch between data variables of various widths
@@ -632,7 +632,7 @@ using the [`corePlugins.triage`](settings.md#corePlugins.triage) setting.
### 1. Entropy
This image shows the overall entropy of the file. Brighter areas indicate regions of higher entropy
-(encrypted, compressed, etc), while darker regions indicate places of lower entropy. You can click anywhere in the
+(encrypted, compressed, etc.), while darker regions indicate places of lower entropy. You can click anywhere in the
entropy map to navigate to that location in your default view.
### 2. File Info
@@ -642,8 +642,8 @@ it into your clipboard.
### 3. Headers
-This section appears only in BinaryViews and the exact information depends on the view itself. PE headers
-are the most detailed and include such items as checksums, characterstics, and compiler strings. Addresses that
+This section appears only in `BinaryView`s and the exact information depends on the view itself. PE headers
+are the most detailed and include such items as checksums, characteristics, and compiler strings. Addresses that
existing in the virtual memory space of the file can be clicked to navigate to that location.
### 4. Base Address Detection (BASE)
@@ -652,8 +652,8 @@ existing in the virtual memory space of the file can be clicked to navigate to t
The Base Address Scan Engine (or BASE) is used to automatically identify load addresses for embedded files or
other formats where the load address isn't known and the file isn't relocatable. BASE is only visible in the triage
-summary when the file doesn't specify a load address such as a raw or mapped file. For BinaryViews like PE or MachO,
-switching the view in the upper-left from the BinaryView name to `raw` will force the BASE UI to show up in the
+summary when the file doesn't specify a load address such as a raw or mapped file. For `BinaryView`s like PE or Mach-O,
+switching the view in the upper-left from the `BinaryView` name to `raw` will force the BASE UI to show up in the
Triage Summary.
See our recent [blog
@@ -692,7 +692,7 @@ clickable to navigate to the virtual address.
### 8. Strings
-Strings can be double clicked to navigate to them, and the table can be sorted or the list filtered by
+Strings can be double-clicked to navigate to them, and the table can be sorted or the list filtered by
typing in the search box.
## Byte Overview
@@ -703,8 +703,8 @@ The Byte Overview (or "Bytes" when selected in the view switcher) shows the bina
top-level selection) as a [Code Page 437](https://en.wikipedia.org/wiki/Code_page_437) view. This view is commonly used
by malware analysis researchers using the [Hiew](http://hiew.ru) tool.
-While this view is less featureful than the Hex view, it allows for a much higher information density as every byte is
-represented by one character as opposted to four total characters when in Hex view (including the space between hex
+While this view is less feature-rich than the Hex view, it allows for a much higher information density as every byte is
+represented by one character as opposed to four total characters when in Hex view (including the space between hex
digits and the ASCII representation).
## Hex View
@@ -829,7 +829,7 @@ is shown below:
![Expression Folding](../img/folding-before.png "Expression Folding"){ width="500" }
-Binary Ninja uses heuristics to determine if optimizatoins will improve readability, but sometimes it doesn't make the
+Binary Ninja uses heuristics to determine if optimizations will improve readability, but sometimes it doesn't make the
preferred choice. In the case above, you can override the heuristic by right-clicking the inner call expression and
choosing "Allow" or "Prevent" from the "Expression Folding" submenu.
@@ -858,7 +858,7 @@ this feature are shown in the table below:
## Merging and Splitting Variables
-Binary Ninja automatically splits all variables that the analysis determines to be safely splittable. This allows the user to assign different types to different uses of the same register or memory location. Sometimes, however, the code is more clear if two or more of these variables are merged together into a single variable.
+Binary Ninja automatically splits all variables that the analysis determines to be safely split. This allows the user to assign different types to different uses of the same register or memory location. Sometimes, however, the code is more clear if two or more of these variables are merged together into a single variable.
### Merge Variable Here
@@ -897,7 +897,7 @@ variable at a definition site and selecting "Split Variable at Definition" from
cases.
Manually split variables will initially provide the selected definition as a separate variable, and all other
-definitions will be automatically resolved into one or more other variables. If some of the definitions should
+definitions will be automatically resolved into one or more other variables. If some definitions should
have been included as part of the same variable, use "Merge Variables..." from the context menu after splitting
to select which of the other definitions should be merged.
@@ -961,14 +961,14 @@ The interactive python prompt also has several built-in "magic" functions and va
- `current_il_instruction`: the current IL instruction. It can be LLIL/MLIL/HLIL depending on which one is shown in the UI
- `current_il_function`: the current IL function. It can be LLIL/MLIL/HLIL depending on which one is shown in the UI
- `current_il_basic_block`: the current IL basic block. It can be LLIL/MLIL/HLIL depending on which one is shown in the UI
-- `current_token`: the current selected [`InstructionTextToken`](https://api.binary.ninja/binaryninja.architecture-module.html#binaryninja.architecture.InstructionTextToken). None if no token is selected
-- `current_data_var`: the current selected [`DataVariable`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.DataVariable). None if no data variable is selected
-- `current_sections`: the list of [`Section`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.Section)s that the current address is in. This the list can be empty
-- `current_segment`: the [`Segment`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.Segment) that the current address is in.
+- `current_token`: the current selected [`InstructionTextToken`](https://api.binary.ninja/binaryninja.architecture-module.html#binaryninja.architecture.InstructionTextToken) (`None` if no token is selected)
+- `current_data_var`: the current selected [`DataVariable`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.DataVariable) (`None` if no data variable is selected)
+- `current_sections`: the list of [`Section`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.Section)s that the current address is in (This list can be empty)
+- `current_segment`: the [`Segment`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.Segment) that the current address is in
- `current_comment`: the comment at the current address. Writing to it sets comment at the current address
-- `current_symbol`: the [`Symbol`](https://api.binary.ninja/binaryninja.types-module.html#binaryninja.types.Symbol) at the current address. None if there is no symbol
+- `current_symbol`: the [`Symbol`](https://api.binary.ninja/binaryninja.types-module.html#binaryninja.types.Symbol) at the current address (`None` if there is no symbol)
- `current_symbols`: the list of [`Symbol`](https://api.binary.ninja/binaryninja.types-module.html#binaryninja.types.Symbol)s at the current address
-- `current_var`: the current selected [`Variable`](https://api.binary.ninja/binaryninja.variable-module.html?highlight=variable#binaryninja.variable.Variable) in a function. Not to be confused with `current_data_var`
+- `current_var`: the current selected [`Variable`](https://api.binary.ninja/binaryninja.variable-module.html?highlight=variable#binaryninja.variable.Variable) in a function (Not to be confused with `current_data_var`)
- `current_ui_context`: the current [`UIContext`](https://api.binary.ninja/cpp/class_u_i_context.html)
- `current_ui_view_frame`: the current [`ViewFrame`](https://api.binary.ninja/cpp/class_view_frame.html)
- `current_ui_view`: the current [`View`](https://api.binary.ninja/cpp/class_view.html)
@@ -1027,8 +1027,8 @@ For more detailed information on using plugins, see the [plugin guide](plugins.m
Binary Ninja supports loading PDB files through a built-in PDB loader. It will automatically search for a corresponding PDB file whenever you load a Windows executable or library that was compiled with a PDB. The PDB loader will search a variety of places for PDBs, in the following order, if the files exist and match the GUID in the analyzed file:
1. Look in symbol servers defined in the `_NT_SYMBOL_PATH` environment variable, as defined by [Microsoft's documentation](https://learn.microsoft.com/en-us/windows/win32/debug/using-symsrv).
-2. Look for the file at the path specified in the loaded binary. E.g. when `C:\Users\foo\foo.exe` was compiled, it stored `C:\Users\foo\foo.pdb` as metadata inside `foo.exe`, so `C:\Users\foo\foo.pdb` will be loaded if it exists (and matches the guid).
-3. Look in the same directory as the opened file/bndb (e.g. If you have opened `C:\foo.exe` or `C:\foo.bndb`, the PDB plugin looks for `C:\foo.pdb`)
+2. Look for the file at the path specified in the loaded binary. E.g. when `C:\Users\foo\foo.exe` was compiled, it stored `C:\Users\foo\foo.pdb` as metadata inside `foo.exe`, so `C:\Users\foo\foo.pdb` will be loaded if it exists (and matches the GUID).
+3. Look in the same directory as the opened file/BNDB (e.g. If you have opened `C:\foo.exe` or `C:\foo.bndb`, the PDB plugin looks for `C:\foo.pdb`)
4. Look in the local symbol store. This is the directory specified by `pdb.files.localStoreAbsolute` in the settings, if it exists. Otherwise, this is a folder relative to the Binary Ninja user directory, specified by the `pdb.files.localStoreRelative` setting (and possibly the `BN_USER_DIRECTORY` environment variable). This directory has the structure `<symbol store>\foo.pdb\<guid>\foo.pdb`, equivalent to a regular symbol server.
5. Attempt to connect and download the PDB from the list of symbol servers specified in setting `pdb.files.symbolServerList`, in order.
@@ -1048,10 +1048,10 @@ The PDB loader comes with a couple configuration options which enable and disabl
## Launching Binary Ninja from the command line (CLI)
-When you launch Binary Ninja from the command-line, you can control whether or not a new window is launched or an existing window is used.
+When you launch Binary Ninja from the command-line, you can control whether a new window is launched or an existing window is used.
* Running Binary Ninja from the command line will try to find a running instance of the same version in which to open any files or URLs passed on the command line, or activate the main window if no arguments are provided.
-* For users whose workflow involves running Binary Ninja from a shell, just running `binaryninja` will try to activate a running instance, and if it does, return you to your shell. Otherwise it will launch a new instance of Binary Ninja.
+* For users whose workflow involves running Binary Ninja from a shell, just running `binaryninja` will try to activate a running instance, and if it does, return you to your shell. Otherwise, it will launch a new instance of Binary Ninja.
* Running `binaryninja` with a file path (or paths), like `binaryninja /bin/ls /bin/cat`, will
1. Try to activate and focus existing tabs for those files in a running instance, or failing that,
2. Try to open those files in new tabs in a running instance, or failing that,
diff --git a/docs/guide/migration/migrationguideghidra.md b/docs/guide/migration/migrationguideghidra.md
index 7867f0b5..55ccbd3e 100644
--- a/docs/guide/migration/migrationguideghidra.md
+++ b/docs/guide/migration/migrationguideghidra.md
@@ -6,9 +6,9 @@ Binary Ninja starts with the [New Tab Page](../index.md#new-tab) open. From here
## Decompiler Settings
-Binary Ninja likes to stay out of your way as much as possible, but sometimes you need to dig into the settings and change how a file is analyzed. If you have a file that can be opened with default settings, you won't get prompted for any additional input. Binary Ninja will automatically analyze the entire file — including running [linear sweep](https://binary.ninja/2017/11/06/architecture-agnostic-function-detection-in-binaries.html) — and provide you with linear decompilation for the whole file (like Ghidra's linear disassembly, but as decomp by default).
+Binary Ninja likes to stay out of your way as much as possible, but sometimes you need to dig into the settings and change how a file is analyzed. If you have a file that can be opened with default settings, you won't get prompted for any additional input. Binary Ninja will automatically analyze the entire file — including running [linear sweep](https://binary.ninja/2017/11/06/architecture-agnostic-function-detection-in-binaries.html) — and provide you with linear decompilation for the whole file (like Ghidra's linear disassembly, but as decompilation by default).
-If you're opening a [Universal Mach-O](https://en.wikipedia.org/wiki/Universal_binary), the Open with Options dialogue will appear so that you can choose which architecture to open (in the top right). If you have a default architecture you want to open whenever you open a universal binary, you can set your preference in a setting called [Universal Mach-O Architecture Preference](../settings.md#settings-reference). You'll also see the Open with Options dialogue when Binary Ninja is unable to recognize the file type or otherwise needs user input to analyze the file (can't find the entry point, needs you to provide some memory mappings, etc).
+If you're opening a [Universal Mach-O](https://en.wikipedia.org/wiki/Universal_binary), the Open with Options dialogue will appear so that you can choose which architecture to open (in the top right). If you have a default architecture you want to open whenever you open a universal binary, you can set your preference in a setting called [Universal Mach-O Architecture Preference](../settings.md#settings-reference). You'll also see the Open with Options dialogue when Binary Ninja is unable to recognize the file type or otherwise needs user input to analyze the file (can't find the entry point, needs you to provide some memory mappings, etc.).
It's worth digging into Binary Ninja's [settings](../settings.md) and seeing what's available to tune, but if you ever want to change a setting for a single binary, you can Open (it) with Options. Go to File -> Open with Options, and any settings you change will apply to only that file.
@@ -89,11 +89,11 @@ That said, I'll walk you through how to set up your sidebars to get it looking v
#### Program Tree
-But first, there are a couple caveats. Binary Ninja does not have an exact 1-to-1 widget for everything in Ghidra. The Program Tree is one of those elements; it's a little bit like our memory map, but it's also kinda not. Our new Binary Ninja layout assumes you've closed the program tree in Ghidra. Now Binary Ninja and Ghidra's sidebars are starting to match by having the symbols view on the top (which we start as a flat listing for you to organize into file yourself), and a different sidebar panel below it. Be sure to check out the options in the Symbols list's hamburger menu (the three lines in the top right).
+But first, there are a couple caveats. Binary Ninja does not have an exact 1-to-1 widget for everything in Ghidra. The Program Tree is one of those elements; it's a bit like our memory map, but it's also kinda not. Our new Binary Ninja layout assumes you've closed the program tree in Ghidra. Now Binary Ninja and Ghidra's sidebars are starting to match by having the symbols view on the top (which we start as a flat listing for you to organize into file yourself), and a different sidebar panel below it. Be sure to check out the options in the Symbols list's hamburger menu (the three lines in the top right).
#### Cross References and Types Manager
-We show cross references by default, but you can toggle that just by clicking it off on the left side under the divider line. If you want to match how Ghidra has it's types showing on the bottom, you can simply drag the types widget to beneath the divider line on the left side. Whenever you open your sidebar, both areas will open together. The Types sidebar also shows you the full type definition when you select a type.
+We show cross references by default, but you can toggle that just by clicking it off on the left side under the divider line. If you want to match how Ghidra has its types showing on the bottom, you can simply drag the types widget to beneath the divider line on the left side. Whenever you open your sidebar, both areas will open together. The Types sidebar also shows you the full type definition when you select a type.
#### Main Area
@@ -102,7 +102,7 @@ Time for the main event!
Ghidra shows you a linear view on the left, and single-function-at-a-time decompilation on the right. We already gave you linear decompilation of the whole Binary here by default, so there are three last things to do:
1. Create a new pane by pressing the icon in the top right that looks like a rectangle with a line through it. The two panes are now synced by address, as you’d expect.
-2. In the left pane, find the drop down that says "High Level IL", and switch down to disassembly. You should now have linear disassembly on the left, and linear decompilation on the right.
+2. In the left pane, find the dropdown that says "High Level IL", and switch down to disassembly. You should now have linear disassembly on the left, and linear decompilation on the right.
3. The final touch is to go back to the decompilation pane on the right and find the hamburger menu for that pane in the top right, and then select “Single Function View.”
Now the UI should be looking extremely familiar. Read our last couple of tips below, don't forget to use the command palette to find what you want to do, and you'll be off analyzing binaries in no time!
diff --git a/docs/guide/migration/migrationguideida.md b/docs/guide/migration/migrationguideida.md
index 0e3af279..029fef1b 100644
--- a/docs/guide/migration/migrationguideida.md
+++ b/docs/guide/migration/migrationguideida.md
@@ -6,9 +6,9 @@ Binary Ninja starts with the [New Tab Page](../index.md#new-tab) open. From here
## Decompiler Settings
-Binary Ninja likes to stay out of your way as much as possible, but sometimes you need to dig into the settings and change how a file is analyzed. If you have a file that can be opened with default settings, you won't get prompted for any additional input. Binary Ninja will automatically analyze the entire file — including running [linear sweep](https://binary.ninja/2017/11/06/architecture-agnostic-function-detection-in-binaries.html) — and provide you with linear decompilation for the whole file (like IDA's linear disassembly, but as decomp by default).
+Binary Ninja likes to stay out of your way as much as possible, but sometimes you need to dig into the settings and change how a file is analyzed. If you have a file that can be opened with default settings, you won't get prompted for any additional input. Binary Ninja will automatically analyze the entire file — including running [linear sweep](https://binary.ninja/2017/11/06/architecture-agnostic-function-detection-in-binaries.html) — and provide you with linear decompilation for the whole file (like IDA's linear disassembly, but as decompilation by default).
-If you're opening a [Universal Mach-O](https://en.wikipedia.org/wiki/Universal_binary), the Open with Options dialogue will appear so that you can choose which architecture to open (in the top right). If you have a default architecture you want to open whenever you open a universal binary, you can set your preference in a setting called [Universal Mach-O Architecture Preference](../settings.md#settings-reference). You'll also see the Open with Options dialogue when Binary Ninja is unable to recognize the file type or otherwise needs user input to analyze the file (can't find the entry point, needs you to provide some memory mappings, etc).
+If you're opening a [Universal Mach-O](https://en.wikipedia.org/wiki/Universal_binary), the Open with Options dialogue will appear so that you can choose which architecture to open (in the top right). If you have a default architecture you want to open whenever you open a universal binary, you can set your preference in a setting called [Universal Mach-O Architecture Preference](../settings.md#settings-reference). You'll also see the Open with Options dialogue when Binary Ninja is unable to recognize the file type or otherwise needs user input to analyze the file (can't find the entry point, needs you to provide some memory mappings, etc.).
It's worth digging into Binary Ninja's [settings](../settings.md) and seeing what's available to tune, but if you ever want to change a setting for a single binary, you can Open (it) with Options. Go to File -> Open with Options, and any settings you change will apply to only that file.
@@ -21,7 +21,7 @@ Importing IDA IDB (`.idb`) and TIL (`.til`) files into Binary Ninja allows you t
There are two ways through the UI to import IDB and TIL files:
-1. Prior to opening the binary, selecting _Open with Options_, allows you to set the IDB file you want to import with the _External Debug Info File_ setting (`analysis.debugInfo.external`).
+1. Prior to opening the binary, selecting _Open with Options_, allows you to set the IDB file you want to import with the _External Debug Info File_ setting (`analysis.debugInfo.external`).
2. After opening a binary, selecting _Import Debug Info from External File_ (`Analysis\\Import Debug Info from External File...`) allows you to apply IDB/TIL files after analysis has already started.
The following data will be imported:
@@ -31,7 +31,7 @@ The following data will be imported:
## Keybindings
-Most of the keybindings you're used to are the same. Any "actions" (renaming, setting types, opening cross-references, etc) you might want to perform can be found in the [command palette](../index.md#command-palette), which will save you from digging through unfamiliar right-click menus and help you learn any new keybindings. You can even [add your own actions](https://binary.ninja/2024/02/15/command-palette.html#how-do-i-register-actions-with-the-command-palette-myself) with ease. All actions can have their keybinding set, changed, or removed in the [keybindings menu](../index.md#default-hotkeys).
+Most of the keybindings you're used to are the same. Any "actions" (renaming, setting types, opening cross-references, etc.) you might want to perform can be found in the [command palette](../index.md#command-palette), which will save you from digging through unfamiliar right-click menus and help you learn any new keybindings. You can even [add your own actions](https://binary.ninja/2024/02/15/command-palette.html#how-do-i-register-actions-with-the-command-palette-myself) with ease. All actions can have their keybinding set, changed, or removed in the [keybindings menu](../index.md#default-hotkeys).
Some major exceptions are:
diff --git a/docs/guide/sharedcache.md b/docs/guide/sharedcache.md
index be253b1c..e3bb875b 100644
--- a/docs/guide/sharedcache.md
+++ b/docs/guide/sharedcache.md
@@ -1,9 +1,8 @@
# Shared Cache
-Shared cache support in Binary Ninja provides you with tools to selectively load specific images, search for
-specific symbols, and follow analysis references between any images loaded from a `dyld_shared_cache` in one view.
+Shared cache support in Binary Ninja provides you with tools to selectively load specific images, search for specific symbols, and follow analysis references between any images loaded from a `dyld_shared_cache` in one view.
-Our support for `dyld_shared_cache` is largely open source. The supporting code can can be found in our public API repository [here](https://github.com/Vector35/binaryninja-api/tree/dev/view/sharedcache). Instructions for setting up your development environment and building plugins like this yourself can be found in our [Developer Guide](../dev/plugins.md#writing-native-plugins). Contributions are welcome!
+Our support for `dyld_shared_cache` is largely open source. The supporting code can be found in our public API repository [here](https://github.com/Vector35/binaryninja-api/tree/dev/view/sharedcache). Instructions for setting up your development environment and building plugins like this yourself can be found in our [Developer Guide](../dev/plugins.md#writing-native-plugins). Contributions are welcome!
## Support Matrix
@@ -80,7 +79,7 @@ opening a `dyld_shared_cache` and is how you add images to the actual binary vie
=== "Images"
Shows a list of all images within the `dyld_shared_cache` and their virtual addresses.
-
+
- Double click on an image to load
- Select image(s) and click button "Load Selected" to load multiple images at once
- Select image(s) and right click if you want more options for loading images
@@ -93,7 +92,7 @@ opening a `dyld_shared_cache` and is how you add images to the actual binary vie
- Double click on a symbol to load the associated image, or use the "Load Image" button
![Shared Cache Symbols](../img/dsc/triage-symbols.png "Shared Cache Symbols")
-
+
=== "Mappings & Regions"
Shows information about the entry mappings and the cache regions.
diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md
index 392010e2..8ff63d89 100644
--- a/docs/guide/troubleshooting.md
+++ b/docs/guide/troubleshooting.md
@@ -9,7 +9,7 @@
We recommend the following steps to produce the best bug-reports:
-1. Try to reproduce your issue with both the latest stable release as well as [switching](index.md#updates) to the latest development branch.
+1. Try to reproduce your issue with both the latest stable release and [the latest development release](index.md#updates).
2. Try temporarily [disabling plugins](#disabling-plugins)
3. Try temporarily [disabling user settings](#disabling-user-settings)
4. Try temporarily [resetting QSettings](#resetting-qsettings)
@@ -25,9 +25,9 @@ In addition to the above-mentioned method of disabling user-plugins, you can als
### Resetting QSettings
-Some UI features rely on [QSettings](https://doc.qt.io/qt-6/qsettings.html#platform-specific-notes) to save state, window location, etc. You can temporarily reset your QSettings by setting the `BN_QSETTINGS_POSTFIX` environment variable which will cause Binary Ninja to use a different qsettings for that launch.
+Some UI features rely on [QSettings](https://doc.qt.io/qt-6/qsettings.html#platform-specific-notes) to save state, window location, etc. You can temporarily reset your QSettings by setting the `BN_QSETTINGS_POSTFIX` environment variable which will cause Binary Ninja to use a different QSettings for that launch.
-Removing the environment variable or running without it will revert to the default qsettings locations.
+Removing the environment variable or running without it will revert to the default QSettings locations.
### Extra logging
@@ -64,7 +64,7 @@ Binary Ninja will refuse to run as root on Linux and macOS platforms. You can wo
## API
- - If the GUI launches but the license file is not valid when launched from the command-line, check that you're using the right version of Python as only 64-bit Python 2.7, or 3.x versions are supported. Additionally, the [personal][purchase] edition does not support headless operation.
+ - If the GUI launches, but the license file is not valid when launched from the command-line, check that you're using the right version of Python as only 64-bit Python 3.x versions are supported. Additionally, the [personal][purchase] edition does not support headless operation.
## Database Issues
@@ -72,7 +72,7 @@ Binary Ninja will refuse to run as root on Linux and macOS platforms. You can wo
Binary Ninja currently uses SQLite for its analysis databases (`.bndb`), projects (`.bnpr`), and type archives (`.bnta`). This means it is only able to have a single instance of these open at any time.
-The message `Error while saving database snapshot: database is locked` means multiple copies are open at the same time. All instances will need to be closed and a new one opened to allow saving again (this includes syncing to an Enterprise server).
+The message `Error while saving database snapshot: database is locked` means multiple copies are open at the same time. All instances will need to be closed, and a new one opened to allow saving again (this includes syncing to an Enterprise server).
### Large File Size
diff --git a/docs/guide/types/attributes.md b/docs/guide/types/attributes.md
index 1796785d..b4453108 100644
--- a/docs/guide/types/attributes.md
+++ b/docs/guide/types/attributes.md
@@ -4,7 +4,7 @@ There are a number of custom attributes and annotations you can add to types in
## Structure Packing
-Use the attribute `__packed` in a structure definition to indicate that structure fields should be packed without padding. This is similar to `#pragma pack(1)` in MSVC and `__attribute__((packed))` in GCC/Clang.
+Use the attribute `__packed` in a structure definition to indicate that structure fields should be packed without padding. This is similar to `#pragma pack(1)` in MSVC and `__attribute__((packed))` in GCC/Clang.
### Examples
@@ -26,8 +26,8 @@ struct PackedHeader __packed
uint32_t version; /* Offset: 0xA */
void (* callback)(); /* Offset: 0xE */
};
-
-/* These also work, thanks to Clang's broad feature support across targets */
+
+/* These also work, thanks to Clang's broad feature support across targets */
struct __attribute__((packed)) Header
{
uint16_t size; /* Offset: 0x0 */
@@ -78,7 +78,7 @@ See [Working with C++ Types and Virtual Function Tables](cpp.md).
## Functions That Don't Return
-If you know that a function does not return (either via infinite loop, or terminating the process), you can annotate their definition with `__noreturn` to inform the analysis of this. Any calls to these functions will cause disassembly in the caller to stop, assuming execution does not continue.
+If you know that a function does not return (either via infinite loop, or terminating the process), you can annotate their definition with `__noreturn` to inform the analysis of this. Any calls to these functions will cause disassembly in the caller to stop, assuming execution does not continue.
### Examples
@@ -110,7 +110,7 @@ __convention("convention_name")
Due to the nature of parsing with Clang, most dedicated convention keywords are only available on their relevant targets. For example, `__stdcall` and `__fastcall` only apply to X86-based targets.
-If you have a custom calling convention, or one with no dedicated keyword, you can specify the convention name with the `__convention("name")` attribute.
+If you have a custom calling convention, or one with no dedicated keyword, you can specify the convention name with the `__convention("name")` attribute.
### Examples
@@ -164,14 +164,14 @@ int get_twice(int arg) __pure
}
int main()
{
- (void)get_twice(1); /* result is unused, this will be dead code eliminated */
+ (void)get_twice(1); /* result is unused, this will be dead code eliminated */
}
```
## Offset Pointers
Offset pointers, often called shifted pointers, relative pointers, or adjusted pointers, represent a pointer to a structure that has been offset by a certain number of bytes.
-Annotating these offset pointers allows Binary Ninja to deduce types for dereferences through them, find the structure's start, and render proper member names.
+Annotating these offset pointers allows Binary Ninja to deduce types for dereferences through them, find the structure's start, and render proper member names.
These are often seen in intrusive linked lists, where structures have a pointer to the next item in the list, but the pointer is offset from the base of the structure and
instead points to the member containing the pointer to the next item. Iterating through the items in the list involves following the pointer, then shifting the result by the offset
@@ -180,7 +180,7 @@ in any dereferences, and saving a couple instructions.
### Examples
-You will see uses of the offset pointers annotated with `(var - offset)` in IL views and `ADJ(var)` in Pseudo-C.
+You will see uses of the offset pointers annotated with `(var - offset)` in IL views and `ADJ(var)` in Pseudo-C.
``` C
/* High Level IL */
@@ -284,7 +284,7 @@ struct BaseClassDescriptor
};
/* ...results in the following presentation in Linear View */
-struct BaseClassDescriptor type_info::`RTTI Base Class Descriptor at (0,32,4,82)' =
+struct BaseClassDescriptor type_info::`RTTI Base Class Descriptor at (0,32,4,82)' =
{
struct TypeDescriptor* __ptr32 __based(start) pTypeDescriptor = class type_info `RTTI Type Descriptor' { 0x180000000 + 0x11180 }
uint32_t numContainedBases = 0x0
@@ -296,7 +296,7 @@ struct BaseClassDescriptor type_info::`RTTI Base Class Descriptor at (0,32,4,82)
}
```
-You can define structures who reference other structures relative to their variable address in memory. Address references are _relative to the pointer, not the base of the structure._
+You can define structures who reference other structures relative to their variable address in memory. Address references are _relative to the pointer, not the base of the structure._
``` C
/* This structure definition... */
@@ -314,7 +314,7 @@ struct Texture tile_red
{
uint32_t width = 128
uint32_t height = 128
- char* __based(var, 0x10) texNameOffset = string_tile_red { &tile_red->texNameOffset + 0x10 }
+ char* __based(var, 0x10) texNameOffset = string_tile_red { &tile_red->texNameOffset + 0x10 }
uint32_t mask = 0
uint32_t flags = 0
}
@@ -323,9 +323,9 @@ char string_tile_red[9] = "tile_red", 0;
## Pointers with Custom Sizes
-Some structures store pointers with a size different than the platform's address width. For example, a 32-bit image base-relative pointer used on an 64-bit architecture. These sized pointers can be annotated with the `__ptr8`, `__ptr16`, `__ptr32`, `__ptr64`, or `__ptr_width()` attributes.
+Some structures store pointers with a size different from the platform's address width. For example, a 32-bit image base-relative pointer used on an 64-bit architecture. These sized pointers can be annotated with the `__ptr8`, `__ptr16`, `__ptr32`, `__ptr64`, or `__ptr_width()` attributes.
-These are often combined with [Based Pointers](#based-pointers), since pointers smaller than the address width cannot point to parts of memory without being shifted first.
+These are often combined with [Based Pointers](#based-pointers), since pointers smaller than the address width cannot point to parts of memory without being shifted first.
### Examples
diff --git a/docs/guide/types/basictypes.md b/docs/guide/types/basictypes.md
index abebeafe..dcfd36f6 100644
--- a/docs/guide/types/basictypes.md
+++ b/docs/guide/types/basictypes.md
@@ -79,7 +79,7 @@ Types in the list have their class indicated by icons:
#### Type Containers
-All of the type containers described in the [type introduction](index.md) are available in the Types View along with `User Types` in a section of its own.
+All the type containers described in the [type introduction](index.md) are available in the Types View along with `User Types` in a section of its own.
* **User Types**: In your analysis: Types created by you, either manually or through actions/plugins
* **System Types**: In your analysis: Types created by analysis or imported during analysis, such as from Libraries or Debug Info
@@ -129,4 +129,4 @@ the name of a type will take you to its definition.
### Structure Offset Annotations
-The Types view annotates code references to structure offsets if a structure member is not present. These annotations use the same convention as in the graph/linear view, showing the offset position and width. For example, the `__offset(0x8).q` token means the code references the offset 0x8 bytes into this structure, and the size of the access is a qword (8 bytes). You can press S on an offset annotation and a structure member of the appropriate type will be created there. Additionally, if you right click the structure name, you can choose to create all of these references.
+The Types view annotates code references to structure offsets if a structure member is not present. These annotations use the same convention as in the graph/linear view, showing the offset position and width. For example, the `__offset(0x8).q` token means the code references the offset 0x8 bytes into this structure, and the size of the access is a qword (8 bytes). You can press S on an offset annotation and a structure member of the appropriate type will be created there. Additionally, if you right-click the structure name, you can choose to create all of these references.
diff --git a/docs/guide/types/cpp.md b/docs/guide/types/cpp.md
index 455e59fd..c803a926 100644
--- a/docs/guide/types/cpp.md
+++ b/docs/guide/types/cpp.md
@@ -398,13 +398,13 @@ Now, go to the data section and apply the virtual function table structures to t
virtual function tables themselves:
``` C
-00004020 struct vtable_for_Animal _vtable_for_Animal =
+00004020 struct vtable_for_Animal _vtable_for_Animal =
00004020 {
00004020 void (* make_sound)(struct Animal* this) = nullptr
00004028 void (* approach)(struct Animal* this) = Animal::approach()
00004030 }
-00004050 struct vtable_for_Flying _vtable_for_Flying =
+00004050 struct vtable_for_Flying _vtable_for_Flying =
00004050 {
00004050 void (* fly)(struct Flying* this) = Flying::fly
00004058 }
@@ -473,20 +473,20 @@ Apply the new virtual function table structures to the virtual function tables i
the data section:
``` C
-00004078 struct vtable_for_Dog _vtable_for_Dog =
+00004078 struct vtable_for_Dog _vtable_for_Dog =
00004078 {
00004078 void (* make_sound)(struct Animal* this) = Dog::make_sound()
00004080 void (* approach)(struct Animal* this) = Animal::approach()
00004088 }
-000040b0 struct vtable_for_Cat _vtable_for_Cat =
+000040b0 struct vtable_for_Cat _vtable_for_Cat =
000040b0 {
000040b0 void (* make_sound)(struct Animal* this) = Cat::make_sound
000040b8 void (* approach)(struct Animal* this) = Cat::approach()
000040c0 void (* nap)(struct Cat* this) = Cat::nap()
000040c8 }
-000040f0 struct vtable_for_Lion _vtable_for_Lion =
+000040f0 struct vtable_for_Lion _vtable_for_Lion =
000040f0 {
000040f0 void (* make_sound)(struct Animal* this) = Lion::make_sound
000040f8 void (* approach)(struct Animal* this) = Cat::approach()
@@ -543,13 +543,13 @@ Apply the virtual function table structures to the corresponding virtual functio
data section:
``` C
-00004130 struct vtable_for_Bird_as_Animal _vtable_for_Bird_as_Animal =
+00004130 struct vtable_for_Bird_as_Animal _vtable_for_Bird_as_Animal =
00004130 {
00004130 void (* make_sound)(struct Animal* this) = Bird::make_sound()
00004138 void (* approach)(struct Animal* this) = Bird::approach()
00004140 }
-00004150 struct vtable_for_Bird_as_Flying _vtable_for_Bird_as_Flying =
+00004150 struct vtable_for_Bird_as_Flying _vtable_for_Bird_as_Flying =
00004150 {
00004150 void (* fly)(struct Flying* this) = Flying::fly
00004158 }
diff --git a/docs/guide/types/debuginfo.md b/docs/guide/types/debuginfo.md
index 5468bb6c..501e0b67 100644
--- a/docs/guide/types/debuginfo.md
+++ b/docs/guide/types/debuginfo.md
@@ -1,8 +1,8 @@
# Debug Info
-Debug Info is a mechanism for importing types, function signatures, and data variables from either the original binary (eg. an ELF compiled with DWARF) or a supplemental file (eg. a PDB).
+Debug Info is a mechanism for importing types, function signatures, and data variables from either the original binary (e.g. an ELF compiled with DWARF) or a supplemental file (e.g. a PDB).
-Currently debug info plugins are limited to types, function signatures, and data variables, but in the future will include line number information, comments, local variables, and possibly more.
+Currently, debug info plugins are limited to types, function signatures, and data variables, but in the future will include line number information, comments, local variables, and possibly more.
## Supported Debug Info
@@ -10,7 +10,7 @@ We currently support [PDBs](https://github.com/Vector35/binaryninja-api/tree/dev
For PDBs, Binary Ninja will automatically try to source from specified local folders and Microsoft's symbol server ([see the PDB settings for more information](../settings.md#settings-reference)).
-DWARF supports information compiled in to ELF binaries, information from external ELF files (`.dwo`, `.debug`, etc), information compiled in to Mach-O's, and information from external `.dSYM` files as well. Support for DWARF information in PEs is [planned](https://github.com/Vector35/binaryninja-api/issues/1555).
+DWARF supports information compiled in to ELF binaries, information from external ELF files (`.dwo`, `.debug`, etc.), information compiled in to Mach-O's, and information from external `.dSYM` files as well. Support for DWARF information in PEs is [planned](https://github.com/Vector35/binaryninja-api/issues/1555).
## Applying Debug Info
@@ -34,13 +34,13 @@ DWARF information is imported from files that contain DWARF sections. Currently,
#### DWARF Import Limitations
-[DWARF version 5](https://dwarfstd.org/dwarf5std.html) is mostly backwards compatible with DWARF version 4, which we originally targetted with our DWARF import plugin, with the caveats descibed in [this issue](https://github.com/Vector35/binaryninja-api/issues/5423).
+[DWARF version 5](https://dwarfstd.org/dwarf5std.html) is mostly backwards compatible with DWARF version 4, which we originally targeted with our DWARF import plugin, with the caveats described in [this issue](https://github.com/Vector35/binaryninja-api/issues/5423).
Components are supported by the API, but not in the parser. The [same issue](https://github.com/Vector35/binaryninja-api/issues/5423) as above would also allow us to support components more easily as well.
#### DWARF Export Limitations
-Our [DWARF Export plugin](https://github.com/Vector35/binaryninja-api/tree/dev/plugins/dwarf/dwarf_export) is also open source and uses a different system from our debug information import plugins. It also does not support function-local variable names or types. The export plugin currently will export the global variables, function prototypes, and all the types in your binary view except for ones that are FunctionTypeClass or VarArgsTypeClass.
+Our [DWARF Export plugin](https://github.com/Vector35/binaryninja-api/tree/dev/plugins/dwarf/dwarf_export) is also open source and uses a different system from our debug information import plugins. It also does not support function-local variable names or types. The export plugin currently will export the global variables, function prototypes, and all the types in your binary view except for ones that are `FunctionTypeClass` or `VarArgsTypeClass`.
#### Special Note for `.dSYM` Files
diff --git a/docs/guide/types/index.md b/docs/guide/types/index.md
index 7abcae64..375533af 100644
--- a/docs/guide/types/index.md
+++ b/docs/guide/types/index.md
@@ -10,7 +10,7 @@ There's so many things to learn about working with Types in Binary Ninja that we
Additionally, several types of containers for type information are documented here:
- [Debug Info](debuginfo.md): Debug Info can provide additional type information (examples include DWARF and PDB files)
-- [Type Libraries](typelibraries.md): Type Libraries contain types from commonly-used dynamic libraries
+- [Type Libraries](typelibraries.md): Type Libraries contain types from commonly-used dynamic libraries
- [Platform Types](platformtypes.md): Types that automatically apply to a platform
- [Type Archives](typearchives.md): How you can use type archives to share types between analysis databases
- [Signature Libraries](../../dev/annotation.md#signature-libraries): Signature libraries are used to match names of functions with signatures for code that is statically compiled
diff --git a/docs/guide/types/platformtypes.md b/docs/guide/types/platformtypes.md
index 286615e6..cf1b8fc4 100644
--- a/docs/guide/types/platformtypes.md
+++ b/docs/guide/types/platformtypes.md
@@ -3,9 +3,9 @@
Binary Ninja pulls type information from a variety of sources. The highest-level source are the platform types loaded for the given platform (which includes operating system and architecture). There are two sources of platform types. The first are shipped with the product in a [binary path](../index.md#directories). The second location is in your [user folder](../index.md#user-folder) and is intended for you to put custom platform types.
???+ Danger "Warning"
- Do NOT make changes to platform types in the binary path as they will be overwritten any time Binary Ninja updates.
+ Do NOT make changes to platform types in the binary path as they will be overwritten any time Binary Ninja updates.
-Platform types are used to define types that should be available to all programs available on that particular platform. They are only for global common types. Consider, for example, that you might want to add the following on windows:
+Platform types are used to define types that should be available to all programs available on that particular platform. They are only for global common types. Consider, for example, that you might want to add the following on Windows:
```
typedef uint8_t u8;
@@ -17,7 +17,7 @@ You could write this type into:
/home/user/.binaryninja/types/platform/windows-x86.c
```
-And any time you opened a 32bit windows binary, that type would be available to use. However, please note that these are not substitutes for [Type Libraries](../../dev/annotation.md#type-libraries). Type Libraries are used to provide a collection of types for a given library such as a libc, or common DLL.
+And any time you opened a 32bit windows binary, that type would be available to use. However, please note that these are not substitutes for [Type Libraries](../../dev/annotation.md#type-libraries). Type Libraries are used to provide a collection of types for a given library such as a libc, or common DLL.
???+ Warning "Tip"
If you don't know the specific platform (and thus filename) you need to create for a given file, just enter `bv.platform` in the scripting console.
@@ -26,7 +26,7 @@ And any time you opened a 32bit windows binary, that type would be available to
You may wish to provide types that are common across multiple architectures or platforms. The easiest way to do this is to use a `#include "filename.c"` line in the specific platform so that any common types will be loaded.
-The base path for these files is in your [user folder](../index.md#user-folder) inside of a "types/platform" subfolder.
+The base path for these files is in your [user folder](../index.md#user-folder) inside a "types/platform" subfolder.
For example, something like:
diff --git a/docs/guide/types/type.md b/docs/guide/types/type.md
index b3ab9f09..9b0306b4 100644
--- a/docs/guide/types/type.md
+++ b/docs/guide/types/type.md
@@ -33,7 +33,7 @@ When used on an integer, all matching enumeration members will be shown.
1. Name of currently selected enum
1. Checkbox (set by default) that hides enums with no matching members for the current integer.
-However in instances where the hotkey is used on other variables, the display will only be used to apply the enum type to the selection and does not allow editing.
+However, in instances where the hotkey is used on other variables, the display will only be used to apply the enum type to the selection and does not allow editing.
## Union Field Resolution
@@ -61,7 +61,7 @@ typedef struct
This is a tagged union; there's an enum defining the different variants of the union, and then the actual union variants/members. The union should take up as much space as the largest variant, so in this case it will usually be 8 bytes (depends on the target machine's pointer width), but only one variant can occupy those bytes at a time.
-When you apply a union type to a variable, you can use the "Field Resolution" option in the right-click menu to change which variant is used for a given instruction.
+When you apply a union type to a variable, you can use the "Field Resolution" option in the right-click menu to change which variant is used for a given instruction.
![Field Resolution Menu](../../img/select-union-field-resolution.png "Field Resolution Menu")
@@ -125,4 +125,4 @@ This also works within data variables with structure type. For example, if the s
Many characters commonly used in function naming are not valid C characters. For example, `::` in C++ types, braces or brackets. While we use clang's type-parser for such APIs as [parse_type_string](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryView.parse_type_string) (note there's also [another version](https://api.binary.ninja/binaryninja.typeparser-module.html#binaryninja.typeparser.TypeParser.parse_type_string) of that API independent of the BinaryView off of the TypeParser module).
-To resolve this, we use `` ` `` (the backtick character) to enclose strings that should be treated as atomic units in the type-parser. You may notice this yourself if you by creating a struct with `:` in the name and then using `n` on the variable to see how it is escaped in the change name dialog.
+To resolve this, we use `` ` `` (the backtick character) to enclose strings that should be treated as atomic units in the type-parser. You may notice this yourself if you create a struct with `:` in the name and then use `n` on the variable to see how it is escaped in the change name dialog.
diff --git a/docs/guide/types/typeimportexport.md b/docs/guide/types/typeimportexport.md
index 43fbfa90..c245deef 100644
--- a/docs/guide/types/typeimportexport.md
+++ b/docs/guide/types/typeimportexport.md
@@ -21,7 +21,7 @@ This feature enables a number of workflows:
### Porting Analysis Between Target Versions
-If you're working with version 1 of a file which has symbols and you now want to port your work over to version 2 (as long as they both have symbols). This isn't going to be perfect as this feature isn't interactive and doesn't take into account changes in parameter counts or ordering, so *use this with caution*.
+If you're working with version 1 of a file which has symbols, and you now want to port your work over to version 2 (as long as they both have symbols). This isn't going to be perfect as this feature isn't interactive and doesn't take into account changes in parameter counts or ordering, so *use this with caution*.
### Quickly Defining Externs
@@ -35,17 +35,17 @@ If you already have a collection of headers containing types you want to use, yo
- `-I<path>` for various user header paths
- `-D<macro>=<value>` for macro definitions
- `-x c -std=c99` to specify C99 mode
-- Other Clang-compatible command-line flags are accepted (eg `-fms-extensions`, `-fms-compatibility`, etc)
+- Other Clang-compatible command-line flags are accepted (e.g. `-fms-extensions`, `-fms-compatibility`, etc.)
You can specify that types from system headers, accessed via `#include <header.h>`, will be in the results. Otherwise, only files from user headers, accessed via `#include "header.h"` will be used.
-You can also specify Define Binary Ninja Macros, which makes the type parser include the various parser extensions that Binary Ninja allows in the Type View editors, eg `__packed`, `__padding`, `__syscall`, etc. You probably only want to use this option when importing a header file exported using [Export Header File](#export-header-file).
+You can also specify Define Binary Ninja Macros, which makes the type parser include the various parser extensions that Binary Ninja allows in the Type View editors, e.g. `__packed`, `__padding`, `__syscall`, etc. You probably only want to use this option when importing a header file exported using [Export Header File](#export-header-file).
After specifying the file(s) and flag(s), pressing Preview will give a list of all the types and functions defined in the file(s). You may check or uncheck the box next to any of the types/functions to control whether they will be imported to your analysis.
If there were any parse errors, those will be shown instead of a list of types. Generally speaking, what this means is you're missing either header search paths or compile definitions. See the section below on [finding system headers](#finding-system-headers).
-After pressing Import, all the checked types/functions will be added to your analysis. Imported types will override any existing types you had defined so they are disabled by default as indicated via the `Exists Already` column. Imported functions will replace signatures of any functions in your analysis whose name matches signatures found in the header.
+After pressing Import, all the checked types/functions will be added to your analysis. Imported types will override any existing types you had defined, so they are disabled by default as indicated via the `Exists Already` column. Imported functions will replace signatures of any functions in your analysis whose name matches signatures found in the header.
![Importing a header file](../../img/import-header.png "Importing a header file")
@@ -105,7 +105,7 @@ From this example, the flags would be:
##### For Windows
-For windows, there's no easy command to list all the include paths so you have to piece them together from the `Include Directory` property in a Visual Studio project. You also want to include `-x c -std=c99` since Windows headers include lots of C++ types that the type importer currently does not support.
+For windows, there's no easy command to list all the include paths, so you have to piece them together from the `Include Directory` property in a Visual Studio project. You also want to include `-x c -std=c99` since Windows headers include lots of C++ types that the type importer currently does not support.
You will end up with something like the following for user mode:
@@ -136,7 +136,7 @@ Note that some header files might require manually including a specific `windows
##### Cross-Platform Targets
-If you are analyzing a target that is for a different operating system, you need to both find the header include paths for that system, and copy (or mount) them to a location accessible by the computer running Binary Ninja.
+If you are analyzing a target that is for a different operating system, you need to both find the header include paths for that system, and copy (or mount) them to a location accessible by the computer running Binary Ninja.
### Export Header File
@@ -147,9 +147,9 @@ If you want to compile code using the structures you defined during your analysi
Binary Ninja pulls type information from a variety of sources. The highest-level source are the platform types loaded for the given platform (which includes operating system and architecture). There are two sources of platform types. The first are shipped with the product in a [binary path](../index.md#directories). The second location is in your [user folder](../index.md#user-folder) and is intended for you to put custom platform types.
???+ Danger "Warning"
- Do NOT make changes to platform types in the binary path as they will be overwritten any time Binary Ninja updates.
+ Do NOT make changes to platform types in the binary path as they will be overwritten any time Binary Ninja updates.
-Platform types are used to define types that should be available to all programs available on that particular platform. They are only for global common types. Consider, for example, that you might want to add the following on windows:
+Platform types are used to define types that should be available to all programs available on that particular platform. They are only for global common types. Consider, for example, that you might want to add the following on Windows:
```
typedef uint8_t u8;
@@ -161,7 +161,7 @@ You could write this type into:
/home/user/.binaryninja/types/platform/windows-x86.c
```
-And any time you opened a 32bit windows binary, that type would be available to use. However, please note that these are not substitutes for [Type Libraries](../../dev/annotation.md#type-libraries). Type Libraries are used to provide a collection of types for a given library such as a libc, or common DLL.
+And any time you opened a 32bit Windows binary, that type would be available to use. However, please note that these are not substitutes for [Type Libraries](../../dev/annotation.md#type-libraries). Type Libraries are used to provide a collection of types for a given library such as a libc, or common DLL.
???+ Warning "Tip"
If you don't know the specific platform (and thus filename) you need to create for a given file, just enter `bv.platform` in the scripting console.
diff --git a/docs/guide/warp.md b/docs/guide/warp.md
index 1872f5d7..1c097515 100644
--- a/docs/guide/warp.md
+++ b/docs/guide/warp.md
@@ -11,8 +11,8 @@ The bundled plugin is open source and is located [here](https://github.com/Vecto
## How WARP Works
-WARP works by making a function GUID based off the byte contents of the function. Because WARP creates this GUID based
-off the byte contents, the functions are expected to be an exact match, aside from variant instructions.
+WARP works by making a function GUID based off the byte contents of the function. Because WARP creates this GUID based
+off the byte contents, the functions are expected to be an exact match, aside from variant instructions.
To use WARP, you only need to know that the function GUID's must match across binaries for the function information to be considered.
To read more about how WARP works, please see the GitHub repository [here](https://github.com/vector35/warp).
@@ -45,13 +45,13 @@ Files are automatically loaded from two locations when Binary Ninja starts:
- [User Directory] + `/signatures/`
- Can be disabled using the setting `analysis.warp.loadUserFiles`.
-???+ Danger "Warning"
+???+ Danger "Warning"
Always place your signature libraries in your user directory. The installation path is wiped whenever Binary Ninja auto-updates. You can locate it with `Open Plugin Folder` in the command palette and navigate "up" a directory.
### Manually
-Aside from using the signature directory you can load any WARP file manually using the
-command `WARP\\Load File` or via the UI sidebar, they both do the same thing. Once the file is
+Aside from using the signature directory you can load any WARP file manually using the
+command `WARP\\Load File` or via the UI sidebar, they both do the same thing. Once the file is
loaded, you do not need to load if for every view, it is available globally.
???+ Info "Tip"
@@ -65,23 +65,23 @@ Before you actually can create these WARP files, you must identify the binary fi
that is done, you can determine which of the following procedures is best:
=== "From the current view"
- You can create signatures for the current view by running the
- command `WARP\\Create\\From View` or by hitting the associated
+ You can create signatures for the current view by running the
+ command `WARP\\Create\\From View` or by hitting the associated
button in the WARP sidebar.
![From View](../img/warp/create_from_view.png "From View")
=== "From a file"
Using the command `WARP\\Create\\From File(s)` you can create
- a signature file for an external file. This is useful if you
+ a signature file for an external file. This is useful if you
are generating signatures for library files (`.a`, `.lib`, `.rlib`).
![From File](../img/warp/create_from_file.png "From File")
=== "From the current project"
- When dealing with a large dataset, you will want a way to process
- files in parallel, using the `WARP\\Create\\From Project` command
- you can generate signatures for any set of files in a project, this
+ When dealing with a large dataset, you will want a way to process
+ files in parallel, using the `WARP\\Create\\From Project` command
+ you can generate signatures for any set of files in a project, this
includes archive formats like library files (`.a`, `.lib`, `.rlib`).
![From Project](../img/warp/create_from_project.png "From Project")
@@ -108,7 +108,7 @@ will be prompted whether you want to keep the existing data, you will want to sa
### File size
-Information in the WARP file will be deduplicated across all processed files automatically.
+Information in the WARP file will be deduplicated across all processed files automatically.
If your files are too large, try and adjust the file data to something like "Symbols" only, and if you are looking to
make the files load quicker, turn off compression.
@@ -182,13 +182,13 @@ to provide an inexpensive base layer of function matching and an open source fil
### Why does the exact same function have a different function GUID?
-Using the render layer, you can identify differences in the two functions guid construction:
+Using the render layer, you can identify differences in the two functions GUID construction:
- Highlighted red is "variant instruction"
- Highlighted yellow is "computed variant instruction"
- Highlighted black is "blacklisted instruction"
-The function guid will differ if the instruction highlights are not exactly the same across all instructions in both functions.
+The function GUID will differ if the instruction highlights are not exactly the same across all instructions in both functions.
![Render Layer](../img/warp/render_layer.png "Render Layer")