summaryrefslogtreecommitdiff
path: root/docs/dev/bnil-hlil.md
blob: ea006547d11ccd80cd2618ab44810ecb11a457f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Binary Ninja Intermediate Language: High Level IL

The High Level Intermediate Language (HLIL) is Binary Ninja's decompiler output. Much like [LLIL](./bnil-llil.md) and [MLIL](./bnil-mlil.md), this representation is tree based and has many of the same instructions. This representation is distinct in a few key ways.

![BNIL-HLIL Selected](../img/BNIL-hlil.png)

1. High level language concepts are recovered.
1. Expressions are folded

## Purposes of HLIL

* Simplified representation
* Small discrete operations
* Enables source-level forms of queries and analysis

## Debug Report

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")
```

![HLIL Debug Report](../img/hlil-debug-report.png)

## The Instruction Set

The instruction set is made up of [`HighLevelILInstruction`](https://api.binary.ninja/binaryninja.highlevelil-module.html#binaryninja.highlevelil.HighLevelILInstruction) objects. Let's start exploring by using the python console to poke around at some instructions. Open up a binary in Binary Ninja and retrieve an HLIL instruction:+

```
>>> current_il_instruction
<HighLevelILVarInit: uint64_t rax_2 = zx.q(rax_1 - 0x6c)>
>>> type(current_il_instruction)
<class 'binaryninja.highlevelil.HighLevelILVarInit'>
```

`current_il_instruction` is mapped to whatever il instruction is currently selected viewed and is not generally available to those writing plugins or scripts. You can see a full list of our [magic variables here](../guide/index.md#magic-console-variables).

There are a number of properties that can be queried on the [`HighLevelILInstruction`](https://api.binary.ninja/binaryninja.highlevelil-module.html#binaryninja.highlevelil.HighLevelILInstruction) object, and the validity of these properties changes depending on what the current operation is. The properties in HLIL are extremely similar to those in MLIL, with one notable exception being that `HLIL_CALL` instruction objects do not have a `.output` property, but instead `HLIL_CALL`s that have return values will be the `inst.right` of a `HighLevelILVarInit`, `HighLevelILVarAssign`, or similar.


### Control Flow

* `HLIL_JUMP` - Branch to the `dest` expression's address
* `HLIL_CALL` - Branch to the `dest` expression function, saving the return address, with the list of parameters `params`
* `HLIL_RET` - Return to the calling function.
* `HLIL_NORET` - This instruction will never be executed, the instruction before it is a call that doesn't return
* `HLIL_IF` - Branch to the `true`/`false` HLIL instruction identifier depending on the result of the `condition` expression
* `HLIL_GOTO` - Branch to the `dest` expression id
* `HLIL_TAILCALL` - This instruction calls the expression `dest` using `params` as input and `output` for return values
* `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` -

### 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_VAR` - A variable expression `src`
* `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`
* `HLIL_CONST_DATA` - A constant data reference `constant data reference`
* `HLIL_CONST_PTR` - A constant integral value which is used as a pointer `constant`
* `HLIL_EXTERN_PTR` - A symbolic pointer `constant` + `offset` to a symbol that exists outside the binary
* `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_SPLIT` - A split pair of variables `high`:`low` which can be used a single expression
* `HLIL_DEREF` - Dereferences `src`
* `HLIL_DEREF_FIELD` -

### Arithmetic Operations

* `HLIL_ADD` - Adds `left` expression to `right` expression
* `HLIL_ADC` - Adds with carry the `left` expression to the `right` expression with carry from the `carry` expression
* `HLIL_SUB` - Subtracts the `right` expression from the `left` expression
* `HLIL_SBB` - Subtraction with borrow the `right` expression from the `left` expression with carry from the `carry` expression
* `HLIL_AND` - Bitwise AND `left` expression with the `right` expression
* `HLIL_OR` - Bitwise OR `left` expression with the `right` expression
* `HLIL_XOR` - Bitwise XOR `left` expression with the `right` expression
* `HLIL_LSL` - Logical shift left the `left` expression by the number of bits stored in the `right` expression
* `HLIL_LSR` - Logical shift right the `left` expression by the number of bits stored in the `right` expression
* `HLIL_ASR` - Arithmetic shift right the `left` expression by the number of bits stored in the `right` expression
* `HLIL_ROL` - Rotate left the `left` expression by the number of bits stored in the `right` expression
* `HLIL_RLC` - Rotate left with carry the `left` expression and the `carry` expression by the number of bits stored in the `right` expression
* `HLIL_ROR` - Rotate right the `left` expression by the number of bits stored in the `right` expression
* `HLIL_RRC` - Rotate right with carry the `left` expression and the `carry` expression by the number of bits stored in the `right` expression
* `HLIL_MUL` - Single-precision multiply the `left` expression with the `right` expression
* `HLIL_MULU_DP` - Double-precision unsigned multiply the `left` expression with the `right` expression, result expression is twice the size of the input expressions
* `HLIL_MULS_DP` - Double-precision signed multiply the `left` expression with the `right` expression, result expression is twice the size of the input expressions
* `HLIL_DIVU` - Unsigned single-precision divide `left` expression by the `right` expression
* `HLIL_DIVU_DP` - Unsigned double-precision divide `left` expression by the `right` expression
* `HLIL_DIVS` - Signed single-precision divide `left` expression by the `right` expression
* `HLIL_DIVS_DP` - Signed double-precision divide `left` expression by the `right` expression
* `HLIL_MODU` - Unsigned single-precision modulus of `left` expression by the `right` expression
* `HLIL_MODU_DP` - Unsigned double-precision modulus of `left` expression by the `right` expression
* `HLIL_MODS` - Signed single-precision modulus of `left` expression by the `right` expression
* `HLIL_MODS_DP` - Signed double-precision modulus of `left` expression by the `right` expression
* `HLIL_NEG` - Sign inversion of `src` expression
* `HLIL_NOT` - Bitwise inversion of `src` expression
* `HLIL_FADD` - IEEE754 floating point addition of `left` expression with `right` expression
* `HLIL_FSUB` - IEEE754 floating point subtraction of `left` expression with `right` expression
* `HLIL_FMUL` - IEEE754 floating point multiplication of `left` expression with `right` expression
* `HLIL_FDIV` - IEEE754 floating point division of `left` expression with `right` expression
* `HLIL_FSQRT` - IEEE754 floating point square root of `left` expression with `right` expression
* `HLIL_FNEG` - IEEE754 floating point sign negation of `src` expression
* `HLIL_FABS` - IEEE754 floating point absolute value of `src` expression
* `HLIL_FLOAT_TO_INT` - IEEE754 floating point to integer conversion of `src` expression
* `HLIL_INT_TO_FLOAT` - Integer to IEEE754 floating point conversion of `src` expression
* `HLIL_FLOAT_CONV` - Convert bytes in `src` expression to IEEE754 floating point
* `HLIL_ROUND_TO_INT` - Rounds the IEEE754 floating point number `src` expression
* `HLIL_FLOOR` - Computes the floating point floor of the IEEE754 number in `src`
* `HLIL_CEIL` - Computes the floating point floor of the IEEE754 number in `src`
* `HLIL_FTRUNC` - Computes the floating point truncation of the IEEE754 number in `src`
* `HLIL_SX` - Sign extends the `src` expression
* `HLIL_ZX` - Zero extends the `src` expression
* `HLIL_ADD_OVERFLOW` - Calculates overflow of the addition of `left` expression with `right` expression
* `HLIL_BOOL_TO_INT` - Converts a bool `src` to an integer

### Comparison Instructions

* `HLIL_CMP_E` - Compare expression evaluates to true if `left` expression is equal to `right`
* `HLIL_CMP_NE` - Compare expression evaluates to true if `left` expression is not equal to `right`
* `HLIL_CMP_SLT` - Compare expression evaluates to true if `left` expression is signed less than `right`
* `HLIL_CMP_ULT` - Compare expression evaluates to true if `left` expression is unsigned less than `right`
* `HLIL_CMP_SLE` - Compare expression evaluates to true if `left` expression is signed less than or equal to `right`
* `HLIL_CMP_ULE` - Compare expression evaluates to true if `left` expression is unsigned less than or equal to `right`
* `HLIL_CMP_SGE` - Compare expression evaluates to true if `left` expression is signed greater than or equal to `right`
* `HLIL_CMP_UGE` - Compare expression evaluates to true if `left` expression is unsigned greater than or equal to `right`
* `HLIL_CMP_SGT` - Compare expression evaluates to true if `left` expression is signed greater than `right`
* `HLIL_CMP_UGT` - Compare expression evaluates to true if `left` expression is unsigned greater than `right`
* `HLIL_TEST_BIT` - Test if bit `right` in expression `left` is set
* `HLIL_FCMP_E` - Floating point compare expressions - evaluates to true if `left` expression is equal to `right`
* `HLIL_FCMP_NE` - Floating point compare expressions - evaluates to true if `left` expression is not equal to `right`
* `HLIL_FCMP_LT` - Floating point compare expressions - evaluates to true if `left` expression is less than `right`
* `HLIL_FCMP_LE` - Floating point compare expressions - evaluates to true if `left` expression is less than or equal to `right`
* `HLIL_FCMP_GE` - Floating point compare expressions - evaluates to true if `left` expression is greater than or equal to `right`
* `HLIL_FCMP_GT` - Floating point compare expressions - evaluates to true if `left` expression is greater than `right`
* `HLIL_FCMP_O` - Floating point compare expressions - evaluates to true if both `left` and `right` expressions are ordered (not NaN)
* `HLIL_FCMP_UO` - Floating point compare expressions - evaluates to true if either `left` or `right` expression is unordered (NaN)

### Miscellaneous Instructions

* `HLIL_NOP` - No operation
* `HLIL_BP` - Breakpoint instruction
* `HLIL_TRAP` - Interrupt/trap instruction with `vector` expression
* `HLIL_INTRINSIC` - Intrinsic instruction defined by the architecture
* `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` -