• Stars
    star
    159
  • Rank 235,916 (Top 5 %)
  • Language
    Python
  • License
    MIT License
  • Created about 5 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A python symbolic execution framework using radare2's ESIL (Evaluable String Intermediate Language)

ESILSolve - A python symbolic execution framework using radare2

logo

ESILSolve uses the z3 theorem prover and r2's ESIL intermediate representation to symbolically execute code.

ESILSolve supports the same architectures as ESIL, including x86, amd64, arm, aarch64, mips and more (6502, 8051, GameBoy...). This project is a work in progress, though it works well way more often than I honestly thought it would.

Installation

To install ESILSolve through the r2 package manager run r2pm -ci esilsolve. Alternatively clone it locally and run pip install . so you can have the tools directory in a convenient location.

Example Usage

from esilsolve import ESILSolver

esilsolver = ESILSolver("examples/defcamp_r100/r100")
flag = esilsolver.z3.BitVec("flag", 12*8)
state = esilsolver.call_state(0x004006fd, args=[[flag]])
end = esilsolver.run(target=0x004007a1, avoid=[0x00400790])
print("FLAG: %s " % end.evaluate_string(flag))

ESILSolve Plugin

The ESILSolve r2 plugin allows the user to quickly use ESILSolve from the r2 console. To get the available plugin commands enter aesx?.

 -- Are you a wizard?
[0x00000000]> aesx?
Usage: aesx[iscxrebdaw] # Core plugin for ESILSolve
| aesxi[f] [debug] [lazy] [check]              Initialize the ESILSolve instance and VM
| aesxs[bc] reg|addr [name] [length]           Set symbolic value in register or memory
| aesxv reg|addr value                         Set concrete value in register or memory
| aesxc sym value                              Constrain symbol to be value, min, max, regex
| aesxc[+-]                                    Push / pop the constraint context
| aesxx[ec] expr value                         Execute ESIL expression and evaluate/constrain the result
| aesxr[ac] target [avoid x,y] [merge w,z]     Run symbolic execution until target, avoiding x,y
| aesxf[c]                                     Resume r2frida after symex is finished
| aesxe[j] sym1 [sym2] [...]                   Evaluate symbol in current state
| aesxb[j] sym1 [sym2] [...]                   Evaluate buffer in current state
| aesxd[j] [reg1] [reg2] [...]                 Dump register values / ASTs
| aesxa[f]                                     Apply the [first] state, setting registers and memory
| aesxw[ls] [state number]                     List or set the current states

These commands can also be accessed using the shortcut aesx... -> X.... Bear in mind that other r2 plugins may use X as well though.

An example of using the plugin to symbolically execute a simple validation function on a 64 bit value in arm64 Android odex code:

[0x6f800b09a0]> Xi
[0x6f800b09a0]> Xs x2 flag 8
[0x6f800b09a0]> Xr 0x6f800b0a1c 0x6f800b09c4
[0x6f800b09a0]> Xc x0 1
[0x6f800b09a0]> Xe flag
flag: 3405691582
[0x6f800b09a0]> ?vx 3405691582
0xcafebabe

Here the state is initialized at the current location with Xi, and the value in register x2 is made symbolic with Xs x2 flag 8. Then the function is run until the return at 0x6f800b0a1c, avoiding a failure branch at 0x6f800b09c4. If the validation succeeds x0 should be 1 so we constrain it to that value with Xc x0 1. Then the value of the flag is evaluated, and it turns out to be 0xcafebabe.

Some other cool uses of the plugin can be seen in the r2con2020 slides in /docs. Its also easy to make your own ESILSolve based r2 scripts. ESILSolver() without arguments will automatically use the current session when the script is run from r2, just like r2pipe.open(). Its simple to make powerful, generic tools utilizing symbolic execution.

r2frida Integration

ESILSolve works well with any IO plugin for radare2, but it has some special features for r2frida. The ESILSolver class has the frida_state(addr) method which allows the user to place a frida hook at the provided address (or symbol name). Once this hook is hit the method will return an initialized state with the exact context of the hooked thread. Then the thread is suspended so that the state can be explored symbolically with ESILSolve without the relevant memory (which ES copies lazily) changing. Once, for instance, a desired state has been reached the required input can be evaluated and written back into real program memory. Then resume() can be called on the ESILSolver instance and the application will continue. An example of this with the same iOS app as above can be seen here

from esilsolve import ESILSolver
import z3

# start the ESILSolver instance by attaching r2frida 
esilsolver = ESILSolver("frida://attach/usb//iOSCrackMe")

validate = esilsolver.r2api.get_address("validate")
# initialize state with context from hook, app is suspended
state = esilsolver.frida_state(validate)

# initialize symbolic bytes of solution
# and constrain them to be /[a-zA-Z]/
code = z3.BitVec("code", 16*8)
state.constrain_bytes(code, "[a-zA-Z]")
addr = state.registers["A0"].as_long()
state.memory[addr] = code

state = esilsolver.run(validate+0x210, avoid=[validate+0x218])
solution = state.evaluate_buffer(code)
print("CODE: '%s'" % solution.decode())

# write solution into proper place
# esilsolver.r2api.write(addr, solution) 
esilsolver.resume() # resume suspended app

r2ghidra and P-Code support

ESILSolve has preliminary support for executing the ESIL generated with the r2ghidra command pdga. This command translates P-Code into ESIL so that r2 can analyze binaries similarly to Ghidra. It is based on the great work of FX Ti and allows ESILSolve to work with more architectures and support floating point instructions. To use the P-Code translation simply pass pcode=true when initializing an ESILSolver instance. See test/float.py for an example.

Docs

This README is getting long and should probably be turned into proper docs. I will do that. Later.

More Repositories

1

radare2

UNIX-like reverse engineering framework and command-line toolset
C
20,356
star
2

iaito

Official QT frontend of radare2
C++
1,047
star
3

radare2-book

The Official Radare2 Book
C
787
star
4

awesome-radare2

A curated list of awesome projects, articles and the other materials powered by Radare2
696
star
5

radeco

radare2-based decompiler and symbol executor
Rust
372
star
6

radare2-r2pipe

Access radare2 via pipe from any programming language!
JavaScript
370
star
7

r2ghidra

Native Ghidra Decompiler for r2
C++
334
star
8

radare2-extras

Source graveyard and random candy for radare2
C
239
star
9

sdb

Simple and fast string based key-value database with support for arrays and json
C
216
star
10

r2con

Radare Congress Stuff
202
star
11

r2con2019

r2con2019 - slides and materials
Python
135
star
12

radare2-pm

Package Manager for Radare2
Shell
131
star
13

radare2-bindings

Bindings of the r2 api for Valabind and friends
Python
130
star
14

r2retdec

RetDec plugin for Radare2
C++
123
star
15

r2con2017

r2con 2017 September 6-9
Python
97
star
16

radare2-webui

webui repository for radare2
JavaScript
93
star
17

r2con2018

HTML
92
star
18

r2ai

local language model for radare2
Python
78
star
19

r2wars

Corewars but within r2
C#
56
star
20

r2pipe.rs

Rust crate for r2pipe
Rust
44
star
21

ghidra-r2web

Ghidra plugin to start an r2 webserver to let r2 interact with it
Java
43
star
22

libdemangle

A simple library focusing on demangling symbols for different programing languages
C
39
star
23

r2con2020

Python
35
star
24

radare

advanced unix-like hexadecimal editor and debugger
C
35
star
25

r2jp

Japanese Community of radare2
34
star
26

r2pm

Radare2 cross platform package manager
Go
33
star
27

radare2-r2papi

High Level API on top of the R2Pipe interface
TypeScript
33
star
28

acr

autoconf replacement
Shell
33
star
29

r2pipe-go

Go API to interact with radare2
Go
31
star
30

ghidra-native

C++
29
star
31

r2con2021

28
star
32

r2env

Install multiple versions of r2 and its plugins via Pip on any system!
Python
25
star
33

r2yara

yara and radare2, better together
C
17
star
34

radare2-rlang

Writing Radare2 plugins in various languages
C
15
star
35

radare2-testbins

Rebol
15
star
36

radare2-rust

Playground for Rust and Radare2
Rust
14
star
37

radare.org

http://www.radare.org/
CSS
14
star
38

r2hexagon

Hexagon disassembler code generator from the official instruction manual.
C
11
star
39

r2con2016

r2con2016 repository
C
10
star
40

esil-rs

Radare2's ESIL in Rust
Rust
10
star
41

r2diaphora

Binary Diffing tool ported to radare2
Python
9
star
42

radare2-gsoc-windows

Various Brainstorming/scripts/ideas/etc. for the GSOC-Windows Task
C
9
star
43

ragui

Vala
8
star
44

radare2-release

Releasing is hard
Shell
7
star
45

r2app

Electron Desktop App for Radare2
JavaScript
6
star
46

blog

The radare2 blog, available on radare.today
Shell
6
star
47

r2pipe-codeshare

A place to share your radare2 scripts
Python
6
star
48

radare2-win-installer

Windows installer scripts for radare2
Inno Setup
5
star
49

r2r-go

Go
5
star
50

radareorg

New amazing website for radare.org
Python
4
star
51

radare2-cheatsheets

TeX
4
star
52

radare2-fuzz

Python
4
star
53

ideas

4
star
54

radare2-skel

Sample radare2 project templates
Python
4
star
55

node-r2r

radare2 regressions testsuite in nodejs
JavaScript
3
star
56

iaito-translations

Makefile
3
star
57

.github

Radare Organization Templates
3
star
58

r2shell

C
2
star
59

infrastructure

Terraform, Nomad, Consul and Vault configuration of radare infrastructure
Dockerfile
2
star
60

r2pm-db

Radare2 package manager database
2
star
61

radare2-snap

Radare2 snap and docker repository
Makefile
2
star
62

radare2-fuzztargets

Makefile
1
star
63

r2r-v

R2 regressions testsuite written in V
V
1
star
64

radeco-regressions

Regresion tests for radeco
Rust
1
star
65

radare2-sigs

Zignature masm32 repository
Python
1
star
66

r2sarif

Load, manage and create SARIF documents with radare2
TypeScript
1
star