How can I disassemble a function in .rel.dyn with gdb? - gdb

I have a function _ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E(demangled name) defined in a shared library called libtiflash_proxy.so and used in a binary tiflash.
I know I can disassemble this function by objdump -d tiflash-dir/libtiflash_proxy.so | grep ....
15c1088: 48 8d 05 39 6e 25 02 lea 0x2256e39(%rip),%rax # 3817ec8 <_ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E>
15c108f: 48 89 45 80 mov %rax,-0x80(%rbp)
However, when I call gdb tiflash, and try to disassemble it in gdb, it outputs
(gdb) disass _ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E
No symbol "_ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E" in current context.
I know this function is in a .rel.dyn section. Maybe because of this, I can't just disassemble it from name.
# nm tiflash-dir/libtiflash_proxy.so | grep "_ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E"
0000000003817ec8 d _ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E
# readelf -r tiflash-dir/libtiflash_proxy.so | grep "3817ec8"
000003817ec8 000000000008 R_X86_64_RELATIVE 3817ee8
My question is is there any ways that I can disassemble _ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E in gdb?

However, when I call gdb tiflash, and try to disassemble it in gdb, it outputs
That's because the function is not defined in the tiflash binary.
Since it's defined in the .so, you could use that:
gdb -q libtiflash_proxy.so
(gdb) disas _ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E
P.S. If you can run the binary (under GDB) until the point at which libtiflash_proxy.so is loaded into the process, disas _ZN12proxy_server3run28run_impl_only_for_decryption2RS17h0667553f3e6e2968E would work from that point on.
P.P.S.
demangled name
No: that's mangled name. Demangled name is proxy_server::run::run_impl_only_for_decryption::RS::h0667553f3e6e2968

Related

I can't use sscanf in linux, thouh i have include the header file [duplicate]

Having trouble stepping into string.h in GDB 7.5. Here's a simple example program:
Source code:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20];
strcpy(str1, "STEP INTO ME\n");
printf(str1);
}
Compiled: ~$ gcc -g foo.c
Invoked: ~$ gdb -q ./a.out
GDB:
(gdb) break 5
Breakpoint 1 at 0x8048471: file foo.c, line 6.
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (strcpy) pending.
(gdb) run
Starting program: /home/user/a.out
Breakpoint 1, main () at foo.c:6
6 strcpy(str_a, "Hello, world!\n");
(gdb) step
7 printf(str_a);
Shouldn't I be in the string library at this point? Instead it continues to the printf().
EDIT:
Scott's suggestion "worked", but not in the expected manner.
Breakpoint 1, main () at foo.c:6
6 strcpy(str_a, "Hello, world!\n");
(gdb) i r $eip
eip 0x80484a1 0x80484a1 <main+21>
(gdb) step
Breakpoint 2, __strcpy_ssse3 () at ../sysdeps/i386/i686/multiarch/strcpy-ssse3.S:78
78 ../sysdeps/i386/i686/multiarch/strcpy-ssse3.S: No such file or directory.
(gdb) i r $eip
eip 0xb7e9c820 0xb7e9c820 <__strcpy_ssse3>
I am surprised at the directory in 78... expected something like: /lib/.../cmov/libc.so.6. And the claim that there is no such file or directory.
Recompile your code with gcc -fno-builtin -g foo.c and the gdb step command will work. (See -fno-builtin documentation). Otherwise small strcpy(), memcpy() calls would often be translated into open coded data movement instructions, e.g. on x86-64:
4 int main() {
0x000000000040052c <+0>: push %rbp
0x000000000040052d <+1>: mov %rsp,%rbp
0x0000000000400530 <+4>: sub $0x20,%rsp
5 char str1[20];
6 strcpy(str1, "STEP INTO ME\n");
0x0000000000400534 <+8>: lea -0x20(%rbp),%rax
0x0000000000400538 <+12>: movl $0x50455453,(%rax)
0x000000000040053e <+18>: movl $0x544e4920,0x4(%rax)
0x0000000000400545 <+25>: movl $0x454d204f,0x8(%rax)
0x000000000040054c <+32>: movw $0xa,0xc(%rax)
7 printf(str1);
0x0000000000400552 <+38>: lea -0x20(%rbp),%rax
0x0000000000400556 <+42>: mov %rax,%rdi
0x0000000000400559 <+45>: mov $0x0,%eax
0x000000000040055e <+50>: callq 0x400410 <printf#plt>
8 }
0x0000000000400563 <+55>: leaveq
0x0000000000400564 <+56>: retq
You can see the strpcy() call being compiled into multiple MOV instructions.
gcc -fno-builtin compiles the same program into:
4 int main() {
0x000000000040057c <+0>: push %rbp
0x000000000040057d <+1>: mov %rsp,%rbp
0x0000000000400580 <+4>: sub $0x20,%rsp
5 char str1[20];
6 strcpy(str1, "STEP INTO ME\n");
0x0000000000400584 <+8>: lea -0x20(%rbp),%rax
0x0000000000400588 <+12>: mov $0x400660,%esi
0x000000000040058d <+17>: mov %rax,%rdi
0x0000000000400590 <+20>: callq 0x400450 <strcpy#plt>
7 printf(str1);
0x0000000000400595 <+25>: lea -0x20(%rbp),%rax
0x0000000000400599 <+29>: mov %rax,%rdi
0x000000000040059c <+32>: mov $0x0,%eax
0x00000000004005a1 <+37>: callq 0x400460 <printf#plt>
8 }
0x00000000004005a6 <+42>: leaveq
0x00000000004005a7 <+43>: retq
and you can see the call to <strcpy#plt>.
Assuming you wanted to step into strcpy() to study its implementation, you'd want to have debug info for libc.so installed. Unfortunately the way to get debug info differs between Linux distros. On Fedora it's as simple as debuginfo-install glibc. It takes more steps on Ubuntu and Debian. This RPM DPKG Rosetta Stone page have links to instructions for Fedora, Ubuntu and Debian (search for debuginfo).
Since you're on Ubuntu 12.10 and actually want to see the strcpy() assembly source code:
$ sudo apt-get install libc6-dbg
$ sudo apt-get source libc6-dev
$ gdb ./a.out
(gdb) directory eglibc-2.15/sysdeps
Source directories searched: /home/scottt/eglibc-2.15/sysdeps:$cdir:$cwd
(gdb) break strcpy
Breakpoint 1 at 0x400450
(gdb) run
Starting program: /home/scottt/a.out
Breakpoint 1, __strcpy_sse2 () at ../sysdeps/x86_64/multiarch/../strcpy.S:32
32 movq %rsi, %rcx /* Source register. */
You tried to set a breakpoint for a function defined in the string library usually part of the standard C library - libc.so
And as gdb informs you:
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (strcpy) pending.
the library is not loaded yet.
But the real problem is, even when the library is loaded, if the library i.e. libc.so does not have debug symbols in it, you would not be able to step through the code within the library using gdb.
You could enable verbose mode to see which symbols, gdb is able to load:
(gdb) b main
Breakpoint 1 at 0x400914: file test.cpp, line 7.
(gdb) set verbose on
(gdb) run
Starting program: /home/agururaghave/.scratch/gdb-test/test
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from system-supplied DSO at 0x7ffff7ffb000...(no debugging symbols found)...done.
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Registering libstdc++-v6 pretty-printer for /usr/lib64/libstdc++.so.6 ...
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Breakpoint 1, main () at test.cpp:7
7 bool result = myObj1 < myObj2;
This line for example tells you whether it was able to get the symbols for libc.so:
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
You could then figure out where the debug symbols are picked up from using show debug-file-directory:
(gdb) show debug-file-directory
The directory where separate debug symbols are searched for is "/usr/lib/debug".
As you see /usr/lib/debug here does not contain the full .so with debug symbols. Instead it only has the debug info without any .text or .data sections of the actual libc.so which the program uses for execution.
The solution to install the debug info for libraries would be distro specific.
I think the package is called libc6-dbg on the debian based distros. On my openSUSE machine, it seems to be called glibc-debuginfo
BTW, +1 on scottt's suggestion of using -fno-builtin so that gcc does not use its built-in methods for functions like strcpy and other standard ones defined as part of C standard.
You probably don't have any symbols for your C library. Try stepi, but be prepared to see only assembly instructions.

Determining size of c++ method

I have a .cpp file with various methods defined:
// test.cpp
// foo() is not inlined
void foo() {
...
}
I compile it:
g++ test.cpp -o test.o -S
And now I want to determine, from examination of test.o, how many bytes of memory the instruction foo() takes up. How can I do this?
I ask because I have, through careful profiling and experimentation, determined that I am incurring instruction cache misses leading to significant slowdowns on certain critical paths. I'd therefore like to get a sense of how many bytes are occupied by various methods, to guide my efforts in shrinking my instruction set size.
I wouldn't recommend the -S flag for that, unless you're in love with your ISA's manual and hand-calculating instruction sizes. Instead, just build and disassemble, presto - out comes the answer:
$ cc -c example.c
$ objdump -d example.o
example.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 8b 45 fc mov -0x4(%rbp),%eax
a: 83 c0 03 add $0x3,%eax
d: 5d pop %rbp
e: c3 retq
As you can see, this function is 15 bytes long.
Build with map file generation, parse the map file. There might be some padding in the end, but it'll give you an idea.
In g++, the option goes:
-Xlinker -Map=MyProject.txt

Getting an address and the cointain in GDB

I have a program in ASM (NASM) and I want obtain an address, but some strange error happen when I was debugging with GDB (I typed "next" and the program exited). Is there some bug in GDB?
test.asm
BITS 32
section .text
global _start
_start:
call function
mov eax,0x41414141
function:
# esi get the address of "mov eax,0x41414141"
pop esi
# Exit
xor eax,eax
xor ebx,ebx
mov al,0x01
int 0x80
Debugging
$ nasm -f elf test.asm
$ ld test.o -o test
$ gdb -q ./test
Reading symbols from /root/Desktop/test...(no debugging symbols found)...done.
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x08048060 _start
0x0804806a function
(gdb) b function
Breakpoint 1 at 0x804806a
(gdb) run # Execute _start
Starting program: /root/Desktop/test
Breakpoint 1, 0x0804806a in function ()
(gdb) # We're going to execute "pop esi" now
(gdb) next # Execute only 1 instruction
Single stepping until exit from function function,
which has no line number information.
[Inferior 1 (process 26492) exited normally]
# WHY EXIT? We was going to execute "pop esi" !!
You used "next" which tells gdb to do source level step (move to next line in source). As you did not build your executable with debug information included gdb does not know how to do this.
There are two solutions:
Build with debug info enabled. I do not know nasm, but it looks it uses the usual -g switch to enable debug info. Add this when assembling.
Use nexti in gdb. This will just execute next assembly instruction and will not care about source.

Converting assembly instructions to binary using objdump or gcc -c

I'm working on the buffer bomb lab and I'm stuck on one thing. I've written my exploit code to solve level 2 (firecracker) but I'm not sure how I can convert this to its raw form using gcc -c.
I've never written a compile-able assembly file but I have written instructions themselves and traced already written ones.. So I know how they work but I'm not sure how to syntactically write the code file itself.
Here are the current contents of the file I'm trying to convert to its raw form:
movl $0x1a4bb386, 0x804d200
push $0x0804915f
ret
What do I need to add to this so that it will compile using gcc -c or objdump -d?
I need to figure out how many bytes these instructions take up and how to insert them into the buffer so that I can write my buffer overflow exploit.
Thanks.
Compiled with gcc -m32 -c code.s
Output was a file code.o
I used objdump -d code.o > code.asm to obtain the raw assembly and bytes needed.
Output:
code.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: c7 05 00 d2 04 08 86 movl $0x1a4bb386,0x804d200
7: b3 4b 1a
a: 68 5f 91 04 08 push $0x804915f
f: c3 ret
I'm curious what the instruction does at VA 0x7 ... Is that just the rest of the instruction movl?

C++ name mangling decoder for g++?

is there any C++ name-mangling decoder for g++?
You can use c++filt to demangle c++ symbols. For instance
$ c++filt -n _Z1fv
f()
c++filt, example usage here:
Can we see the template instantiated code by C++ compiler
You may also be interested on the -C option of objdump:
objdump -CSr main.o
which demangles relocation references like:
char *sn = new char[4];
10: bf 04 00 00 00 mov $0x4,%edi
15: e8 00 00 00 00 callq 1a <main+0x1a>
16: R_X86_64_PC32 operator new[](unsigned long)-0x4
Without -C it would show the mangled name _Znam.
See also: Can objdump un-mangle names of C++ template functions?
There are also some online demanglers mentioned at Is there an online name demangler for C++? like http://demangler.com/ If it exists, there is SaaS of it.
nm also has a -C option.
you have c++filt. Recently I found an online tool as well.
1.
c++filt [-_|--strip-underscore]
[-n|--no-strip-underscore]
[-p|--no-params]
[-t|--types]
[-i|--no-verbose]
[-r|--no-recurse-limit]
[-R|--recurse-limit]
[-s format|--format=format]
[--help] [--version] [symbol…]
Example:
c++filt symbol
for more info
Online solution
visit