Converting assembly instructions to binary using objdump or gcc -c - 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?

Related

simavr ignores memory content of located sections

Question also posted in https://github.com/buserror/simavr/issues/484
For a project with an Atmega324P I use special sections to ensure that some code is located on desired addresses. Works fine on real target, but these sections are not loaded proper in simavr.
Any idea what is going wrong and how to solve this problem?
To reproduce this problem I use an Ubuntu system with avr-gcc (5.4.0), avr-gdb (10.1.90.20210103-git) and simavr (1.6+dfsg-3).
Create file main.c
#define ATT_SECTION_APP __attribute__((section(".app")))
int main () ATT_SECTION_APP;
int main () {
asm("nop");
return 0;
}
Build project and locate section .app to 0x7100
avr-gcc -c -o main.o main.c
avr-gcc -o main.elf -Wl,-section-start=.app=0x7100 -mmcu=atmega324p main.o
Check result in elf-file
Disassemble elf-file with avr-objdump -d main.elf
Disassembly of section .app:
00007100 <main>:
7100: cf 93 push r28
7102: df 93 push r29
7104: cd b7 in r28, 0x3d ; 61
7106: de b7 in r29, 0x3e ; 62
7108: 00 00 nop
710a: 80 e0 ldi r24, 0x00 ; 0
710c: 90 e0 ldi r25, 0x00 ; 0
710e: df 91 pop r29
7110: cf 91 pop r28
7112: 08 95 ret
Start simavr
simavr -g -m atmega324p main.elf
Start avr-gdb and show memory on location 0x7100
Start in another shell avr-gdb with avr-gdb main.elf.
Then execute the following commands on gdb console:
target remote localhost:1234
x/20b 0x7100
As you can see, the memory locations starting with 0x7100 are cleared (= 0xff) instead of showing the same content as in disassembly view. Symbols like main are shown as desired.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000 in __vectors ()
(gdb) x/20b 0x7100
0x7100 <main>: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0x7108 <main+8>: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0x7110 <main+16>: 0xff 0xff 0xff 0xff

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 does GCC create extra assembly instructions on my machine?

It has been a while since I started working with SSE/AVX intrinsic functions. I recently began writing a header for matrix transposition. I used a lot of if constexpr branches so that the compiler always selects the optimal instruction set depending on some template parameters. Now I wanted to check if everything works as expected by looking into the local disassembly with objdump. When using Clang, I get a clear output which basically contains only the assembly instructions corresponding to the utilized intrinsic functions. However, if I use GCC, the disassembly is quite bloated with extra instructions. A quick check on Godbolt shows me that those extra instructions in the GCC disassembly shouldn't be there.
Here is a small example:
#include <x86intrin.h>
#include <array>
std::array<__m256, 1> Test(std::array<__m256, 1> a)
{
std::array<__m256, 1> b;
b[0] = _mm256_unpacklo_ps(a[0], a[0]);
return b;
}
I compile with -march=native -Wall -Wextra -Wpedantic -pthread -O3 -DNDEBUG -std=gnu++1z. Then I use objdump -S -Mintel libassembly.a > libassembly.dump on the object file. For Clang (6.0.0), the result is:
In archive libassembly.a:
libAssembly.cpp.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_Z4TestSt5arrayIDv8_fLm1EE>:
0: c4 e3 7d 04 c0 50 vpermilps ymm0,ymm0,0x50
6: c3 ret
which is the same as Godbolt returns: Godbolt - Clang 6.0.0
For GCC (7.4) the output is
In archive libassembly.a:
libAssembly.cpp.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_Z4TestSt5arrayIDv8_fLm1EE>:
0: 4c 8d 54 24 08 lea r10,[rsp+0x8]
5: 48 83 e4 e0 and rsp,0xffffffffffffffe0
9: c5 fc 14 c0 vunpcklps ymm0,ymm0,ymm0
d: 41 ff 72 f8 push QWORD PTR [r10-0x8]
11: 55 push rbp
12: 48 89 e5 mov rbp,rsp
15: 41 52 push r10
17: 48 83 ec 28 sub rsp,0x28
1b: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
22: 00 00
24: 48 89 45 e8 mov QWORD PTR [rbp-0x18],rax
28: 31 c0 xor eax,eax
2a: 48 8b 45 e8 mov rax,QWORD PTR [rbp-0x18]
2e: 64 48 33 04 25 28 00 xor rax,QWORD PTR fs:0x28
35: 00 00
37: 75 0c jne 45 <_Z4TestSt5arrayIDv8_fLm1EE+0x45>
39: 48 83 c4 28 add rsp,0x28
3d: 41 5a pop r10
3f: 5d pop rbp
40: 49 8d 62 f8 lea rsp,[r10-0x8]
44: c3 ret
45: c5 f8 77 vzeroupper
48: e8 00 00 00 00 call 4d <_Z4TestSt5arrayIDv8_fLm1EE+0x4d>
As you can see, there are a lot of additional instructions. In contrast to that, Godbolt does not include all these extra instructions: Godbolt - GCC 7.4
So what is going on here? I have just started learning assembly, so maybe it is totally clear to someone with assembly experience, but I am a little bit confused why GCC creates those extra instructions on my machine.
Greetings and thank you in advance.
EDIT
To avoid further confusions, I just compiled using:
gcc-7 -I/usr/local/include -O3 -march=native -Wall -Wextra -Wpedantic -pthread -std=gnu++1z -o test.o -c /<PathToFolder>/libAssembly.cpp
Output remains the same. I am not sure if this is relevant, but it generates the warning:
warning: ignoring attributes on template argument ‘__m256 {aka __vector(8) float}’ [-Wignored-attributes]
Usually I surpress this warning and it shouldn't be an issue:
Implication of GCC warning: ignoring attributes on template argument (-Wignored-attributes)
Processor is Intel(R) Core(TM) i7-6700K CPU # 4.00GHz
Here is the gcc -v:
gcc-7 -v
Using built-in specs.
COLLECT_GCC=gcc-7
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.4.0-1ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
Use -fno-stack-protector
Your local GCC defaults to -fstack-protector-strong but Godbolt's GCC install doesn't.
mov rax,QWORD PTR fs:0x28 is the telltale clue; Thread-local storage at fs:40 aka fs:0x28 is where GCC keeps its stack cookie constant. The call after the ret is call __stack_chk_fail (but you disassembled a .o without using objdump -dr to show relocations, so the placeholder +0 offset just looked like still a target within this function).
Since you have arrays (or a class containing an array), stack-protector-strong kicks in even though their sizes are compile-time constants. So you get the code to store the stack cookie, then check it and branch on stack overflow. (Even the array of size 1 in this MVCE is enough to trigger that.)
Making arrays on the stack with 32-byte alignment (for __m256) requires 32-byte alignment, and your GCC is older than GCC8 so you get the ridiculously clunky stack-alignment code that builds a full copy of the stack frame including a return address. Generated assembly for extended alignment of stack variables (To be clear, GCC8 still does align the stack here, just wasting fewer instructions on it.)
This is pretty much a missed optimization; gcc never actually spills or reloads to those arrays so it could have just optimized them away, along with the stack alignment, like it did without stack-protector.
More recent GCC is better at optimizing away stack alignment after optimizing away the memory for aligned locals in more cases, but this has been a persistent missed optimization in AVX code. Fortunately the cost is pretty negligible in a function that loops; as long as small helper functions inline.
Compiling on Godbolt with -fstack-protector-strong reproduces your output. Newer GCC, including current trunk pre-10, still has both missed optimizations, but stack alignment costs fewer instructions because it just uses RBP as a frame pointer and aligns RSP, then references locals relative to aligned RSP. It still checks the stack cookie (with no instructions between storing it and checking it).
On your desktop, compiling with -fno-stack-protector should make good asm.

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

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