Writing the shortest valid C quine
For a while, I have had a fascination with code poetry (also things like “perl golf”). Elegance is quite beautiful, really.
What is a quine?
In short, it is a program that prints its own source code, without having access to the source itself. This is a quine written in C, by an unknown programmer. Supposedly it was written in the margin of a book by Ray Toal, a professor from Loyola Marymount University, in the 80s.
Ray’s much more in-depth webpage on quines. Check it out, it’s great.
Note: Since writing the article I read that a computer scientist named Szymon Rusinkiewicz won the IOCCC contest for this same quine in 1994: smr.c.
If you compile the code, you will probably get a bunch of warnings, but as expected, when executed, it prints it’s own source. You can verify that it isn’t just reading the source code file by removing the .c file.
My foray into writing the shortest C quine
I have quite a bit of code, some of it works… most of it, sadly, does not.
So why not cut the code?
I wondered if
would compile an empty file! Could it be?1
gcc
So I went ahead and did
, then I ran 1
echo > qui.c
1
gcc qui.c -o quine
and… the compiler promptly projectile vomited all over my workstation. I get to look at what it says, and realize it’s not actually the C compiler, it is the linker
, trying to make a call to the function 1
ld
, while… we have none.1
main()
Let’s try this again, the short explanation is I’m going to tell the compiler to only generate an object, and not try to link it yet, then manually link the object to dead space in memory:
Note: This was originally written using
, however, morb reminded me that echo spits out a newline by default. Using 1
echo > qg.c
is shorter.1
touch
So actually, this program will print output to standard error, but it is actually the operating system throwing an exception after my code tries to call undefined memory, and segfaults, but it does, in fact, print nothing to standard out, as it should. You can see what makes up a completely bare-bones ELF like this, which is interesting:
Note: The linker will spit out
, which I think is a default entry point that the registers can point to, since I did not define it. I’ll have to keep this in mind for future exploit development that the linker will default to this entry address…1
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
We can now run our code. You’ll see the segfault, but if you want you can direct the stderr file descriptor to
, to see if it does, indeed, print its own source code.1
/dev/null
If you enjoy my work, sponsor or hire me! I work hard keeping oxasploits running!
Bitcoin Address:
bc1qclqhff9dlvmmuqgu4907gh6gxy8wy8yqk596yp
Thank you so much and happy hacking!