The radare shell support macro definitions and these ones can be used to make up your own set of commands into a macro and then use it from the shell by just giving the name and arguments. You can understand a macro as a function.
Let's see how to define a macro:
[0x465D8810]> (? Usage: (foo\n..cmds..\n) Record macros grouping commands (foo args\n ..) ; define a macro (-foo) ; remove a macro .(foo) ; to call it Argument support: (foo x y\n$1 @ $2) ; define fun with args .(foo 128 0x804800) ; call it with args
The command to manage macros is '('. The first thing we can do is a hello world:
[0x465D8810]> (hello .. ?e Hello World .. ?e =========== .. ) [0x465D8810]> .(hello) Hello World =========== [0x465D8810]>
Macros supports arguments, and they are referenced with $# expressions.
Here's an example of how to define a simple oneliner function called 'foo' accepting two arguments to be used to print 8bit values from an address.
; Create our macro [0x465D8810]> (dump addr len .. p8 $1 @ $0) ; List defined macros [0x465D8810]> ( 0 dump: p8 $1 @ $0 ; Call the macro [0x465D8810]> .(dump esp 10) 01 00 00 00 e4 17 e6 bf 00 00 ; Remove it! [0x465D8810]> (-dump)
We can define these macros in our ~/.radarerc
$ cat ~/.radarerc (dump addr len p8 $1 @ $0)
It is also possible to recursively call a macro to emulate a loop. Here's a simple example of a recursive loop using macros in radare:
(loop times cmd ? $0 == 0 ?? () $1 .(loop $0-1 $1))