Flags are conceptually similar to bookmarks. They associate a name with a given offset in a file. Flags can be grouped into 'flag spaces'. A flag space is a namespace for flags, grouping together flags of similar characteristics or type. Examples for flag spaces: sections, registers, symbols.
To create a flag:
[0x4A13B8C0]> f flag_name @ offset
You can remove a flag by appending the - character to command. Most commands accept - as argument-prefix as an indication to delete something.
[0x4A13B8C0]> f-flag_name
To switch between or create new flagspaces use the fs command:
[0x00005310]> fs?
|Usage: fs [*] [+-][flagspace|addr] # Manage flagspaces
| fs display flagspaces
| fs* display flagspaces as r2 commands
| fsj display flagspaces in JSON
| fs * select all flagspaces
| fs flagspace select flagspace or create if it doesn't exist
| fs-flagspace remove flagspace
| fs-* remove all flagspaces
| fs+foo push previous flagspace and set
| fs- pop to the previous flagspace
| fs-. remove the current flagspace
| fsq list flagspaces in quiet mode
| fsm [addr] move flags at given address to the current flagspace
| fss display flagspaces stack
| fss* display flagspaces stack in r2 commands
| fssj display flagspaces stack in JSON
| fsr newname rename selected flagspace
[0x00005310]> fs
0 439 * strings
1 17 * symbols
2 54 * sections
3 20 * segments
4 115 * relocs
5 109 * imports
[0x00005310]>
Here there are some command examples:
[0x4A13B8C0]> fs symbols ; select only flags in symbols flagspace
[0x4A13B8C0]> f ; list only flags in symbols flagspace
[0x4A13B8C0]> fs * ; select all flagspaces
[0x4A13B8C0]> f myflag ; create a new flag called 'myflag'
[0x4A13B8C0]> f-myflag ; delete the flag called 'myflag'
You can rename flags with fr.
Local flags
Every flag name should be unique for addressing reasons. But it is quite a common need to have the flags, for example inside the functions, with simple and ubiquitous names like loop or return. For this purpose you can use so called "local" flags, which are tied to the function where they reside. It is possible to add them using f. command:
[0x00003a04]> pd 10
│ 0x00003a04 48c705c9cc21. mov qword [0x002206d8], 0xffffffffffffffff ;
[0x2206d8:8]=0
│ 0x00003a0f c60522cc2100. mov byte [0x00220638], 0 ; [0x220638:1]=0
│ 0x00003a16 83f802 cmp eax, 2
│ .─< 0x00003a19 0f84880d0000 je 0x47a7
│ │ 0x00003a1f 83f803 cmp eax, 3
│ .──< 0x00003a22 740e je 0x3a32
│ ││ 0x00003a24 83e801 sub eax, 1
│.───< 0x00003a27 0f84ed080000 je 0x431a
││││ 0x00003a2d e8fef8ffff call sym.imp.abort ; void abort(void)
││││ ; CODE XREF from main (0x3a22)
││╰──> 0x00003a32 be07000000 mov esi, 7
[0x00003a04]> f. localflag @ 0x3a32
[0x00003a04]> f.
0x00003a32 localflag [main + 210]
[0x00003a04]> pd 10
│ 0x00003a04 48c705c9cc21. mov qword [0x002206d8], 0xffffffffffffffff ;
[0x2206d8:8]=0
│ 0x00003a0f c60522cc2100. mov byte [0x00220638], 0 ; [0x220638:1]=0
│ 0x00003a16 83f802 cmp eax, 2
│ .─< 0x00003a19 0f84880d0000 je 0x47a7
│ │ 0x00003a1f 83f803 cmp eax, 3
│ .──< 0x00003a22 740e je 0x3a32 ; main.localflag
│ ││ 0x00003a24 83e801 sub eax, 1
│.───< 0x00003a27 0f84ed080000 je 0x431a
││││ 0x00003a2d e8fef8ffff call sym.imp.abort ; void abort(void)
││││ ; CODE XREF from main (0x3a22)
││`──> .localflag:
││││ ; CODE XREF from main (0x3a22)
││`──> 0x00003a32 be07000000 mov esi, 7
[0x00003a04]>
Flag Zones
radare2 offers flag zones, which lets you label different offsets on the scrollbar, for making it easier to navigate through large binaries. You can set a flag zone on the current seek using:
[0x00003a04]> fz flag-zone-name
Set scr.scrollbar=1 and go to the Visual mode, to see your flag zone appear on the scrollbar on the right end of the window.
See fz? for more information.
Writing Data
Radare can manipulate a loaded binary file in many ways. You can resize the file, move and copy/paste bytes, insert new bytes (shifting data to the end of the block or file), or simply overwrite bytes. New data may be given as a wide-string, assembler instructions, or the data may be read in from another file.
Resize the file using the r command. It accepts a numeric argument. A positive value sets a new size for the file. A negative one will truncate the file to the current seek position minus N bytes.
r 1024 ; resize the file to 1024 bytes
r -10 @ 33 ; strip 10 bytes at offset 33
Write bytes using the w command. It accepts multiple input formats like inline assembly, endian-friendly dwords, files, hexpair files, wide strings:
[0x00404888]> w?
Usage: w[x] [str] [ | w[1248][+-][n] increment/decrement byte,word.. | w foobar write string 'foobar' | w0 [len] write 'len' bytes with value 0x00 | w6[de] base64/hex write base64 [d]ecoded or [e]ncoded string | wa[?] push ebp write opcode, separated by ';' (use '"' around the command) | waf f.asm assemble file and write bytes | waF f.asm assemble file and write bytes and show 'wx' op with hexpair bytes of assembled code | wao[?] op modify opcode (change conditional of jump. nop, etc) | wA[?] r 0 alter/modify opcode at current seek (see wA?) | wb 010203 fill current block with cyclic hexpairs | wB[-]0xVALUE set or unset bits with given value | wc list all write changes | wc[?][jir+-*?] write cache undo/commit/reset/list (io.cache) | wd [off] [n] duplicate N bytes from offset at current seek (memcpy) (see y?) | we[?] [nNsxX] [arg] extend write operations (insert instead of replace) | wf[fs] -|file write contents of file at current offset | wh r2 whereis/which shell command | wm f0ff set binary mask hexpair to be used as cyclic write mask | wo[?] hex write in block with operation. 'wo?' fmi | wp[?] -|file apply radare patch file. See wp? fmi | wr 10 write 10 random bytes | ws pstring write 1 byte for length and then the string | wt[f][?] file [sz] write to file (from current seek, blocksize or sz bytes) | wts host:port [sz] send data to remote host:port via tcp:// | ww foobar write wide string 'f\x00o\x00o\x00b\x00a\x00r\x00' | wx[?][fs] 9090 write two intel nops (from wxfile or wxseek) | wv[?] eip+34 write 32-64 bit value honoring cfg.bigendian | wz string write zero terminated string (like w + \x00) Some examples: [0x00000000]> wx 123456 @ 0x8048300 [0x00000000]> wv 0x8048123 @ 0x8049100 [0x00000000]> wa jmp 0x8048320 The wo command (write over) has many subcommands, each combines the existing data with the new data using an operator. The command is applied to the current block. Supported operators include XOR, ADD, SUB... [0x4A13B8C0]> wo? |Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize] |Example: | wox 0x90 ; xor cur block with 0x90 | wox 90 ; xor cur block with 0x90 | wox 0x0203 ; xor cur block with 0203 | woa 02 03 ; add [0203][0203][...] to curblk | woe 02 03 ; create sequence from 2 to 255 with step 3 |Supported operations: | wow == write looped value (alias for 'wb') | woa += addition | wos -= substraction | wom *= multiply | wod /= divide | wox ^= xor | woo |= or | woA &= and | woR random bytes (alias for 'wr $b' | wor >>= shift right | wol <<= shift left | wo2 2= 2 byte endian swap | wo4 4= 4 byte endian swap It is possible to implement cipher-algorithms using radare core primitives and wo. A sample session performing xor(90) + add(01, 02): [0x7fcd6a891630]> px - offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x7fcd6a891630 4889 e7e8 6839 0000 4989 c48b 05ef 1622 0x7fcd6a891640 005a 488d 24c4 29c2 5248 89d6 4989 e548 0x7fcd6a891650 83e4 f048 8b3d 061a 2200 498d 4cd5 1049 0x7fcd6a891660 8d55 0831 ede8 06e2 0000 488d 15cf e600 [0x7fcd6a891630]> wox 90 [0x7fcd6a891630]> px - offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x7fcd6a891630 d819 7778 d919 541b 90ca d81d c2d8 1946 0x7fcd6a891640 1374 60d8 b290 d91d 1dc5 98a1 9090 d81d 0x7fcd6a891650 90dc 197c 9f8f 1490 d81d 95d9 9f8f 1490 0x7fcd6a891660 13d7 9491 9f8f 1490 13ff 9491 9f8f 1490 [0x7fcd6a891630]> woa 01 02 [0x7fcd6a891630]> px - offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x7fcd6a891630 d91b 787a 91cc d91f 1476 61da 1ec7 99a3 0x7fcd6a891640 91de 1a7e d91f 96db 14d9 9593 1401 9593 0x7fcd6a891650 c4da 1a6d e89a d959 9192 9159 1cb1 d959 0x7fcd6a891660 9192 79cb 81da 1652 81da 1456 a252 7c77Write Over
Zoom