C/C++ inline assembler with instructions in string variables - c++

So as you know in C and C++ if using Visual-C you can have in line assembly instructions such as:
int main() {
printf("Hello\n");
__asm int 3
printf("this will not be printed.\n");
return 0;
}
Which will make a breakpoint inside of the executable. So my question is, is there somekind of function I can use to call __asm using a variable such as a char array. I was thinking something like this:
char instruction[100] = "int 3";
__asm instruction
But that doesn't seem to really work since it gives 'Invalid OP code'. So can you help with this or it isn't possible at all.

Neither C nor C++ are interpreted languages, the compiler generates the int 3 machine instruction at compile time. The compiled program will not recognise the string as an instruction at run-time - unless your program is itself an interpreter.
You can of course use a macro:
#define BREAKPOINT __asm int 3
int main()
{
printf("Hello\n");
BREAKPOINT ;
printf("this will not be printed.\n");
return 0;
}

The code of your program is created by the compiler, during compilation.
You are trying to feed the compiler the input for that at run time - when the program is already executing. If you want ‘on-the-fly-compilation’, you will have to program an incremental compiler and linker that can modify the code while executing it.
Note that even if you would be successful, many OS would block such execution, as it violates security. It would be a great way to build viruses, and is therefore typically blocked.

Related

Segmentation Fault before even the first line of `main()` is executed and there are no non-local variables

In the C++ code below, a segmentation fault occurs before the first line of main() is executed.
This happens even though there are no objects to be constructed before entering main() and it does not happen if I remove a (large) variable definition at the second line of main().
I assume the segmentation fault occurs because of the size of the variable being defined. My question is why does this occur before the prior line is executed?
It would seem this shouldn't be occurring due to instruction reordering by the optimizer. I say this based on the compilation options selected and based on debug output.
Is the size of the (array) variable being defined blowing the stack / causing the segfault?
It would seem so since using a smaller array (e.g. 15 elements) does not result in a segmentation fault and since the expected output to stdout is seen.
#include <array>
#include <iostream>
#include <vector>
using namespace std;
namespace {
using indexes_t = vector<unsigned int>;
using my_uint_t = unsigned long long int;
constexpr my_uint_t ITEMS{ 52 };
constexpr my_uint_t CHOICES{ 5 };
static_assert(CHOICES <= ITEMS, "CHOICES must be <= ITEMS");
constexpr my_uint_t combinations(const my_uint_t n, my_uint_t r)
{
if (r > n - r)
r = n - r;
my_uint_t rval{ 1 };
for (my_uint_t i{ 1 }; i <= r; ++i) {
rval *= n - r + i;
rval /= i;
}
return rval;
}
using hand_map_t = array<indexes_t, combinations(ITEMS, CHOICES)>;
class dynamic_loop_functor_t {
private:
// std::array of C(52,5) = 2,598,960 (initially) empty vector<unsigned int>
hand_map_t hand_map;
};
}
int main()
{
cout << "Starting main()..." << endl
<< std::flush;
// "Starting main()..." is not printed if and only if the line below is included.
dynamic_loop_functor_t dlf;
// The same result occurs with either of these alternatives:
// array<indexes_t, 2598960> hand_map;
// indexes_t hand_map[2598960];
}
OS: CentOS Linux release 7.9.2009 (Core)
Compiler: g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Compile command:
g++ -std=c++14 -Wall -Wpedantic -Og -g -o create_hand_map create_hand_map.cpp
No errors or warnings are generated at compile time.
Static analysis:
A static analysis via cppcheck produces no unexpected results.
Using check-config as suggested in the command output below yields only: Please note: Cppcheck does not need standard library headers to get proper results.
$ cppcheck --enable=all create_hand_map.cpp
create_hand_map.cpp:136:27: style: Unused variable: dlf [unusedVariable]
dynamic_loop_functor_t dlf;
^
nofile:0:0: information: Cppcheck cannot find all the include files (use --check-config for details) [missingIncludeSystem]
Attempted debug with GDB:
$ gdb ./create_hand_map
GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-36.el7
<snip>
This GDB was configured as "x86_64-redhat-linux-gnu".
<snip>
Reading symbols from ./create_hand_map...done.
(gdb) run
Starting program: ./create_hand_map
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400894 in std::operator<< <std::char_traits<char> > (__s=0x4009c0 "Starting main()...",
__out=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/ostream:561
561 __ostream_insert(__out, __s,
(gdb) bt
#0 0x0000000000400894 in std::operator<< <std::char_traits<char> > (
__s=0x4009c0 "Starting main()...", __out=...)
at /opt/rh/devtoolset-7/root/usr/include/c++/7/ostream:561
#1 main () at create_hand_map.cpp:133
(gdb)
This is definitely a stack overflow. sizeof(dynamic_loop_functor_t) is nearly 64 MiB, and the default stack size limit on most Linux distributions is only 8 MiB. So the crash is not surprising.
The remaining question is, why does the debugger identify the crash as coming from inside std::operator<<? The actual segfault results from the CPU exception raised by the first instruction to access to an address beyond the stack limit. The debugger only gets the address of the faulting instruction, and has to use the debug information provided by the compiler to associate this with a particular line of source code.
The results of this process are not always intuitive. There is not always a clear correspondence between instructions and source lines, especially when the optimizer may reorder instructions or combine code coming from different lines. Also, there are many cases where a bug or problem with one source line can cause a fault in another section of code that is otherwise innocent. So the source line shown by the debugger should always be taken with a grain of salt.
In this case, what happened is as follows.
The compiler determines the total amount of stack space to be needed by all local variables, and allocates it by subtracting this number from the stack pointer at the very beginning of the function, in the prologue. This is more efficient than doing a separate allocation for each local variable at the point of its declaration. (Note that constructors, if any, are not called until the point in the code where the variable's declaration actually appears.)
The prologue code is typically not associated with any particular line of source code, or maybe with the line containing the function's opening {. But in any case, subtracting from the stack pointer is a pure register operation; it does not access memory and therefore cannot cause a segfault by itself. Nonetheless, the stack pointer is now pointing outside the area mapped for the stack, so the next attempt to access memory near the stack pointer will segfault.
The next few instructions of main execute the cout << "Starting main". This is conceptually a call to the overloaded operator<< from the standard library; but in GCC's libstdc++, the operator<< is a very short function that simply calls an internal helper function named __ostream_insert. Since it is so short, the compiler decides to inline operator<< into main, and so main actually contains a call to __ostream_insert. This is the instruction that faults: the x86 call instruction pushes a return address to the stack, and the stack pointer, as noted, is out of bounds.
Now the instructions that set up arguments and call __ostream_insert are marked by the debug info as corresponding to the source of operator<<, in the <ostream> header file - even though those instructions have been inlined into main. Hence your debugger shows the crash as having occurred "inside" operator<<.
Had the compiler not inlined operator<< (e.g. if you compile without optimization), then main would have contained an actual call to operator<<, and this call is what would have crashed. In that case the traceback would have pointed to the cout << "Starting main" line in main itself - misleading in a different way.
Note that you can have GCC warn you about functions that use a large amount of stack with the options -Wstack-usage=NNN or -Wframe-larger-than=NNN. These are not enabled by -Wall, but could be useful to add to your build, especially if you expect to use large local objects. Specifying either of them, with a reasonable number for NNN (say 4000000), I get a warning on your main function.
You must raise the stack size limit before putting the huge object on stack.
In Linux you can achieve that by calling setrlimit() from main(). From then on you can invoke functions with huge stack objects. E.g.:
struct huge_t { /* something really huge lives here */ };
int main () {
struct rlimit rlim;
rlim.rlim_cur = sizeof (huge_t) + 1048576;
setrlimit (RLIMIT_STACK, &rlim);
return worker ();
}
int worker () {
struct huge_t huge;
/* do something with huge */
return EXIT_SUCCESS;
}
Because local objects are allocated on stack before you have the chance to call setrlimit() the huge object must be in worker().

Is there a way to turn off loop optimisation on both C++ and Rust compilation?

I'm looking for a compiler flag that will allow me to prevent the compiler optimising away the loop in code like this:
void func() {
std::unique_ptr<int> up1(new int(0)), up2;
up2 = move(up1);
for(int i = 0; i < 1000000000; i++) {
if(up2) {
*up2 += 1;
}
}
if(up2)
printf("%d", *up2);
}
in both C++ and Rust code. I'm trying to compare similar sections of code in terms of speed and running this loop rather than just evaluating the overall result is important. Since Rust statically guarantees that the pointer ownership hasn't been moved, it doesn't need the null pointer checks on each iteration of the loop and I would imagine therefore it would produce faster code if the loop couldn't be optimised out for whatever reason.
Rust compiles using an LLVM backend, so I would preferably be using that for C++ as well.
In Rust you can use test::black_box.
In C++ (using gcc) asm volatile("" : "+r" (datum));. See this.
One typical way to avoid having the compiler optimize away loops is to make their bounds indeterminate at compile time. In this example, rather than looping up to 10000000, loop up to a count which is read from stdin or argv.

C code decomposer

I was wondering whether there exists a program to break a c source code down to a lower level code by substituting all loops and function calls by goto statement. Thus, it would reduce a code to variable declaration/heap allocation, if statement, goto statement and logic/arithmetic functions.
I think such program would be useful for designing a virtual machine to interpret C code.
Example:
for(int a = 0; a < 100; a++){
printf("Hello");
}
would become
int a = 0;
if(!(a<100)){
goto endForLoopOne;
}
forLoopOne:
printf("Hello");
if(a<100){
a++;
goto forLoopOne;
}
endForLoopOne:
gcc and clang (or probably many other compilers) allows you to get assembly output from c source.
In gcc -S flag will produce a .s file.
gcc -S <your c source>
The syntax of assembly will be AT&T though.
From what i understand the functionality you are asking about is somewhat implemented in compiler construction. The original high level code is transformed to intermediate 3 address code. What i think a simple parser/compiler can be written that can do that. I wrote one such program for assignment in compiler design course this month.It was written in c using flex(lexical analyser) and bison(yacc).

Why does this program, which defines main as a function pointer, fail?

The following program compiles perfectly with no errors or warnings (even with -Wall) in g++, but crashes immediately.
#include <cstdio>
int stuff(void)
{
puts("hello there.");
return 0;
}
int (*main)(void) = stuff;
This is an (obviously horribly misguided) attempt at running a C++ program without explicitly declaring main as a function. It was my intention for the program to execute stuff by binding it to the symbol main. I was very surprised that this compiled, but why exactly does it fail, having compiled? I've looked at the generated assembly but I don't know enough to understand it at all.
I'm fully aware that there are plenty of restrictions on how main can be defined/used, but I'm unclear on how my program breaks any of them. I haven't overloaded main or called it within my program... so exactly what rule am I breaking by defining main this way?
Note: this was not something I was trying to do in actual code. It was actually the beginnings of an attempt to write Haskell in C++.
In the code that runs before main, there is something like:
extern "C" int main(int argc, char **argv);
The problem with your code is that if you have a function pointer called main, it is not a the same as a function (as opposed to Haskell where a function and a funciton pointer is pretty much interchangable - at least with my 0.1% knowledge of Haskell).
Whilst the compiler will happily accept:
int (*func)() = ...;
int x = func();
as a valid call to the function pointer func. However, when the compiler generates code to call func, it actually does this in a different way [although the standard doesn't say how this should be done, and it varies on different processor architectures, in practice it loads the value in the pointer variable, and then calls this content].
When you have:
int func() { ... }
int x = func();
the call to func just refers to the address of func itself, and calls that.
So, assuming your code actually does compile, the startup code before main will call the address of your variable main rather than indirectly reading the value in main and then calling that. In modern systems, this will cause a segfault because main lives in the data segment which is not executable, but in older OS's it would most likely crash due to main does not contain real code (but it may execute a few instructions before it falls over in this case - in the dim and distant past, I've accidentally run all sorts of "rubbish" with rather difficult to discover causes...)
But since main is a "special" function, it's also possible that the compiler says "No, you can't do this".
It used to work, many years ago to do this:
char main[] = { 0xXX, 0xYY, 0xZZ ... };
but again, this doesn't work in a modern OS, because main ends up in the data section, and it's not executable in that section.
Edit: After actually testing the posted code, at least on my 64-bit Linux, the code actually compiles, but crashes, unsurprisingly, when it tries to execute main.
Running in GDB gives this:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000600950 in main ()
(gdb) bt
#0 0x0000000000600950 in main ()
(gdb) disass
Dump of assembler code for function main:
=> 0x0000000000600950 <+0>: and %al,0x40(%rip) # 0x600996
0x0000000000600956 <+6>: add %al,(%rax)
End of assembler dump.
(gdb) disass stuff
Dump of assembler code for function stuff():
0x0000000000400520 <+0>: push %rbp
0x0000000000400521 <+1>: mov %rsp,%rbp
0x0000000000400524 <+4>: sub $0x10,%rsp
0x0000000000400528 <+8>: lea 0x400648,%rdi
0x0000000000400530 <+16>: callq 0x400410 <puts#plt>
0x0000000000400535 <+21>: mov $0x0,%ecx
0x000000000040053a <+26>: mov %eax,-0x4(%rbp)
0x000000000040053d <+29>: mov %ecx,%eax
0x000000000040053f <+31>: add $0x10,%rsp
0x0000000000400543 <+35>: pop %rbp
0x0000000000400544 <+36>: retq
End of assembler dump.
(gdb) x main
0x400520 <stuff()>: 0xe5894855
(gdb) p main
$1 = (int (*)(void)) 0x400520 <stuff()>
(gdb)
So, we can see that main is not really a function, it's a variable which contains a pointer to stuff. The startup code calls main as if it was a function, but it fails to execute the instructions there (because it's data, and data has the "no execute" bit set - not that you can see that here, but I know it works that way).
Edit2:
Inspecting dmesg shows:
a.out[7035]: segfault at 600950 ip 0000000000600950 sp 00007fff4e7cb928 error 15 in a.out[600000+1000]
In other words, the segmentation fault happens immediately with the execution of main - because it's not executable.
Edit3:
Ok, so it's slightly more convoluted than that (at least in my C runtime library), as the code that calls main is a function that takes the pointer to main as an argument, and calls it through a pointer. This however doesn't change the fact that when the compiler builds the code, it produces a level of indirection less than it needs, and tries to execute the variable called main rather than the function that the variable is pointing at.
Listing __libc_start_main in GDB:
87 STATIC int
88 LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
89 int argc, char *__unbounded *__unbounded ubp_av,
90 #ifdef LIBC_START_MAIN_AUXVEC_ARG
91 ElfW(auxv_t) *__unbounded auxvec,
92 #endif
At this point, printing main gives us a function pointer that points at 0x600950, which is the variable called main (same as what I dissassembled above)
(gdb) p main
$1 = (int (*)(int, char **, char **)) 0x600950 <main>
Note that this is a different variable main than the one called main in the source posted in the question.
There's nothing special here about it being main(). The same will happen if you do this for any function. Consider this example:
file1.cpp:
#include <cstdio>
void stuff(void)
{
puts("hello there.");
}
void (*func)(void) = stuff;
file2.cpp:
extern "C" {void func(void);}
int main(int argc, char**argv)
{
func();
}
This will also compile, and then segfault. It is essentially doing the same thing for the function func, but because the coding is explicit it now more apparently looks wrong. main() is a plain C type function with no name mangling, and just appears as a name in the symbol table. If you make it something other than a function, you get a segfault when it executes a pointer.
I guess the interesting part is that the compiler will allow you to define a symbol called main when it is already implicitly declared with a different type.

Direct C function call using GCC's inline assembly

If you want to call a C/C++ function from inline assembly, you can do something like this:
void callee() {}
void caller()
{
asm("call *%0" : : "r"(callee));
}
GCC will then emit code which looks like this:
movl $callee, %eax
call *%eax
This can be problematic since the indirect call will destroy the pipeline on older CPUs.
Since the address of callee is eventually a constant, one can imagine that it would be possible to use the i constraint. Quoting from the GCC online docs:
`i'
An immediate integer operand (one with constant value) is allowed. This
includes symbolic constants whose
values will be known only at assembly
time or later.
If I try to use it like this:
asm("call %0" : : "i"(callee));
I get the following error from the assembler:
Error: suffix or operands invalid for `call'
This is because GCC emits the code
call $callee
Instead of
call callee
So my question is whether it is possible to make GCC output the correct call.
I got the answer from GCC's mailing list:
asm("call %P0" : : "i"(callee)); // FIXME: missing clobbers
Now I just need to find out what %P0 actually means because it seems to be an undocumented feature...
Edit: After looking at the GCC source code, it's not exactly clear what the code P in front of a constraint means. But, among other things, it prevents GCC from putting a $ in front of constant values. Which is exactly what I need in this case.
For this to be safe, you need to tell the compiler about all registers that the function call might modify, e.g. : "eax", "ecx", "edx", "xmm0", "xmm1", ..., "st(0)", "st(1)", ....
See Calling printf in extended inline ASM for a full x86-64 example of correctly and safely making a function call from inline asm.
Maybe I am missing something here, but
extern "C" void callee(void)
{
}
void caller(void)
{
asm("call callee\n");
}
should work fine. You need extern "C" so that the name won't be decorated based on C++ naming mangling rules.
If you're generating 32-bit code (e.g. -m32 gcc option), the following asm inline emits a direct call:
asm ("call %0" :: "m" (callee));
The trick is string literal concatenation. Before GCC starts trying to get any real meaning from your code it will concatenate adjacent string literals, so even though assembly strings aren't the same as other strings you use in your program they should be concatenated if you do:
#define ASM_CALL(X) asm("\t call " X "\n")
int main(void) {
ASM_CALL( "my_function" );
return 0;
}
Since you are using GCC you could also do
#define ASM_CALL(X) asm("\t call " #X "\n")
int main(void) {
ASM_CALL(my_function);
return 0;
}
If you don't already know you should be aware that calling things from inline assembly is very tricky. When the compiler generates its own calls to other functions it includes code to set up and restore things before and after the call. It doesn't know that it should be doing any of this for your call, though. You will have to either include that yourself (very tricky to get right and may break with a compiler upgrade or compilation flags) or ensure that your function is written in such a way that it does not appear to have changed any registers or condition of the stack (or variable on it).
edit this will only work for C function names -- not C++ as they are mangled.