radareorg / radare2

UNIX-like reverse engineering framework and command-line toolset
https://www.radare.org/
GNU Lesser General Public License v3.0
20.34k stars 2.97k forks source link

gdbserver symbols? #8931

Open bannsec opened 6 years ago

bannsec commented 6 years ago

When I connect using gdb:// debug handler to a network listening gdbserver instance, I cannot get the binary symbols using is. Perhaps related, I cannot locate any functions with afl. There is simply no output for those commands.

radare commented 6 years ago

to get symbols you must load a binary and to list functions you need to analyze code. None of those things happen when you gdb:// for obvious reasons.

You can tell r2 to analyze code or load the symbols info from a local file

On 2 Dec 2017, at 04:49, bannsec notifications@github.com wrote:

When I connect using gdb:// debug handler to a network listening gdbserver instance, I cannot get the binary symbols using is. Perhaps related, I cannot locate any functions with afl. There is simply no output for those commands.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

bannsec commented 6 years ago

Is there a way to tell r2 what the file you want to open from the command line, similar to gdb? For instance:

r2 -d gdb://<connection>:<port> <my_file>

For the manual opening of the file after the fact, I'm assuming that's o <filename>? If so, how do you do that with PIC so that the symbols are actually at their load addresses?

radare commented 6 years ago

The problem is that each can be mapped in different addresses on each run and there can be multiple files loaded. So you cant do this from there. But will work from the r2 shell using .!rabin2 -r or using the ob subcommands. Sorry im not in laptop to give you proper commands right now

On 2 Dec 2017, at 19:04, bannsec notifications@github.com wrote:

Is there a way to tell r2 what the file you want to open from the command line, similar to gdb? For instance:

r2 -d gdb://: For the manual opening of the file after the fact, I'm assuming that's o ? If so, how do you do that with PIC so that the symbols are actually at their load addresses?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

bannsec commented 6 years ago

It would look like dmm would provide the needed loading commands, but it doesn't seem to load as expected:

[0xf77a7c60]> dmm*
f mod._home_r2_radare_work_app17unix = 0x08048000
.!rabin2 -rsB 0x08048000 '/home/r2/radare_work/app17unix'
f mod._lib_i386_linux_gnu_ld_2.19.so = 0xf77a7000
.!rabin2 -rsB 0xf77a7000 '/lib/i386-linux-gnu/ld-2.19.so'
[0xf77a7c60]> .dmm*
[0xf77a7c60]> is

[0xf77a7c60]> f
0x0804a11c 4 sym._IO_stdin_used
0x08048548 16 sym.operatordelete_void__
0x080485b8 16 sym.operatornew___unsignedint_
0xf77a7000 0 sym.GLIBC_2.1
0xf77b8760 30 sym._dl_get_tls_static_info
0xf77a7000 0 sym.GLIBC_PRIVATE
0xf77a7000 0 sym.GLIBC_2.3
0xf77a7000 0 sym.GLIBC_2.4
0xf77bc900 80 sym.free
0xf77bc9d0 144 sym.realloc
0xf77b8aa0 37 sym._dl_allocate_tls
0xf77c8918 20 sym._r_debug
0xf77c7f28 4 sym.__libc_stack_end
0xf77bc770 268 sym.__libc_memalign
0xf77b8ad0 133 sym._dl_deallocate_tls
0xf77b9cb0 177 sym._dl_find_dso_for_object
0xf77bc8b0 74 sym.calloc
0xf77c7efc 4 sym._dl_argv
0xf77b7fc0 550 sym._dl_mcount
0xf77b8690 203 sym._dl_tls_setup
0xf77b6750 2 sym._dl_debug_state
0xf77b8e90 75 sym.___tls_get_addr
0xf77c8040 2104 sym._rtld_global
0xf77b8ee0 9 sym.__tls_get_addr
0xf77b9280 150 sym._dl_make_stack_executable
0xf77bc880 40 sym.malloc
0xf77b8860 571 sym._dl_allocate_tls_init
0xf77c7d20 468 sym._rtld_global_ro
0xf77c7f2c 4 sym.__libc_enable_secure
0xf77a7000 0 sym.GLIBC_2.0
0xf77afcc0 473 sym._dl_rtld_di_serinfo
[0xf77a7c60]> iR

[0xf77a7c60]> il

When I load the binary directly with r2, i get the following results:

[0x08048600]> is
[Symbols]
vaddr=0x0804a11c paddr=0x0000211c ord=016 fwd=NONE sz=4 bind=GLOBAL type=OBJECT name=_IO_stdin_used
vaddr=0x08048518 paddr=0x00000518 ord=001 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.sprintf
vaddr=0x08048528 paddr=0x00000528 ord=002 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.getchar
vaddr=0x08048538 paddr=0x00000538 ord=003 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp.__gmon_start__
vaddr=0x00000000 paddr=0x00000000 ord=004 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._Jv_RegisterClasses
vaddr=0x08048548 paddr=0x00000548 ord=005 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=operatordelete(void*)
vaddr=0x08048558 paddr=0x00000558 ord=006 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.putchar
vaddr=0x08048568 paddr=0x00000568 ord=007 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.memset
vaddr=0x08048578 paddr=0x00000578 ord=008 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.__libc_start_main
vaddr=0x08048588 paddr=0x00000588 ord=009 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.tcgetattr
vaddr=0x08048598 paddr=0x00000598 ord=010 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.strlen
vaddr=0x080485a8 paddr=0x000005a8 ord=011 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.printf
vaddr=0x080485b8 paddr=0x000005b8 ord=012 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=operatornew[](unsignedint)
vaddr=0x080485c8 paddr=0x000005c8 ord=013 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.tcsetattr
vaddr=0x080485d8 paddr=0x000005d8 ord=014 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.sscanf
vaddr=0x080485e8 paddr=0x000005e8 ord=015 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.__gxx_personality_v0

16 symbols

[0x08048600]> il
[Linked libraries]
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6

4 libraries
radare commented 6 years ago

.dmm* loads the info as flags. Is will not show anything because it didnt loaded the bin inside r2. Just the flags

On 2 Dec 2017, at 19:49, bannsec notifications@github.com wrote:

It would look like dmm would provide the needed loading commands, but it doesn't seem to load as expected:

[0xf77a7c60]> dmm f mod._home_r2_radare_work_app17unix = 0x08048000 .!rabin2 -rsB 0x08048000 '/home/r2/radare_work/app17unix' f mod._lib_i386_linux_gnu_ld_2.19.so = 0xf77a7000 .!rabin2 -rsB 0xf77a7000 '/lib/i386-linux-gnu/ld-2.19.so' [0xf77a7c60]> .dmm [0xf77a7c60]> is

[0xf77a7c60]> f 0x0804a11c 4 sym._IO_stdin_used 0x08048548 16 sym.operatordelete_void 0x080485b8 16 sym.operatornew__unsignedint 0xf77a7000 0 sym.GLIBC_2.1 0xf77b8760 30 sym._dl_get_tls_static_info 0xf77a7000 0 sym.GLIBC_PRIVATE 0xf77a7000 0 sym.GLIBC_2.3 0xf77a7000 0 sym.GLIBC_2.4 0xf77bc900 80 sym.free 0xf77bc9d0 144 sym.realloc 0xf77b8aa0 37 sym._dl_allocate_tls 0xf77c8918 20 sym._r_debug 0xf77c7f28 4 sym.libc_stack_end 0xf77bc770 268 sym.libc_memalign 0xf77b8ad0 133 sym._dl_deallocate_tls 0xf77b9cb0 177 sym._dl_find_dso_for_object 0xf77bc8b0 74 sym.calloc 0xf77c7efc 4 sym._dl_argv 0xf77b7fc0 550 sym._dl_mcount 0xf77b8690 203 sym._dl_tls_setup 0xf77b6750 2 sym._dl_debugstate 0xf77b8e90 75 sym.tls_get_addr 0xf77c8040 2104 sym._rtld_global 0xf77b8ee0 9 sym.__tls_get_addr 0xf77b9280 150 sym._dl_make_stack_executable 0xf77bc880 40 sym.malloc 0xf77b8860 571 sym._dl_allocate_tls_init 0xf77c7d20 468 sym._rtld_global_ro 0xf77c7f2c 4 sym.__libc_enable_secure 0xf77a7000 0 sym.GLIBC_2.0 0xf77afcc0 473 sym._dl_rtld_di_serinfo [0xf77a7c60]> iR

[0xf77a7c60]> il

When I load the binary directly with r2, i get the following results:

[0x08048600]> is [Symbols] vaddr=0x0804a11c paddr=0x0000211c ord=016 fwd=NONE sz=4 bind=GLOBAL type=OBJECT name=_IO_stdin_used vaddr=0x08048518 paddr=0x00000518 ord=001 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.sprintf vaddr=0x08048528 paddr=0x00000528 ord=002 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.getchar vaddr=0x08048538 paddr=0x00000538 ord=003 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp.__gmon_start vaddr=0x00000000 paddr=0x00000000 ord=004 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._Jv_RegisterClasses vaddr=0x08048548 paddr=0x00000548 ord=005 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=operatordelete(void*) vaddr=0x08048558 paddr=0x00000558 ord=006 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.putchar vaddr=0x08048568 paddr=0x00000568 ord=007 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.memset vaddr=0x08048578 paddr=0x00000578 ord=008 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.libc_start_main vaddr=0x08048588 paddr=0x00000588 ord=009 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.tcgetattr vaddr=0x08048598 paddr=0x00000598 ord=010 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.strlen vaddr=0x080485a8 paddr=0x000005a8 ord=011 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.printf vaddr=0x080485b8 paddr=0x000005b8 ord=012 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=operatornew vaddr=0x080485c8 paddr=0x000005c8 ord=013 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.tcsetattr vaddr=0x080485d8 paddr=0x000005d8 ord=014 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.sscanf vaddr=0x080485e8 paddr=0x000005e8 ord=015 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.__gxx_personality_v0

16 symbols

[0x08048600]> il [Linked libraries] libstdc++.so.6 libm.so.6 libgcc_s.so.1 libc.so.6

4 libraries — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

bannsec commented 6 years ago

So I have created a python function to load up all files after attaching to gdbserver:

def load_modules():
    modules = r2.cmdj("dmmj")
    for module in modules:
        r2.cmd("oba {addr:d} {file_name:s}".format(file_name=module['file'], addr=module['address']))

Manually running this after opening r2 using #!python2 <script_file>.py seems to work. However, attempting to run this on load does not:

$ r2 -d -c "#!python2 /tmp/pwnyQHp7g.gdb.py" gdb://127.0.0.1:33529
= attach 9210 0
Traceback (most recent call last):
  File "/tmp/pwnyQHp7g.gdb.py", line 8, in <module>
    load_modules()
  File "/tmp/pwnyQHp7g.gdb.py", line 4, in load_modules
    modules = r2.cmdj("dmmj")
NameError: global name 'r2' is not defined
 -- Execute a command on the visual prompt with cmd.vprompt
[0xf778cc60]> 

It appears that the r2pipe instance is not being created in time for my script to use it.

bannsec commented 6 years ago

So I've found out that if I run #!python2 first, to get an interactive prompt, exit that prompt, then run my script again it works. However, that breaks the purpose of trying to run this right off the bat.

Example:

= attach 10153 0
Traceback (most recent call last):
  File "/tmp/pwnHrcGmy.gdb.py", line 12, in <module>
    load_modules()
  File "/tmp/pwnHrcGmy.gdb.py", line 6, in load_modules
    modules = r2.cmdj("dmmj")
NameError: global name 'r2' is not defined
 -- Use 'e' and 't' in Visual mode to edit configuration and track flags.
[0x7f4a77039130]> #!python2 /tmp/pwnHrcGmy.gdb.py
Traceback (most recent call last):
  File "/tmp/pwnHrcGmy.gdb.py", line 12, in <module>
    load_modules()
  File "/tmp/pwnHrcGmy.gdb.py", line 6, in load_modules
    modules = r2.cmdj("dmmj")
NameError: global name 'r2' is not defined
[0x7f4a77039130]> #!python2
Traceback (most recent call last):
  File "<string>", line 9, in <module>
Exception: Cannot find IPython
^D

[0x7f4a77039130]> #!python2 /tmp/pwnHrcGmy.gdb.py
[0x7f4a77039130]> is
[Symbols]
vaddr=0x56339a36c010 paddr=0x00002010 ord=016 fwd=NONE sz=8 bind=GLOBAL type=OBJECT name=stdout
vaddr=0x56339a36b7fa paddr=0x002017fa ord=001 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._ITM_deregisterTMCloneTable
vaddr=0x56339a16a7b0 paddr=0x000007b0 ord=002 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.puts
vaddr=0x56339a16a7b8 paddr=0x000007b8 ord=003 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.__stack_chk_fail
vaddr=0x56339a16a7c0 paddr=0x000007c0 ord=004 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.printf
vaddr=0x56339a16a7c8 paddr=0x000007c8 ord=005 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.alarm
vaddr=0x56339a36b7fa paddr=0x002017fa ord=006 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.__libc_start_main
vaddr=0x56339a36b7fa paddr=0x002017fa ord=007 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp.__gmon_start__
vaddr=0x56339a16a7d0 paddr=0x000007d0 ord=008 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.prctl
vaddr=0x56339a16a7d8 paddr=0x000007d8 ord=009 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.setvbuf
vaddr=0x56339a16a7e0 paddr=0x000007e0 ord=010 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.perror
vaddr=0x56339a36b7fa paddr=0x002017fa ord=011 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._Jv_RegisterClasses
vaddr=0x56339a16a7e8 paddr=0x000007e8 ord=012 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.__isoc99_scanf
vaddr=0x56339a16a7f0 paddr=0x000007f0 ord=013 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.exit
vaddr=0x56339a36b7fa paddr=0x002017fa ord=014 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._ITM_registerTMCloneTable
vaddr=0x56339a16a7f8 paddr=0x000007f8 ord=015 fwd=NONE sz=16 bind=WEAK type=FUNC name=imp.__cxa_finalize

16 symbols

[0x7f4a77039130]> 
radare commented 6 years ago

Use -i instead of -c#!py...

Also wheres the r2=r2pipe.open() line in your script?

On 2 Dec 2017, at 23:35, bannsec notifications@github.com wrote:

So I've found out that if I run #!python2 first, to get an interactive prompt, exit that prompt, then run my script again it works. However, that breaks the purpose of trying to run this right off the bat.

Example:

= attach 10153 0 Traceback (most recent call last): File "/tmp/pwnHrcGmy.gdb.py", line 12, in load_modules() File "/tmp/pwnHrcGmy.gdb.py", line 6, in load_modules modules = r2.cmdj("dmmj") NameError: global name 'r2' is not defined -- Use 'e' and 't' in Visual mode to edit configuration and track flags. [0x7f4a77039130]> #!python2 /tmp/pwnHrcGmy.gdb.py Traceback (most recent call last): File "/tmp/pwnHrcGmy.gdb.py", line 12, in load_modules() File "/tmp/pwnHrcGmy.gdb.py", line 6, in load_modules modules = r2.cmdj("dmmj") NameError: global name 'r2' is not defined [0x7f4a77039130]> #!python2 Traceback (most recent call last): File "", line 9, in Exception: Cannot find IPython ^D

[0x7f4a77039130]> #!python2 /tmp/pwnHrcGmy.gdb.py [0x7f4a77039130]> is [Symbols] vaddr=0x56339a36c010 paddr=0x00002010 ord=016 fwd=NONE sz=8 bind=GLOBAL type=OBJECT name=stdout vaddr=0x56339a36b7fa paddr=0x002017fa ord=001 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._ITM_deregisterTMCloneTable vaddr=0x56339a16a7b0 paddr=0x000007b0 ord=002 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.puts vaddr=0x56339a16a7b8 paddr=0x000007b8 ord=003 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.stack_chk_fail vaddr=0x56339a16a7c0 paddr=0x000007c0 ord=004 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.printf vaddr=0x56339a16a7c8 paddr=0x000007c8 ord=005 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.alarm vaddr=0x56339a36b7fa paddr=0x002017fa ord=006 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.libc_start_main vaddr=0x56339a36b7fa paddr=0x002017fa ord=007 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp.gmon_start vaddr=0x56339a16a7d0 paddr=0x000007d0 ord=008 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.prctl vaddr=0x56339a16a7d8 paddr=0x000007d8 ord=009 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.setvbuf vaddr=0x56339a16a7e0 paddr=0x000007e0 ord=010 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.perror vaddr=0x56339a36b7fa paddr=0x002017fa ord=011 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._Jv_RegisterClasses vaddr=0x56339a16a7e8 paddr=0x000007e8 ord=012 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.isoc99_scanf vaddr=0x56339a16a7f0 paddr=0x000007f0 ord=013 fwd=NONE sz=16 bind=GLOBAL type=FUNC name=imp.exit vaddr=0x56339a36b7fa paddr=0x002017fa ord=014 fwd=NONE sz=16 bind=WEAK type=NOTYPE name=imp._ITM_registerTMCloneTable vaddr=0x56339a16a7f8 paddr=0x000007f8 ord=015 fwd=NONE sz=16 bind=WEAK type=FUNC name=imp.cxa_finalize

16 symbols

[0x7f4a77039130]> — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

bannsec commented 6 years ago

I'm using the r2 that is implicitly available from running the script with #!python2. My assumption was that was intentional functionality to allow you to talk to the application you're currently using.

Explicitly adding that instantiation fixed the error.

SrimantaBarua commented 6 years ago
  1. Are you using the standard gdbserver or maybe something like lldb's debugserver?
  2. What is the target platform?
  3. If you're using gdbserver and the target is Linux, try r2 -e dbg.exe.path=</path/to/local/file> -d gdb://host:port
abcSup commented 4 years ago

Hello @bannsec. Thank you for reporting the issue and I am here to check again if the issue is still ongoing. I appreciate that if you can help me to confirm it again with the latest r2 or you can provide me with more details (steps, files, platforms) on how to reproduce the issue.

r2 has changed a lot since you reported the issue. I can confirm that doing is after connecting to a remote gdb will definitely output some symbols. Symbols are loaded from the binary via the gdb connection when connecting.

$ gdbserver host:4444 /bin/ls
$ r2 -d gdb://localhost:4444
= attach 4300 1
= attach 4300 0
 -- How about a nice game of chess?
[0x7ffff7dd6090]> is
[Symbols]
nth paddr       vaddr          bind   type   size lib name
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
119  ---------- 0x00220280     GLOBAL OBJ    8        __progname
120  0x000201e0 0x5555557741e0 GLOBAL OBJ    4        ls_mode
121  0x0001636c 0x55555556a36c GLOBAL FUNC   0        _fini
122  ---------- 0x00220290     GLOBAL OBJ    4        optind
123  0x00003758 0x555555557758 GLOBAL FUNC   0        _init
124  ---------- 0x002202a8     WEAK   OBJ    8        program_invocation_name
125  ---------- 0x00220268     GLOBAL NOTYPE 0        __bss_start
------------------------------snipped------------------------------
[0x7ffff7dd6090]>