The Official Radare2 Book | страница 100



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)

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,=

Radare2 has a very rich set of commands and configuration options to perform data and code analysis, to extract useful information from a binary, like pointers, string references, basic blocks, opcode data, jump targets, cross references and much more. These operations are handled by the a (analyze) command family:

|Usage: a[abdefFghoprxstc] [...]

| aa[?] analyze all (fcns + bbs) (aa0 to avoid sub renaming)

| a8 [hexpairs] analyze bytes

| ab[b] [addr] analyze block at given address

| abb [len] analyze N basic blocks in [len] (section.size by default)