intro to radare2 ESIL guide
===========================
- What is ESIL? At a glance
- How do we read ESIL?
- How do we use ESIL?
- What is ESIL used for?
- How does ESIL compare to other ILs?
- Errata
- References
- Cool Projects
ESIL stands for 'Evaluable Strings Intermediate Language'. It is a stack based IL where each ESIL expression represents an individual instruction. Commands are separated by commas and read from left-to-right in post-fix notation.
What does the ESIL virtual machine look like?
Pseudocode for the ESIL VM is generally described as:
while word = haveCommand():
if word.isOperator():
esilOperators[word](vm)
else:
vm.push(word)
nextCommand()
There are two categories of inputs:
- values - A value gets pushed to the stack
- operators - An operator pops the values (arguments) off the stack, does some work, then pushes the result.
Example ESIL expression (post-fix):
4,esp,-=,ebp,esp,=[4]
ESIL expression converted to in-fix:
esp -= 4 // raise esp by 4
4 bytes [esp] = ebp // write the value of ebp [size of dword (4 bytes)] to top of stack
We have push ebp
!
How do we view ESIL expressions in r2?
Display ESIL information
[0x00000000]> e emu.str = true
Only view ESIL expressions instead of assembly
[0x00000000]> e asm.esil = true
What commands can we use with ESIL?
-
aei
: Initialize the ESIL virtual machine -
aeim
: Initialize the ESIL virtual machine memory (stack) -
aeip
: Set the initial ESIL virtual machine instruction pointer -
aer
: Set up initial register values -
ae
: evaluate an ESIL expression for example:ae 1,1,+
-
aes
: step an ESIL expression -
aesu 0x1020
: step until an address is reached -
aets+
: create a new record and replay mode session for reverse debugging -
aesb
: step backwards in the reverse debugging session
ESIL memory commands:
esil.stack
: enable or disable the stack for asm.emu modeesil.stack.addr
: set the stack address for the ESIL VMesil.stack.size
: set the stack size for the ESIL VMesil.stack.depth
: limit the number of pushes that can be done on the stackesil.romem
: specify read-only access to the ESIL memoryesil.fillstack
andesil.stack.pattern
: fill the ESIL VM stack with a pattern upon initializationesil.nonull
: stop the ESIL VM execution on a NULL pointer read or write
ESIL is used to accomplish partial emulation (imprecise emulation).
The ESIL VM is not expected to emulate external calls, system calls, or SIMD instructions.
ESIL emulation has seen use for:
- avoiding anti-debugging techniques
- calculating indirect jumps and conditional jumps
- encryption / decryption routines
- unpacking
- deobfuscation (polymorphic / self-writing code)
ESIL is also being experimented with for symbolic execution.
Name | Infinite Memory | Infinite Registers | Floating Point Support | Architectures Supported | Additional Notes |
---|---|---|---|---|---|
ESIL | yes | yes | no | Designed for evaluation and emulation. Ability to implement custom operations. Register aliases. | |
REIL | yes | yes | no | x86, ARM, PowerPC | BinNavi and BinDiff built on REIL. Written in Java. |
BIL | no | x86, ARM | IL for Binary Analysis Platform (BAP). Integration with IDA Pro, qira | ||
Vex IL | yes | yes | Supports types. Used in valgrind and angr. | ||
Pcode | yes | Verbose. Each instruction is a sequence of p-code operations over varnodes. |
- ESILSolve Symbolic Executor - z3 and ESIL for symbolic execution
- Modality Symbolic Executor - r2 plugin to integrate symbolic execution capabilities of angr