Mapping Files

Radare’s I/O subsystem allows you to map the contents of files into the same I/O space used to contain a loaded binary. New contents can be placed at random offsets.

The o command permits the user to open a file, this is mapped at offset 0 unless it has a known binary header and then the maps are created in virtual addresses.

Sometimes, we want to rebase a binary, or maybe we want to load or map the file in a different address.

When launching r2, the base address can be changed with the -B flag. But you must notice the difference when opening files with unknown headers, like bootloaders, so we need to map them using the -m flag (or specifying it as argument to the o command).

radare2 is able to open files and map portions of them at random places in memory specifying attributes like permissions and name. It is the perfect basic tooling to reproduce an environment like a core file, a debug session, by also loading and mapping all the libraries the binary depends on.

Opening files (and mapping them) is done using the o (open) command. Let’s read the help:

  1. [0x00000000]> o?
  2. |Usage: o [com- ] [file] ([offset])
  3. | o list opened files
  4. | o-1 close file descriptor 1
  5. | o-!* close all opened files
  6. | o-- close all files, analysis, binfiles, flags, same as !r2 --
  7. | o [file] open [file] file in read-only
  8. | o+ [file] open file in read-write mode
  9. | o [file] 0x4000 rwx map file at 0x4000
  10. | oa[-] [A] [B] [filename] Specify arch and bits for given file
  11. | oq list all open files
  12. | o* list opened files in r2 commands
  13. | o. [len] open a malloc://[len] copying the bytes from current offset
  14. | o= list opened files (ascii-art bars)
  15. | ob[?] [lbdos] [...] list opened binary files backed by fd
  16. | oc [file] open core file, like relaunching r2
  17. | of [file] open file and map it at addr 0 as read-only
  18. | oi[-|idx] alias for o, but using index instead of fd
  19. | oj[?] list opened files in JSON format
  20. | oL list all IO plugins registered
  21. | om[?] create, list, remove IO maps
  22. | on [file] 0x4000 map raw file at 0x4000 (no r_bin involved)
  23. | oo[?] reopen current file (kill+fork in debugger)
  24. | oo+ reopen current file in read-write
  25. | ood[r] [args] reopen in debugger mode (with args)
  26. | oo[bnm] [...] see oo? for help
  27. | op [fd] prioritize given fd (see also ob)
  28. | ox fd fdx exchange the descs of fd and fdx and keep the mapping

Prepare a simple layout:

  1. $ rabin2 -l /bin/ls
  2. [Linked libraries]
  3. libselinux.so.1
  4. librt.so.1
  5. libacl.so.1
  6. libc.so.6
  7. 4 libraries

Map a file:

  1. [0x00001190]> o /bin/zsh 0x499999

List mapped files:

  1. [0x00000000]> o
  2. - 6 /bin/ls @ 0x0 ; r
  3. - 10 /lib/ld-linux.so.2 @ 0x100000000 ; r
  4. - 14 /bin/zsh @ 0x499999 ; r

Print hexadecimal values from /bin/zsh:

  1. [0x00000000]> px @ 0x499999

Unmap files using the o- command. Pass the required file descriptor to it as an argument:

  1. [0x00000000]> o-14

You can also view the ascii table showing the list of the opened files:

  1. [0x00000000]> ob=