Tech News
← Back to articles

Implementing a web server in a single printf() call (2014)

read original related products more articles

A guy just forwarded a joke that most of us will already know Jeff Dean Facts (also here and here). Everytime I read that list, this part stands out:

Jeff Dean once implemented a web server in a single printf() call. Other engineers added thousands of lines of explanatory comments but still don’t understand exactly how it works. Today that program is the front-end to Google Search.

It is really possible to implement a web server using a single printf call, but I haven’t found anyone doing it. So this time after reading the list, I decided to implement it. So here is the code, a pure single printf call, without any extra variables or macros (don’t worry, I will explain how to this code works)

#include int main(int argc, char *argv[]) { printf("%*c%hn%*c%hn" "\xeb\x3d\x48\x54\x54\x50\x2f\x31\x2e\x30\x20\x32" "\x30\x30\x0d\x0a\x43\x6f\x6e\x74\x65\x6e\x74\x2d" "\x74\x79\x70\x65\x3a\x74\x65\x78\x74\x2f\x68\x74" "\x6d\x6c\x0d\x0a\x0d\x0a\x3c\x68\x31\x3e\x48\x65" "\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x3c\x2f" "\x68\x31\x3e\x4c\x8d\x2d\xbc\xff\xff\xff\x48\x89" "\xe3\x48\x83\xeb\x10\x48\x31\xc0\x50\x66\xb8\x1f" "\x90\xc1\xe0\x10\xb0\x02\x50\x31\xd2\x31\xf6\xff" "\xc6\x89\xf7\xff\xc7\x31\xc0\xb0\x29\x0f\x05\x49" "\x89\xc2\x31\xd2\xb2\x10\x48\x89\xde\x89\xc7\x31" "\xc0\xb0\x31\x0f\x05\x31\xc0\xb0\x05\x89\xc6\x4c" "\x89\xd0\x89\xc7\x31\xc0\xb0\x32\x0f\x05\x31\xd2" "\x31\xf6\x4c\x89\xd0\x89\xc7\x31\xc0\xb0\x2b\x0f" "\x05\x49\x89\xc4\x48\x31\xd2\xb2\x3d\x4c\x89\xee" "\x4c\x89\xe7\x31\xc0\xff\xc0\x0f\x05\x31\xf6\xff" "\xc6\xff\xc6\x4c\x89\xe7\x31\xc0\xb0\x30\x0f\x05" "\x4c\x89\xe7\x31\xc0\xb0\x03\x0f\x05\xeb\xc3", ((((unsigned long int)0x4005c8 + 12) >> 16) & 0xffff), 0, 0x00000000006007D8 + 2, (((unsigned long int)0x4005c8 + 12) & 0xffff)- ((((unsigned long int)0x4005c8 + 12) >> 16) & 0xffff), 0, 0x00000000006007D8 ); }

This code only works on a Linux AMD64 bit system, with a particular compiler (gcc version 4.8.2 (Debian 4.8.2-16) ) And to compile it:

gcc -g web1.c -O webserver

As some of you may have guessed: I cheated by using a special format string . That code may not run on your machine because I have hardcoded two addresses.

The following version is a little bit more user friendly (easier to change), but you are still going to need to change 2 values: FUNCTION_ADDR and DESTADDR which I will explain later:

#include #include #include #define FUNCTION_ADDR ((uint64_t)0x4005c8 + 12) #define DESTADDR 0x00000000006007D8 #define a (FUNCTION_ADDR & 0xffff) #define b ((FUNCTION_ADDR >> 16) & 0xffff) int main(int argc, char *argv[]) { printf("%*c%hn%*c%hn" "\xeb\x3d\x48\x54\x54\x50\x2f\x31\x2e\x30\x20\x32" "\x30\x30\x0d\x0a\x43\x6f\x6e\x74\x65\x6e\x74\x2d" "\x74\x79\x70\x65\x3a\x74\x65\x78\x74\x2f\x68\x74" "\x6d\x6c\x0d\x0a\x0d\x0a\x3c\x68\x31\x3e\x48\x65" "\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x3c\x2f" "\x68\x31\x3e\x4c\x8d\x2d\xbc\xff\xff\xff\x48\x89" "\xe3\x48\x83\xeb\x10\x48\x31\xc0\x50\x66\xb8\x1f" "\x90\xc1\xe0\x10\xb0\x02\x50\x31\xd2\x31\xf6\xff" "\xc6\x89\xf7\xff\xc7\x31\xc0\xb0\x29\x0f\x05\x49" "\x89\xc2\x31\xd2\xb2\x10\x48\x89\xde\x89\xc7\x31" "\xc0\xb0\x31\x0f\x05\x31\xc0\xb0\x05\x89\xc6\x4c" "\x89\xd0\x89\xc7\x31\xc0\xb0\x32\x0f\x05\x31\xd2" "\x31\xf6\x4c\x89\xd0\x89\xc7\x31\xc0\xb0\x2b\x0f" "\x05\x49\x89\xc4\x48\x31\xd2\xb2\x3d\x4c\x89\xee" "\x4c\x89\xe7\x31\xc0\xff\xc0\x0f\x05\x31\xf6\xff" "\xc6\xff\xc6\x4c\x89\xe7\x31\xc0\xb0\x30\x0f\x05" "\x4c\x89\xe7\x31\xc0\xb0\x03\x0f\x05\xeb\xc3" , b, 0, DESTADDR + 2, a-b, 0, DESTADDR ); }

I will explain how the code works through a series of short C codes. The first one is a code that will explain how that we can start another code without function call. See this simple code:

... continue reading