Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Exploring mullender.c – A deep dive into the first IOCCC winner (lainsystems.com)
150 points by todsacerdoti on Aug 30, 2020 | hide | past | favorite | 35 comments


Not so much "obfuscated C" as it is "embedding a binary into a C program". You can still do something similar with modern compilers:

    char code[] = { /* put your bytes here */ };
    ((void(*)())code)();
I believe it is technically UB, but it does exactly what you'd think it does, and if compilers started doing funny things with it, you wouldn't be able to write things like JITs at all. A tiny demonstration of this can be found at the bottom of C4x86: https://github.com/EarlGray/c4/blob/master/c4x86.c


> Not so much "obfuscated C" as it is "embedding a binary into a C program".

The meaning of "obfuscated C" as the contest requires was not well-defined at that time and had to be amended for a very long time. There are at least 5 more entries that abused and subsequently changed the rules at that time [1] [2] [3] [4] [5]. ([6] is an exception; this kind of abuse of the rules is allowed and now common.)

> [...] if compilers started doing funny things with it, you wouldn't be able to write things like JITs at all.

Well, see [7].

[1] https://www.ioccc.org/1987/biggar/hint.html

[2] https://www.ioccc.org/1988/spinellis.hint

[3] https://www.ioccc.org/1989/jar.1.hint

[4] https://www.ioccc.org/1993/lmfjyh.hint

[5] https://www.ioccc.org/1994/smr.hint

[6] https://www.ioccc.org/1995/spinellis.hint

[7] https://www.ioccc.org/2011/richards/hint.html


The IOCCC can use a UX improvement where they have, for each entry, pages with an introduction, the hints page, how the thing works, the actual code and what happens when you run it (including output).

As it stands, it's very interesting to read but most examples are hard to run and I always end up going away unfulfilled.


This is why I do these write ups, I want to document the most obtuse pieces of code I can and explain the logic in a clear way =) I'll be writing more so be on the look out!


Your writeup was extremely interesting and helpful, thank you!


I have been working to improve the usability for this years winning entries. For some entries it doesn't work well to "inline" the C code.


I think something like this gets disallowed these days as .rodata and .data gets mapped NX.


Using compiler hints, data can be placed directly in the code section.

Works on x86/x86_64 Linux:

char main[] __attribute__ ((section(".text"))) = "\xe8\x0d\0\0\0Hello world!\n"

#ifdef __x86_64__

"\x31\xc0\x8d\x50\x0d\xff\xc0\x89\xc7\x5e\x0f\x05\x31\xff\x8d\x47\x3c\x0f\x05";

#else

"\x31\xdb\x8d\x53\x0d\x59\x8d\x43\x04\x43\xcd\x80\x31\xdb\x8d\x43\x01\xcd\x80";

#endif


I wonder if there have been any entries that use return oriented programming? I wasn’t able to find one...



Calling that "technically UB" is putting it lightly.


What would be blessed way of doing it? Inline assembly jumping to it?


In other words, this type of behavior can be summarized as: Instead of waiting for other people to exploit your program in C, why not to execute some shellcode and pwn yourself while you're at it... /joke


The author says “I tried to define ‘main’ as an array of shorts with a modern compiler and it did not like that one bit”, but without saying which modern C compiler or what it didn’t like about it.

This sort of trick should still be possible with modern compilers. GCC has the charming warning

  warning: ‘main’ is usually a function [-Wmain]
if main is declared as something other than a function.

Here’s someone who got it to work in 2015, anyway: http://jroweboy.github.io/c/asm/2015/01/26/when-is-main-not-...


Author of the article here. This was simply meant to be a minor observation, the focus of the article is not an investigation about the various ways to define main in your program.

Anyway, this is the error I got if you're curious. (I left such things out because the article was getting long as is)

warning: variable named 'main' with external linkage has undefined behavior [-Wmain] short main[] = { 16, 18 };

This is on OS X so it's clang 11.0.3.


I’m sorry your comment has been downvoted. I can’t imagine why. Thanks for writing an interesting article.

I realise this was a minor observation on your part, and I was remarking on it in that spirit. I’m sorry not to have made that clearer. I’ve found it rather dispiriting when writing of mine has been posted here, and the comments have seemed like nitpicking criticism, so I regret having given you that impression. One has to remind oneself that people who enjoy the article and have nothing to add will usually not leave comments, and so the comments give a misleading impression of how people felt about it.

The message you quote above appears to be a warning, rather than an error.


No harm no fowl, I appreciate constructive criticism but sometimes I'm on edge posting in these forums. It's like, this content is being posted to some of the best in the field - I want to be as precise and accurate as I can be.

Anyway, I'm glad you found it interesting =)


> I tried to define ‘main’ as an array of shorts with a modern compiler and it did not like that one bit

He didn't even try to get it to work by changing that one bit!


It's fairly important reminder that pretty much every program we write has huge numbers of contextual and environmental assumptions built in - not just the obvious OS and envvars but things like the business model, the assumptions about how other parts of an organisation will react to certain outputs - it is often amazing to me that any piece of code can be understood by "outsiders" - we all are writing obfuscated code.


Having grown up coding assembly on the MC68000 (Europe, Amiga, demos ...) and spent years doing low-level embedded development on ARM Cortex cores it's really fascinating to see how similar they both are to the PDP.


IKR? I had an Atari ST which I coded in ASM and then I was in college and they had a PDP and the prof let me look at the ASM books and I was astounded!


I like Gavin Barraclough's entries, the first is

https://www.ioccc.org/years.html#2001_anonymous

Which I believe was a runner up, and was a PPC to x86 binary translator

and his winning entry:

https://www.ioccc.org/years.html#2004_gavin

Which was a protected mode multitasking operating system with a windowing system/gui.

because of course.


I will definitely be adding these to my list of potential article topics for the future. Thank you!


It still compiles (without warnings) and runs on modern VAX systems (NetBSD 9, gcc 7.4.0, VAXstation VLC):

  claire: {4} cc --version
  cc (nb3 20190319) 7.4.0
  Copyright (C) 2017 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  claire: {5} cc mullender.c -o mullender
  claire: {6} ./mullender
                                                                             :-)
  claire: {7} uname -p
  vax


Are you the VAX assembly expert I've been looking for? Can you explain some things (specifically the code after the PDP section)? If so e-mail me, I'd love to ask some questions. (The e-mail addr is easily found on my website)


Christopher Mills' winning entry for the 25th IOCCC (2018) is a PDP-11 emulator. Included with the BSD 2.9 image is the mullender.c entry -- you can compile and run it.

<https://ioccc.org/2018/mills/hint.html>


This is on my list to investigate!


Love the theme. It's quite similar to Cadey's blog. https://christine.website/ Dark themes are so nice when done well...


It’s Hugo’s terminal theme https://themes.gohugo.io/hugo-theme-terminal/


Beauty is in the eye of the beholder, and in my case, I find it very hard to look at any dark theme for more than a very brief amount of time. I'm wondering whether I've got some eye condition but I know from previous comments that there are at least a few other folks on HN who experience the same.


Sorry it was uncomfortable to read for you, I can look into implementing a button to switch between a light and dark theme.


Thanks for your consideration. I used to have a "readability" bookmarklet in my browser that was gold for cases like this. But at some point these stopped playing nicely with the various script/tracking blocker add-ons I have installed, so there's that.


Very deep. Should have ask for and a 8” Wang word processor Disk and where is my 5...

But the real surprise is the Docker image. Can we have pdp-11 and Ibm 360 one? Tired of firing the dos mode version.


This is like most of the program listing from home computer magazines in the 80s


Indeed the code is not very difficult (except for that f'ing VAX), it's the manner in which they accomplished it + the personal stories that I think really make this cool (I wrote it though so I'm a bit biased).

In the future I'm going to dissect more complicated obfuscated programs so I hope you'll get to enjoy those.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: