Skip to content

Instantly share code, notes, and snippets.

@lanzafame
Forked from leegao/worst_practices_in_gcc.c
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lanzafame/842a22ee9aeadca334bb to your computer and use it in GitHub Desktop.
Save lanzafame/842a22ee9aeadca334bb to your computer and use it in GitHub Desktop.
The guide to getting fired: horrendous abuses of GCC.
For fun only: most of what is listed here are undefined with respect to the C standard, hence for obvious reasons they are not portable (sigh of relief comming from audience).
Tested with GCC (and codepad), so use #ifdef __GNUC__ to enclose all of these examples.
1: Map - Reduce in C ... as Macros ...
#define MAP(fn, ret_type, fst, ...) ({ \
typeof(fst) from[] = {(fst), __VA_ARGS__ }; \
ret_type to[sizeof(from)/sizeof(typeof(fst))]; \
int i, n = sizeof(from)/sizeof(typeof(fst)); \
for(i=0;i<n;i++) to[i]=(fn)(from[i]); \
&to;}) \
// MAP(atoi, int, "1", "2", "3", "4", "5")
#define FOLD(fn, acc, fst, ...) ({ \
typeof(fst) from[] = {(fst), __VA_ARGS__ }; \
typeof(acc) accumulator = acc; \
int i, n = sizeof(from)/sizeof(typeof(fst)); \
for(i=0;i<n;i++) accumulator = (fn)(accumulator, from[i]); \
accumulator;}) \
// FOLD(add, 0., 1, 2, 3, 4, 5);
2: Casting functions into char* pointers
char* code = (char*)(&add); // I don't know why you would ever need to...
or casting pointers of other types into function pointers (On x86 machines):
The following will actually run:
int eax = ((int(*)())("\xc3"))()
This will return the immediate value of the EAX register when called
Even worse, writing the swap function in machine code
int a = 10, b = 20;
((void(*)(int,int))"\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3")(a,b);
A for-loop to 1000:
((int(*)())"\x66\x31\xc0\x8b\x5c\x24\x04\x66\x40\x50\xff\xd3\x58\x66\x3d\xe8\x03\x75\xf4\xc3")(&function); // calls function with 1->1000
Recursion (repeatedly checks if %eax is >= 100)
const char* lol = "\x8b\x5c\x24\x4\x3d\xe8\x3\x0\x0\x7e\x2\x31\xc0\x83\xf8\x64\x7d\x6\x40\x53\xff\xd3\x5b\xc3\xc3\x5d\xc3\x55\x89\xe5\x83\xe4\xf0\x83\xec\x20\xb8\xce\x83\x4";
i = ((int(*)(int*))(lol))(lol);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment