C++ name mangling decoder for g++? - c++

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

Related

How can I disassemble a function in .rel.dyn with 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

Valgrind reports SIGILL in std::string::swap

I am using valgrind 3.16 to debug my program, and it reports illegal instruction in std::string::swap. The program is compiled on Ubuntu 18.04 with g++ 7.5.0.
vex amd64->IR: unhandled instruction bytes: 0x62 0xF1 0xFE 0x8 0x6F 0x47 0x1 0xC5 0xF8 0x11
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0
==392550== valgrind: Unrecognised instruction at address 0x3fef89.
==392550== at 0x3FEF89: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /tmp/tmp.BnUAMaceSS/cmake-build-release-parallel-chameleon/release/lqf-tpch-query-dev)
==392550== by 0x4F4CD0C: std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
I have two questions:
Is there a website I can query instructions using the given OP code? I tried this website but cannot find anything corresponding to 0x62 0xF1 0xFE ...
Why would valgrind reports SIGILL in std library?
The code works well by itself. I also applied undefined,thread,leak and address sanitizer, and stack-check. They report no error. So I think the problem is from valgrind.
I really appreciate #TedLyngmo's comments of applying sanitizers. Although the sanitizer itself does not give any error, after applying sanitizer the error location changes. Now it is pointing to some of my code base which uses AVX 512 instructions. When I replace those instructions Valgrind can run.
Although I am still not sure why applying sanitizer will have such effect, I would like to share this experience with those who may encounter similar errors in the future.
Question 1: convert opcode to assembly
This website can disassemble opcode to assembly online for x86 or x64. For the opcode in your question, insert 62 F1 FE 08 6F 47 01 C5 F8 11 (note that use 08 for 0x8) to the text box under disassemble, then it outputs
Disassembly:
0: 62 f1 fe 08 6f 47 01 vmovdqu64 xmm0,XMMWORD PTR [rdi+0x10]
7: c5 .byte 0xc5
8: f8 clc
9: 11 .byte 0x11
So the instruction is vmovdqu64which is an AVX512 instruction.
Or you it can be hacked as following
$ cat instruct.c
#include <stdio.h>
int main(void)
{
asm(".byte 0x62, 0xF1, 0xFE, 0x8, 0x6F, 0x47, 0x1, 0xC5, 0xF8, 0x11");
return 0;
}
$ gcc -c instruct.c
$ objdump -drwC -Mintel instruct.o
instruct.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: f3 0f 1e fa endbr64
4: 55 push rbp
5: 48 89 e5 mov rbp,rsp
8: 62 f1 fe 08 6f 47 01 vmovdqu64 xmm0,XMMWORD PTR [rdi+0x10]
f: c5 f8 11 b8 00 00 00 00 vmovups XMMWORD PTR [rax+0x0],xmm7
17: 5d pop rbp
18: c3 ret
In order for valgrind to run a program with AVX512 instructions, one can compile the program with gcc flag -mno-avx512f as documented here which points out that extension instructions can be enabled with flag (e.g. -mavx512f) and disabled with a corresponding -mno- option.
Another way to use valgrind on a program with AVX512 instructions is to build Valgind from source and apply patches from here. Following are steps for it:
Clone valgrind source code
$ git clone https://sourceware.org/git/valgrind.git
$ cd valgrind
Download patches from here
Copy the patches to local files (e.g. patch512-part1.patch inside
folder
valgrind). Currently there are
four patches, and they look quite messy due to the fact that the author
keeps
updating it (which is good) and obsoleting old ones. One should also apply the
patches on top of right commit since new commits from valgrind master branch after the patches may break the
build system. For example, up to now patches from comment 58, 73, 60 and 74 and
on top of commit b77dbefe72e4a5c7bcf1576a02c909010bd56991 can be compiled
successfully.
$ git reset --hard b77dbefe72e4a5c7bcf1576a02c909010bd56991
Apply patches
$ patch -p1 < patch512-part1.patch
$ patch -p1 < patch512-part2.patch
$ patch -p1 < patch512-part3.patch
$ patch -p1 < patch512-part4.patch
Compile valgrind
$ ./autogen.sh
$ ./configure --prefix=<install-path>
$ make
$ make install

Why is my simple `main` program's ELF header say it's a `DYN (Shared object file)` instead of an executable? [duplicate]

This question already has answers here:
Why does GCC create a shared object instead of an executable binary according to file?
(2 answers)
Closed 2 years ago.
Here's a very simple C++ program:
// main.cpp
int main() {}
My Makefile generates the following command to compile the program.
❯ make
g++ -O0 -fverbose-asm -o main main.cpp
I check with the command file to see it's an ELF executable:
❯ file main
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=921d352e49a0e4262aece7e72418290189520782, for GNU/Linux 3.2.0, not stripped
Everything seems fine until I try to inspect the ELF header:
❯ readelf -e main
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
...
Type: DYN (Shared object file)
From wikipedia here, it appears that there are different types of files such as EXEC. Why does it say my simple main program is a shared object and not an executable on the ELF header?
From the limited scope of knowledge I have on .so's, I thought they were libraries that is linked but not loaded until runtime. How does that make sense in this context?
Extra information:
❯ g++ --version
g++ (Arch Linux 9.3.0-1) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
❯ readelf --version
GNU readelf (GNU Binutils) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.
❯ lsb_release -a
LSB Version: 1.4
Distributor ID: Arch
Description: Arch Linux
Release: rolling
Codename: n/a
Executables that are as compiled as "position independent executables" (with -pie/-fPIE) should be relocated to a random address at runtime. To achieve this, they use the DYN type.
Your version of g++ was configured with --enable-default-pie, so it sets -pie and -fPIE by default. You can disable this, and generate a normal executable, by linking with -no-pie.

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

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?