I know that C compilers are capable of taking standalone code, and generate standalone shellcode out of it for the specific system they are targetting.
For example, given the following in anon.c
:
int give3() {
return 3;
}
I can run
gcc anon.c -o anon.obj -c objdump -D anon.obj
which gives me (on MinGW):
anon1.obj: file format pe-i386
Disassembly of section .text:
00000000 <_give3>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: b8 03 00 00 00 mov $0x3,%eax
8: 5d pop %ebp
9: c3 ret
a: 90 nop
b: 90 nop
So I can make main like this:
main.c
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv)
{
uint8_t shellcode[] = {
0x55,
0x89, 0xe5,
0xb8, 0x03, 0x00, 0x00, 0x00,
0x5d, 0xc3,
0x90,
0x90
};
int (*p_give3)() = (int (*)())shellcode;
printf("%d.\n", (*p_give3)());
}
My question is, is it practical to automate the process of converting the self contained anonymous function that does not refer to anything that is not within its scope or in arguments?
eg:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv)
{
uint8_t shellcode[] = [@[
int anonymous() {
return 3;
}
]];
int (*p_give3)() = (int (*)())shellcode;
printf("%d.\n", (*p_give3)());
}
Which would compile the text into shellcode, and place it into the buffer?
The reason I ask is because I really like writing C, but making pthreads, callbacks is incredibly painful; and as soon as you go one step above C to get the notion of "lambdas", you lose your language's ABI(eg, C++ has lambda, but everything you do in C++ is suddenly implementation dependent), and "Lisplike" scripting addons(eg plug in Lisp, Perl, JavaScript/V8, any other runtime that already knows how to generalize callbacks) make callbacks very easy, but also much more expensive than tossing shellcode around.
If this is practical, then it is possible to put functions which are only called once into the body of the function calling it, thus reducing global scope pollution. It also means that you do not need to generate the shellcode manually for each system you are targetting, since each system's C compiler already knows how to turn self contained C into assembly, so why should you do it for it, and ruin readability of your own code with a bunch of binary blobs.
So the question is: is this practical(for functions which are perfectly self contained, eg even if they want to call puts, puts has to be given as an argument or inside a hash table/struct in an argument)? Or is there some issue preventing this from being practical?