In the following answer, I'll show you several ways to achieve what you want. I'll use different approaches to do this with radre2.
First, let's create a program with a bit longer strings:
$ cat helloworld.c
#include <stdio.h>
void main (int argc, char * argv[] ) {
char * arr[] = {"Hello", "World", "Byebye"};
arr[0] = "F";
printf( "%s\n", arr[0] );
}
$ gcc helloworld.c -o helloworld
And open it in radare2:
$ r2 helloworld
Now that we have a tiny binary, we can start.
Method 1: Strings in data sections
Using the iz
command you can list the strings in the data sections. For each string, you can see the section it belongs to:
[0x000005b0]> iz
000 0x000007b4 0x000007b4 5 6 (.rodata) ascii Hello
001 0x000007ba 0x000007ba 5 6 (.rodata) ascii World
002 0x000007c0 0x000007c0 6 7 (.rodata) ascii Byeby
And of course, you can always use radare's internal grep (~
) to take only the relevant columns:
[0x000005b0]> iz~[5,7]
(.rodata) Hello
(.rodata) World
(.rodata) Byebye
Method 2: Strings in the whole binary
Unlike iz
, the command izz
will search for strings in the whole binary. This command will show you more strings than iz
but it'll search for strings in other sections as well.
[0x000005b0]> izz
000 0x00000034 0x00000034 4 10 (LOAD0) utf16le @8\t@
001 0x00000238 0x00000238 27 28 (.interp) ascii /lib64/ld-linux-x86-64.so.2
002 0x00000379 0x00000379 9 10 (.dynstr) ascii libc.so.6
003 0x00000383 0x00000383 4 5 (.dynstr) ascii puts
004 0x00000388 0x00000388 16 17 (.dynstr) ascii __stack_chk_fail
005 0x00000399 0x00000399 14 15 (.dynstr) ascii __cxa_finalize
006 0x000003a8 0x000003a8 17 18 (.dynstr) ascii __libc_start_main
007 0x000003ba 0x000003ba 9 10 (.dynstr) ascii GLIBC_2.4
008 0x000003c4 0x000003c4 11 12 (.dynstr) ascii GLIBC_2.2.5
009 0x000003d0 0x000003d0 27 28 (.dynstr) ascii _ITM_deregisterTMCloneTable
010 0x000003ec 0x000003ec 14 15 (.dynstr) ascii __gmon_start__
011 0x000003fb 0x000003fb 25 26 (.dynstr) ascii _ITM_registerTMCloneTable
...
019 0x000007b4 0x000007b4 5 6 (.rodata) ascii Hello
020 0x000007ba 0x000007ba 5 6 (.rodata) ascii World
021 0x000007c0 0x000007c0 6 7 (.rodata) ascii Byebye
022 0x00000810 0x00000810 4 5 (.eh_frame) ascii \e\f\a\b
023 0x00000840 0x00000840 4 5 (.eh_frame) ascii \e\f\a\b
024 0x00000867 0x00000867 5 6 (.eh_frame) ascii ;*3$"
025 0x0000088a 0x0000088a 4 5 (.eh_frame) ascii h\f\a\b
026 0x00001038 0x00000000 16 17 (.comment) ascii GCC: (GNU) 7.2.0
027 0x00001669 0x00000001 6 7 (.strtab) ascii init.c
028 0x00001670 0x00000008 10 11 (.strtab) ascii crtstuff.c
...
Again, you can see that radare2 shows you the section name for each string.
If you are searching for specific strings, grep is your friend:
[0x000005b0]> izz~Hello, World, Byebye
019 0x000007b4 0x000007b4 5 6 (.rodata) ascii Hello
020 0x000007ba 0x000007ba 5 6 (.rodata) ascii World
021 0x000007c0 0x000007c0 6 7 (.rodata) ascii Byebye
[0x000005b0]> izz~Hello, World, Byebye[5,7]
(.rodata) Hello
(.rodata) World
(.rodata) Byebye
Method 3: Section of a specific address
In this method, you already know the address of the string and you want to know to which section it belongs. Let's take "Hello" for example. We saw that "Hello" address is 0x000007b4
. Let's verify it using ps
(print string):
[0x000005b0]> ps @ 0x000007b4
Hello
As you can see, we printed a zero-terminated string from 0x07b4
("@" is radare's temporary seek). Now that we are sure that this is the address of "Hello", we can use iS.
to show the current Section name:
[0x000005b0]> iS. @ 0x07b4
Current section
00 0x000007b0 25 0x000007b0 25 -r-- .rodata
As expected, this address belongs to the .rodata
section. Just as we saw before.
Show Sections' attributes
Finally, you wanted to check whether the sections' attributes are read-only or read-write. Using iS
you can list all the sections, including their attributes:
[0x000005b0]> iS
[Sections]
00 0x00000000 0 0x00000000 0 ----
01 0x00000238 28 0x00000238 28 -r-- .interp
02 0x00000254 32 0x00000254 32 -r-- .note.ABI_tag
03 0x00000274 36 0x00000274 36 -r-- .note.gnu.build_id
04 0x00000298 28 0x00000298 28 -r-- .gnu.hash
05 0x000002b8 192 0x000002b8 192 -r-- .dynsym
06 0x00000378 157 0x00000378 157 -r-- .dynstr
07 0x00000416 16 0x00000416 16 -r-- .gnu.version
08 0x00000428 48 0x00000428 48 -r-- .gnu.version_r
09 0x00000458 216 0x00000458 216 -r-- .rela.dyn
10 0x00000530 48 0x00000530 48 -r-- .rela.plt
11 0x00000560 23 0x00000560 23 -r-x .init
12 0x00000580 48 0x00000580 48 -r-x .plt
13 0x000005b0 498 0x000005b0 498 -r-x .text
14 0x000007a4 9 0x000007a4 9 -r-x .fini
15 0x000007b0 25 0x000007b0 25 -r-- .rodata
16 0x000007cc 52 0x000007cc 52 -r-- .eh_frame_hdr
17 0x00000800 240 0x00000800 240 -r-- .eh_frame
18 0x00000de0 8 0x00200de0 8 -rw- .init_array
19 0x00000de8 8 0x00200de8 8 -rw- .fini_array
20 0x00000df0 480 0x00200df0 480 -rw- .dynamic
21 0x00000fd0 48 0x00200fd0 48 -rw- .got
22 0x00001000 40 0x00201000 40 -rw- .got.plt
23 0x00001028 16 0x00201028 16 -rw- .data
24 0x00001038 0 0x00201038 8 -rw- .bss
25 0x00001038 17 0x00000000 17 ---- .comment
26 0x00001050 1560 0x00000000 1560 ---- .symtab
27 0x00001668 555 0x00000000 555 ---- .strtab
28 0x00001893 259 0x00000000 259 ---- .shstrtab
29 0x00000040 504 0x00000040 504 -r-x PHDR
30 0x00000238 28 0x00000238 28 -r-- INTERP
31 0x00000000 2288 0x00000000 2288 -r-x LOAD0
32 0x00000de0 600 0x00200de0 608 -rw- LOAD1
33 0x00000df0 480 0x00200df0 480 -rw- DYNAMIC
34 0x00000254 68 0x00000254 68 -r-- NOTE
35 0x000007cc 52 0x000007cc 52 -r-- GNU_EH_FRAME
36 0x00000000 0 0x00000000 0 -rw- GNU_STACK
37 0x00000de0 544 0x00200de0 544 -r-- GNU_RELRO
38 0x00000000 64 0x00000000 64 -rw- ehdr
Alternatively, use iSq
to show a less-verbose output (q is for quiet), and you also can grep for read-write sections:
[0x000005b0]> iS~rw
18 0x00000de0 8 0x00200de0 8 -rw- .init_array
19 0x00000de8 8 0x00200de8 8 -rw- .fini_array
20 0x00000df0 480 0x00200df0 480 -rw- .dynamic
21 0x00000fd0 48 0x00200fd0 48 -rw- .got
22 0x00001000 40 0x00201000 40 -rw- .got.plt
23 0x00001028 16 0x00201028 16 -rw- .data
24 0x00001038 0 0x00201038 8 -rw- .bss
32 0x00000de0 600 0x00200de0 608 -rw- LOAD1
33 0x00000df0 480 0x00200df0 480 -rw- DYNAMIC
36 0x00000000 0 0x00000000 0 -rw- GNU_STACK
38 0x00000000 64 0x00000000 64 -rw- ehdr
If you want to see read-only sections, use grep like this iS~r--
.