A target opcode is translated into a comma separated list of ESIL expressions.
xor eax, eax -> 0,eax,=,1,zf,=
Memory access is defined by brackets operation:
mov eax, [0x80480] -> 0x80480,[],eax,=
Default operand size is determined by size of operation destination.
movb $0, 0x80480 -> 0,0x80480,=[1]
The ? operator uses the value of its argument to decide whether to evaluate the expression in curly braces.
1. Is the value zero? -> Skip it.
2. Is the value non-zero? -> Evaluate it.
cmp eax, 123 -> 123,eax,==,$z,zf,=
jz eax -> zf,?{,eax,eip,=,}
If you want to run several expressions under a conditional, put them in curly braces:
zf,?{,eip,esp,=[],eax,eip,=,$r,esp,-=,}
Whitespaces, newlines and other chars are ignored. So the first thing when processing a ESIL program is to remove spaces:
esil = r_str_replace (esil, " ", "", R_TRUE);
Syscalls need special treatment. They are indicated by '$' at the beginning of an expression. You can pass an optional numeric value to specify a number of syscall. An ESIL emulator must handle syscalls. See (r_esil_syscall).
Arguments Order for Non-associative Operations
As discussed on IRC, the current implementation works like this:
a,b,- b - a
a,b,/= b /= a
This approach is more readable, but it is less stack-friendly.
Special Instructions
NOPs are represented as empty strings. As it was said previously, interrupts are marked by '$' command. For example, '0x80,$'. It delegates emulation from the ESIL machine to a callback which implements interrupt handler for a specific OS/kernel/platform.
Traps are implemented with the TRAP command. They are used to throw exceptions for invalid instructions, division by zero, memory read error, or any other needed by specific architectures.
Quick Analysis
Here is a list of some quick checks to retrieve information from an ESIL string. Relevant information will be probably found in the first expression of the list.
indexOf('[') -> have memory references
indexOf("=[") -> write in memory
indexOf("pc,=") -> modifies program counter (branch, jump, call)
indexOf("sp,=") -> modifies the stack (what if we found sp+= or sp-=?)
indexOf("=") -> retrieve src and dst
indexOf(":") -> unknown esil, raw opcode ahead
indexOf("$") -> accesses internal esil vm flags ex: $z
indexOf("$") -> syscall ex: 1,$
indexOf("TRAP") -> can trap
indexOf('++') -> has iterator
indexOf('--') -> count to zero
indexOf("?{") -> conditional
equalsTo("") -> empty string, aka nop (wrong, if we append pc+=x)
Common operations:
• Check dstreg
• Check srcreg
• Get destinaion
• Is jump
• Is conditional
• Evaluate
• Is syscall
CPU Flags
CPU flags are usually defined as single bit registers in the RReg profile. They are sometimes found under the 'flg' register type.
Variables
Properties of the VM variables:
1. They have no predefined bit width. This way it should be easy to extend them to 128, 256 and 512 bits later, e.g. for MMX, SSE, AVX, Neon SIMD.
2. There can be unbound number of variables. It is done for SSA-form compatibility.
3. Register names have no specific syntax. They are just strings.
4. Numbers can be specified in any base supported by RNum (dec, hex, oct, binary ...).
5. Each ESIL backend should have an associated RReg profile to describe the ESIL register specs.
Bit Arrays
What to do with them? What about bit arithmetics if use variables instead of registers?
Arithmetics
1. ADD ("+")
2. MUL ("*")
3. SUB ("-")
4. DIV ("/")
5. MOD ("%")
Bit Arithmetics
1. AND "&"
2. OR "|"
3. XOR "^"
4. SHL "<<"
5. SHR ">>"
6. ROL "<<<"
7. ROR ">>>"
8. NEG "!"
Floating Point Unit Support
At the moment of this writing, ESIL does not yet support FPU. But you can implement support for unsupported instructions using r2pipe. Eventually we will get proper support for multimedia and floating point.
Handling x86 REP Prefix in ESIL
ESIL specifies that the parsing control-flow commands must be uppercase. Bear in mind that some architectures have uppercase register names. The corresponding register profile should take care not to reuse any of the following:
3,SKIP - skip N instructions. used to make relative forward GOTOs
3,GOTO - goto instruction 3
LOOP - alias for 0,GOTO
BREAK - stop evaluating the expression
STACK - dump stack contents to screen
CLEAR - clear stack
Usage Example:
rep cmpsb
cx,!,?{,BREAK,},esi,[1],edi,[1],==,?{,BREAK,},esi,++,edi,++,cx,--,0,GOTO
Unimplemented/Unhandled Instructions
Those are expressed with the 'TODO' command. They act as a 'BREAK', but displays a warning message describing that an instruction is not implemented and will not be emulated. For example:
fmulp ST(1), ST(0) => TODO,fmulp ST(1),ST(0)
ESIL Disassembly Example:
[0x1000010f8]> e asm.esil=true
[0x1000010f8]> pd $r @ entry0
0x1000010f8 55 8,rsp,-=,rbp,rsp,=[8]
0x1000010f9 4889e5 rsp,rbp,=
0x1000010fc 4883c768 104,rdi,+=
0x100001100 4883c668 104,rsi,+=
0x100001104 5d rsp,[8],rbp,=,8,rsp,+=
0x100001105 e950350000 0x465a,rip,= ;[1]
0x10000110a 55 8,rsp,-=,rbp,rsp,=[8]
0x10000110b 4889e5 rsp,rbp,=
0x10000110e 488d4668 rsi,104,+,rax,=
0x100001112 488d7768 rdi,104,+,rsi,=
0x100001116 4889c7 rax,rdi,=
0x100001119 5d rsp,[8],rbp,=,8,rsp,+=
0x10000111a e93b350000 0x465a,rip,= ;[1]
0x10000111f 55 8,rsp,-=,rbp,rsp,=[8]
0x100001120 4889e5 rsp,rbp,=
0x100001123 488b4f60 rdi,96,+,[8],rcx,=
0x100001127 4c8b4130 rcx,48,+,[8],r8,=
0x10000112b 488b5660 rsi,96,+,[8],rdx,=
0x10000112f b801000000 1,eax,=
0x100001134 4c394230 rdx,48,+,[8],r8,==,cz,?=
0x100001138 7f1a sf,of,!,^,zf,!,&,?{,0x1154,rip,=,} ;[2]
0x10000113a 7d07 of,!,sf,^,?{,0x1143,rip,} ;[3]
0x10000113c b8ffffffff 0xffffffff,eax,= ; 0xffffffff
0x100001141 eb11 0x1154,rip,= ;[2]
0x100001143 488b4938 rcx,56,+,[8],rcx,=
0x100001147 48394a38 rdx,56,+,[8],rcx,==,cz,?=
Introspection
To ease ESIL parsing we should have a way to express introspection expressions to extract the data that we want. For example, we may want to get the target address of a jump. The parser for ESIL expressions should offer an API to make it possible to extract information by analyzing the expressions easily.
> ao~esil,opcode
opcode: jmp 0x10000465a
esil: 0x10000465a,rip,=
We need a way to retrieve the numeric value of 'rip'. This is a very simple example, but there are more complex, like conditional ones. We need expressions to be able to get:
• opcode type
• destination of a jump
• condition depends on
• all regs modified (write)
• all regs accessed (read)
API HOOKS
It is important for emulation to be able to setup hooks in the parser, so we can extend it to implement analysis without having to change it again and again. That is, every time an operation is about to be executed, a user hook is called. It can be used for example to determine if RIP is going to change, or if the instruction updates the stack. Later, we can split that callback into several ones to have an event-based analysis API that may be extended in JavaScript like this:
esil.on('regset', function(){..
esil.on('syscall', function(){esil.regset('rip'
For the API, see the functions hook_flag_read(), hook_execute() and hook_mem_read(). A callback should return true or 1 if you want to override the action that it takes. For example, to deny memory reads in a region, or voiding memory writes, effectively making it read-only. Return false or 0 if you want to trace ESIL expression parsing.
Other operations require bindings to external functionalities to work. In this case, r_ref and r_io. This must be defined when initializing the ESIL VM.
• Io Get/Set
Out ax, 44
44,ax,:ou
• Selectors (cs,ds,gs...)
Mov eax, ds:[ebp+8]
Ebp,8,+,:ds,eax,=
Data and Code Analysis
Оглавление
- Introduction
- History
- The Framework
- radare2
- rabin2
- rasm2
- Examples
- rahash2
- Examples
- radiff2
- rafind2
- ragg2
- Examples
- rarun2
- Sample rarun2 script
- Connecting a Program with a Socket
- Debugging a Program Redirecting the stdio into Another Terminal
- rax2
- Examples
- Downloading radare2
- Building with meson + ninja
- Helper Scripts
- Cleaning Up
- Compilation and Portability
- Static Build
- Meson build
- Docker
- Cleaning Up Old Radare2 Installations
- Windows
- Prerequisites
- Step-by-Step
- Install Visual Studio 2015 (or higher)
- Install Python 3 and Meson via Conda
- Set Up Conda:
- Create a Python Environment for Radare2
- Install Meson
- Install Git for Windows
- Get Radare2 Code
- Compile Radare2 Code
- Check That Radare2 Runs From All Locations
- Android
- Prerequisites
- Step-by-step
- Download and extract the Android NDK
- Make
- Specify NDK base path
- Compile + create tar.gz + push it to connected android device
- Meson
- Create a cross-file for meson
- Compile with meson + ninja
- Move files to your android device and enjoy
- User Interfaces
- Basic Radare2 Usage
- Command-line Options
- Common usage patterns
- Command Format
- Expressions
- Basic Debugger Session
- Contributing
- Radare2 Book
- Configuration
- Colors
- Themes
- Configuration Variables
- asm.arch
- asm.bits
- asm.syntax
- asm.pseudo
- asm.os
- asm.flags
- asm.lines.call
- asm.lines.out
- asm.linestyle
- asm.offset
- asm.trace
- asm.bytes
- asm.sub.reg
- asm.sub.jmp
- asm.sub.rel
- asm.sub.section
- asm.sub.varonly
- cfg.bigendian
- cfg.newtab
- scr.color
- scr.seek
- scr.scrollbar
- scr.utf8
- cfg.fortunes
- cfg.fortunes.type
- stack.size
- Files
- RC Files
- System
- Your Home
- Target file
- Basic Commands
- Seeking
- Open file
- Seeking at any position
- Block Size
- Sections
- Mapping Files
- Print Modes
- Hexadecimal View
- Show Hexadecimal Words Dump (32 bits)
- 8 bits Hexpair List of Bytes
- Show Hexadecimal Quad-words Dump (64 bits)
- Date/Time Formats
- Basic Types
- High-level Languages Views
- Strings
- Print Memory Contents
- Disassembly
- Selecting Target Architecture
- Configuring the Disassembler
- Disassembly Syntax
- Flags
- Local flags
- Flag Zones
- Introduction
- History
- The Framework
- radare2
- rabin2
- rasm2
- Examples
- rahash2
- Examples
- radiff2
- rafind2
- ragg2
- Examples
- rarun2
- Sample rarun2 script
- Connecting a Program with a Socket
- Debugging a Program Redirecting the stdio into Another Terminal
- rax2
- Examples
- Downloading radare2
- Building with meson + ninja
- Helper Scripts
- Cleaning Up
- Compilation and Portability
- Static Build
- Meson build
- Docker
- Cleaning Up Old Radare2 Installations
- Windows
- Prerequisites
- Step-by-Step
- Install Visual Studio 2015 (or higher)
- Install Python 3 and Meson via Conda
- Set Up Conda:
- Create a Python Environment for Radare2
- Install Meson
- Install Git for Windows
- Get Radare2 Code
- Compile Radare2 Code
- Check That Radare2 Runs From All Locations
- Android
- Prerequisites
- Step-by-step
- Download and extract the Android NDK
- Make
- Specify NDK base path
- Compile + create tar.gz + push it to connected android device
- Meson
- Create a cross-file for meson
- Compile with meson + ninja
- Move files to your android device and enjoy
- User Interfaces
- Basic Radare2 Usage
- Command-line Options
- Common usage patterns
- Command Format
- Expressions
- Basic Debugger Session
- Contributing
- Radare2 Book
- Configuration
- Colors
- Themes
- Configuration Variables
- asm.arch
- asm.bits
- asm.syntax
- asm.pseudo
- asm.os
- asm.flags
- asm.lines.call
- asm.lines.out
- asm.linestyle
- asm.offset
- asm.trace
- asm.bytes
- asm.sub.reg
- asm.sub.jmp
- asm.sub.rel
- asm.sub.section
- asm.sub.varonly
- cfg.bigendian
- cfg.newtab
- scr.color
- scr.seek
- scr.scrollbar
- scr.utf8
- cfg.fortunes
- cfg.fortunes.type
- stack.size
- Files
- RC Files
- System
- Your Home
- Target file
- Basic Commands
- Seeking
- Open file
- Seeking at any position
- Block Size
- Sections
- Mapping Files
- Print Modes
- Hexadecimal View
- Show Hexadecimal Words Dump (32 bits)
- 8 bits Hexpair List of Bytes
- Show Hexadecimal Quad-words Dump (64 bits)
- Date/Time Formats
- Basic Types
- High-level Languages Views
- Strings
- Print Memory Contents
- Disassembly
- Selecting Target Architecture
- Configuring the Disassembler
- Disassembly Syntax
- Flags
- Local flags
- Flag Zones
- Writing Data
- Write Over
- Zoom
- Yank/Paste
- Comparing Bytes
- SDB
- Usage example
- So what ?
- More Examples
- Dietline
- Autocompletion
- Emacs (default) mode
- Moving
- Deleting
- Killing and Yanking
- History
- Vi mode
- Entering command modes
- Moving
- Deleting and Yanking
- Visual Mode
- Navigation
- print modes aka panels
- Getting Help
- Visual Disassembly
- Navigation
- d as define
- Usage of the Cursor for Inserting/Patching...
- XREF
- Function Argument display
- Add a comment
- Type other commands
- Search
- The HUDS
- The "UserFriendly HUD"
- The "flag/comment/functions/.. HUD"
- Tweaking the Disassembly
- Visual Configuration Editor
- Examples
- asm.arch: Change Architecture & & asm.bits: Word size in bits at assembler
- asm.pseudo: Enable pseudo syntax
- asm.syntax: Select assembly syntax (intel, att, masm...)
- asm.describe: Show opcode description
- Visual Assembler
- Visual Configuration Editor
- Visual Panels
- Concept
- Overview
- Commands
- Basic Usage
- Split Screen
- Window Mode Commands
- Edit Values
- Tabs
- Saving layouts
- Searching for Bytes
- Basic Search
- Configuring Search Options
- Pattern Matching Search
- Search Automation
- Searching Backwards
- Assembler Search
- Searching for AES Keys
- Disassembling
- Adding Metadata to Disassembly
- ESIL
- Using ESIL
- ESIL Commands
- ESIL Instruction Set
- ESIL Flags
- Syntax and Commands
- Arguments Order for Non-associative Operations
- Special Instructions
- Quick Analysis
- CPU Flags
- Variables
- Bit Arrays
- Arithmetics
- Bit Arithmetics
- Floating Point Unit Support
- Handling x86 REP Prefix in ESIL
- Usage Example:
- Unimplemented/Unhandled Instructions
- ESIL Disassembly Example:
- Introspection
- API HOOKS
- Data and Code Analysis
- Code Analysis
- Analyze functions
- Hand craft function
- Recursive analysis
- Configuration
- Control flow configuration
- Reference control
- Analysis ranges
- Jump tables
- Platform specific controls
- Visuals
- Analysis hints
- Managing variables
- Type inference
- Types
- Loading types
- Printing types
- Linking Types
- Structure Immediates
- Managing enums
- Internal representation
- Structures
- Unions
- Function prototypes
- Calling Conventions
- Virtual Tables
- Syscalls
- Emulation
- Emulation in analysis loop
- Symbols
- Signatures
- Finding Best Matches zb
- Graph commands
- Ascii Art ** (e.g. agf )
- Interactive Ascii Art (e.g. agfv )
- Tiny Ascii Art (e.g. agft )
- Graphviz dot (e.g. agfd )
- JSON (e.g. agfj )
- Graph Modelling Language (e.g. agfg )
- SDB key-value (e.g. agfk )
- R2 custom graph commands (e.g. agf* )
- Web / image (e.g. agfw )
- Scripting
- Loops
- Macros
- Aliases
- R2pipe
- Examples
- Python
- NodeJS
- Go
- Rust
- Ruby
- Perl
- Erlang
- Haskell
- Dotnet
- Java
- Swift
- NewLisp
- Dlang
- Debugger
- Getting Started
- Small session in radare2 debugger
- Migration from ida, GDB or WinDBG
- How to run the program using the debugger
- How do I attach/detach to running process ? (gdb -p)
- How to set args/environment variable/load a specific libraries for the debugging session of radare
- How to script radare2 ?
- How to list Source code as in gdb list ?
- shortcuts
- Equivalent of "set-follow-fork-mode" gdb command
- Common features
- Registers
- Memory Maps
- Heap
- Files
- Reverse Debugging
- Windows Messages
- Remote Access Capabilities
- Debugging with gdbserver
- WinDBG Kernel-mode Debugging (KD)
- Setting Up KD on Windows
- Serial Port
- Network
- Connecting to KD interface on r2
- Serial Port
- Network
- Using KD
- WinDBG Backend for Windows (DbgEng)
- Using the plugin
- Tools
- Rax2
- rafind2
- Rarun2
- Rabin2 — Show Properties of a Binary
- File Properties Identification
- Code Entrypoints
- Imports
- Exports
- Symbols (Exports)
- List Libraries
- Strings
- Program Sections
- Radiff2
- Binary Diffing
- Rasm2
- Assembler
- Visual mode
- Disassembler
- pd N
- pD N
- pda
- pi, pI
- Disassembler Configuration
- ragg2
- Compiling ragg2 example
- Tiny binaries
- Syntax of the language
- Preprocessor
- Aliases
- Includes
- Hashbang
- Main
- Function definition
- Function signatures
- Function types
- Syscalls
- Libraries
- Core library
- Variables
- Arrays
- Tracing
- Poin ters
- Virtual registers
- Math operations
- Return values
- Traps
- Inline assembly
- Labels
- Control flow
- Comments
- rahash2
- Hashing by blocks
- Hashing with rabin2
- Obtaining hashes within radare2 session
- Examples
- Plugins
- Types of plugins
- Listing plugins
- Notes
- IO plugins
- Implementing a new disassembly plugin
- Moving plugin into the tree
- Implementing a new analysis plugin
- Implementing a new format
- To enable virtual addressing
- Create a folder with file format name in libr/bin/format
- Some Examples
- Write a debugger plugin
- More to come..
- Implementing a new pseudo architecture
- Python plugins
- Implementing new format plugin in Python
- Debugging
- Testing the plugin
- Creating an r2pm package of the plugin
- Crackmes
- IOLI CrackMes
- IOLI 0x00
- IOLI 0x01
- IOLI 0x02
- IOLI 0x03
- IOLI 0x04 0x04
- IOLI 0x05
- IOLI 0x06
- IOLI 0x07
- IOLI 0x08
- IOLI 0x09
- Avatao R3v3rs3 4
- .radare2
- .first_steps
- .main
- .vmloop
- ***
- .instructionset
- .bytecode
- .outro
- Radare2 Reference Card
- Survival Guide
- Flags
- Flagspaces
- Information
- Print string
- Visual mode
- Searching
- Saving (Broken)
- Usable variables in expression
- Authors & Contributors
- The radare2 book