summaryrefslogtreecommitdiff
path: root/docs/dev/bnil-llil.md
diff options
context:
space:
mode:
authorJordan Wiens <github@psifertex.com>2026-05-27 14:55:28 -0400
committerJordan Wiens <github@psifertex.com>2026-05-27 14:55:28 -0400
commit162b406ea28aa5bacc34a00745d8780bcbf58753 (patch)
tree39802866489bd352c54599024e24ee346b44cd35 /docs/dev/bnil-llil.md
parentf2ae12d97604da6136b26c184eb7fe30531b4d5e (diff)
add better syntax highlighting for code blocks
Diffstat (limited to 'docs/dev/bnil-llil.md')
-rw-r--r--docs/dev/bnil-llil.md32
1 files changed, 16 insertions, 16 deletions
diff --git a/docs/dev/bnil-llil.md b/docs/dev/bnil-llil.md
index 2ac1e77f..5509151e 100644
--- a/docs/dev/bnil-llil.md
+++ b/docs/dev/bnil-llil.md
@@ -21,7 +21,7 @@ Since doing is the easiest way to learn let's start with a simple example binary
Next, enter the following in the console:
-```
+```pycon
>>> for block in current_function.low_level_il:
... for instr in block:
... print (instr.address, instr.instr_index, instr)
@@ -43,7 +43,7 @@ Finally, we can print out the attributes of the instruction. We first print out
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:
-```
+```pycon
>>> list(current_function.low_level_il)
[<block: x86_64@0x0-0x3f>, <block: x86_64@0x3f-0x45>, <block: x86_64@0x45-0x47>,
<block: x86_64@0x47-0x53>, <block: x86_64@0x53-0x57>, <block: x86_64@0x57-0x5a>]
@@ -56,13 +56,13 @@ In python, iterating over a class is a distinct operation from subscripting. Thi
## 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:
-```
+```text
eax = eax + ecx * 4
```
The tree for such an instruction would look like:
-```
+```text
=
/ \
eax +
@@ -75,7 +75,7 @@ There are quite a few reasons that we chose to use expression trees that we won'
Now let's get back to the examples. First let's pick an instruction to work with:
-```
+```pycon
>>> instr = current_function.low_level_il[2]
>>> instr
<il: rsp = rsp - 0x110>
@@ -85,63 +85,63 @@ For the above instruction, we have a few operations we can perform:
* **address** - returns the virtual address
-```
+```pycon
>>> hex(instr.address)
'0x40084aL'
```
* **function** - returns the containing function
-```
+```pycon
>>> instr.function
<binaryninja.lowlevelil.LowLevelILFunction object at 0x111c79810>
```
* **instr_index** - returns the LLIL index
-```
+```pycon
>>> instr.instr_index
2
```
* **operands** - returns a list of all operands.
-```
+```pycon
>>> instr.operands
['rsp', <il: rsp - 0x110>]
```
* **operation** - returns the enumeration value of the current operation
-```
+```pycon
>>> instr.operation
<LowLevelILOperation.LLIL_SET_REG: 1>
```
* **src** - returns the source operand
-```
+```pycon
>>> instr.src
<il: rsp - 0x110>
```
* **dest** - returns the destination operand
-```
+```pycon
>>> instr.dest
'rsp'
```
* **size** - returns the size of the operation in bytes (in this case we have an 8 byte assignment)
-```
+```pycon
>>> instr.size
8L
```
Now with some knowledge of the `LowLevelIL` class let's try to do something with it. Let's say our goal is to find all the times the register `rdx` is written to in the current function. This code is straight forward:
-```
+```pycon
>>> for block in current_function.low_level_il:
... for instr in block:
... if instr.operation == LowLevelILOperation.LLIL_SET_REG and instr.dest.name == 'rdx':
@@ -187,14 +187,14 @@ Control flow transferring- and comparison instructions are straightforward enoug
Labels function much like they do in C code. They can be put anywhere in the emitted IL and serve as a destination for the `if` and `goto` instructions. Labels are required because one assembly language instruction can translate to multiple IL instructions, and you need to be able to branch to any of the emitted IL instructions. Let's consider the following x86 instruction `cmove` (Conditional move if equal flag is set):
-```
+```nasm
test eax, eax
cmove eax, ebx
```
To translate this instruction to IL we have to first create true and false labels. Then we emit the `if` instruction, passing it the proper conditional and labels. Next we emit the true label, then we emit the set register instruction and a goto false label instruction. This results in the following output:
-```
+```text
0 @ 00000002 if (eax == 0) then 1 else 3
1 @ 00000002 eax = ebx
2 @ 00000002 goto 3