Выбрать главу

1 Cheese

2 Potato

3 Butter

[0x00404800]> join foodtypes foods.txt

1 Protein Cheese

2 Carbohydrate Potato

3 Fat Butter

Similarly, sorting the content is also possible with the sort command. A typical example could be:

[0x00404800]> sort file

eleven

five

five

great

one

one

radare

The ?$? command describes several helpful variables you can use to do similar actions even more easily, like the $v "immediate value" variable, or the $m opcode memory reference variable.

One of the most common task in automation is looping through something, there are multiple ways to do this in radare2.

We can loop over flags:

@@ flagname-regex

For example, we want to see function information with afi command:

[0x004047d6]> afi

#

offset: 0x004047d0

name: entry0

size: 42

realsz: 42

stackframe: 0

call-convention: amd64

cyclomatic-complexity: 1

bits: 64

type: fcn [NEW]

num-bbs: 1

edges: 0

end-bbs: 1

call-refs: 0x00402450 C

data-refs: 0x004136c0 0x00413660 0x004027e0

code-xrefs:

data-xrefs:

locals:0

args: 0

diff: type: new

[0x004047d6]>

Now let's say, for example, that we'd like see a particular field from this output for all functions found by analysis. We can do that with a loop over all function flags (whose names begin with fcn.):

[0x004047d6]> fs functions

[0x004047d6]> afi @@ fcn.* ~name

This command will extract the name field from the afi output of every flag with a name matching the regexp fcn.*. There are also a predefined loop called @@f, which runs your command on every functions found by r2:

[0x004047d6]> afi @@f ~name

We can also loop over a list of offsets, using the following syntax:

@@=1 2 3 ... N

For example, say we want to see the opcode information for 2 offsets: the current one, and at current + 2:

[0x004047d6]> ao @@=$$ $$+2

address: 0x4047d6

opcode: mov rdx, rsp

prefix: 0

bytes: 4889e2

refptr: 0

size: 3

type: mov

esiclass="underline" rsp,rdx,=

stack: null

family: cpu

address: 0x4047d8

opcode: loop 0x404822

prefix: 0

bytes: e248

refptr: 0

size: 2

type: cjmp

esiclass="underline" 1,rcx,-=,rcx,?{,4212770,rip,=,}

jump: 0x00404822

faiclass="underline" 0x004047da

stack: null

cond: al

family: cpu

[0x004047d6]>

Note we're using the $$ variable which evaluates to the current offset. Also note that $$+2 is evaluated before looping, so we can use the simple arithmetic expressions.

A third way to loop is by having the offsets be loaded from a file. This file should contain one offset per line.

[0x004047d0]> ?v $$ > offsets.txt

[0x004047d0]> ?v $$+2 >> offsets.txt

[0x004047d0]> !cat offsets.txt

4047d0

4047d2

[0x004047d0]> pi 1 @@.offsets.txt

xor ebp, ebp

mov r9, rdx

radare2 also offers various foreach constructs for looping. One of the most useful is for looping through all the instructions of a function:

[0x004047d0]> pdf

╒ (fcn) entry0 42

│; UNKNOWN XREF from 0x00400018 (unk)

│; DATA XREF from 0x004064bf (sub.strlen_460)

│; DATA XREF from 0x00406511 (sub.strlen_460)

│; DATA XREF from 0x0040b080 (unk)

│; DATA XREF from 0x0040b0ef (unk)

│0x004047d0 xor ebp, ebp

│0x004047d2 mov r9, rdx

│0x004047d5 pop rsi

│0x004047d6 mov rdx, rsp

│0x004047d9 and rsp, 0xfffffffffffffff0

│0x004047dd push rax

│0x004047de push rsp

│0x004047df mov r8, 0x4136c0

│0x004047e6 mov rcx, 0x413660 ; "AWA..AVI..AUI..ATL.%.. "

0A..AVI..AUI.

│0x004047ed mov rdi, main ; "AWAVAUATUH..S..H...." @

0

│0x004047f4 call sym.imp.__libc_start_main

╘0x004047f9 hlt

[0x004047d0]> pi 1 @@i

mov r9, rdx

pop rsi

mov rdx, rsp

and rsp, 0xfffffffffffffff0

push rax

push rsp

mov r8, 0x4136c0

mov rcx, 0x413660

mov rdi, main

call sym.imp.__libc_start_main

hlt

In this example the command pi 1 runs over all the instructions in the current function (entry0). There are other options too (not complete list, check @@? for more information):

   • @@k sdbquery - iterate over all offsets returned by that sdbquery

   • @@t- iterate over on all threads (see dp)

   • @@b - iterate over all basic blocks of current function (see afb)

   • @@f - iterate over all functions (see aflq)

The last kind of looping lets you loop through predefined iterator types:

   • symbols

   • imports

   • registers

   • threads

   • comments

   • functions

   • flags

This is done using the @@@ command. The previous example of listing information about functions can also be done using the @@@ command:

[0x004047d6]> afi @@@ functions ~name

This will extract name field from afi output and will output a huge list of function names. We can choose only the second column, to remove the redundant name: on every line:

[0x004047d6]> afi @@@ functions ~name[1]

Beware, @@@ is not compatible with JSON commands.

Apart from simple sequencing and looping, radare2 allows to write simple macros, using this construction:

[0x00404800]> (qwe; pd 4; ao)

This will define a macro called 'qwe' which runs sequentially first 'pd 4' then 'ao'. Calling the macro using syntax .(macro) is simple:

[0x00404800]> (qwe; pd 4; ao)

[0x00404800]> .(qwe)

0x00404800 mov eax, 0x61e627 ; "tab"

0x00404805 push rbp

0x00404806 sub rax, section_end.LOAD1

0x0040480c mov rbp, rsp

address: 0x404800

opcode: mov eax, 0x61e627

prefix: 0

bytes: b827e66100

ptr: 0x0061e627

refptr: 0

size: 5

type: mov

esiclass="underline" 6415911,rax,=

stack: null

family: cpu

[0x00404800]>

To list available macroses simply call (*:

[0x00404800]> (*

(qwe ; pd 4; ao)

And if want to remove some macro, just add '-' before the name:

[0x00404800]> (-qwe)

Macro 'qwe' removed.

[0x00404800]>

Moreover, it's possible to create a macro that takes arguments, which comes in handy in some simple scripting situations. To create a macro that takes arguments you simply add them to macro definition.

[0x00404800]

[0x004047d0]> (foo x y; pd $0; s +$1)

[0x004047d0]> .(foo 5 6)

;-- entry0:

0x004047d0 xor ebp, ebp

0x004047d2 mov r9, rdx

0x004047d5 pop rsi

0x004047d6 mov rdx, rsp

0x004047d9 and rsp, 0xfffffffffffffff0

[0x004047d6]>

As you can see, the arguments are named by index, starting from 0: $0, $1, ...

radare2 also offers aliases which might help you save time by quickly executing your most used commands. They are under $?

The general usage of the feature is: $alias=cmd

[0x00404800]> $disas=pdf

The above command will create an alias disas for pdf. The following command prints the disassembly of the main function.

[0x00404800]> $disas @ main

Apart from commands, you can also alias a text to be printed, when called.

[0x00404800]> $my_alias=$test input

[0x00404800]> $my_alias

test input

To undefine alias, use $alias=: