10 ms·
A C89 compiler that produces executables that are also valid ASCII text files [pdf]
- Y_Y 9y agoThis is the work of Tom7, well known for other projects like Learnfun & Playfun, ARST ARSW and running a marathon in hockey skates.
- learc83 9y agoThanks for pointing that out. I wouldn't have noticed who that was otherwise. His video on learnfun/playfun is both hilarious and amazing. https://www.youtube.com/watch?v=xOCurBYI_gY https://www.youtube.com/watch?v=xOCurBYI_gY
- hannob 9y agoThere was actually a tool "com2txt" back in the DOS days. So you could convert an executable and put it into an email.... Update: I have my data well sorted enough that I found it :-) It even comes with code and is under a vague free license: https://github.com/hannob/com2txt https://github.com/hannob/com2txt
- Cyph0n 9y agoThanks for sharing! Kind of uncanny to see a perfectly readable Makefile written around the year I was born...
- CobrastanJorji 9y agoMake's been around since the '70s. Bell Labs cranked it out right after inventing C.
- amq 9y agoWhy not just use base64 (from 1992)?
- jdmichal 9y agoIt didn't just create a text file. It created an executable text file. First two paragraphs of the README: Com2txt is a tool on MS-DOS which converts a com file to a text file. It's DOS generic. Unlike tools such as uuencode, the text file generated by com2txt works as a com file, exactly like the original com file does. Using com2txt, you can create a com file which can be sent through networks such as internet, and runs without any decoding. Moreover, the text file got by com2txt consists only of ECHOable characters; it doesn't contain characters such as `<' or `|'. So, using ECHO command, you can easily generate the textized com file and use it in a batch file. For detail see section 4.
- sixothree 9y agoI didn't gleam that from the original comment either. Crazy fun stuff though.
- bluefox 9y agoI also remember JauMing Tseng's XPACK...
- deleted 9y ago[deleted]
- ptspts 9y agoShameless plug: I also wrote a tool similar to com2txt in 1996: https://github.com/pts/pts-xcom https://github.com/pts/pts-xcom . A quick comparison: * com2txt.exe is 7110 bytes long, xcom.com is only 401 bytes long. * xcom.com can also convert back from text to binary. * xcom.com can also convert to data text (without the self-decoder header).
- skocznymroczny 9y agoCan it also stop an alien invasion?
- techolic 9y agoSend some aliens and test it out!
- Sniffnoy 9y agoDoes this output self-modifying code, or does it also try to avoid that like ABC does?
- softbuilder 9y agoBack in the BBS/FidoNet days someone sent me a comic GIF that, when renamed with a .COM extension, would execute under DOS. It was a nifty little demo, although .COM files were going the way of the dinosaur around then.
- NuSkooler 9y agoWish I could remember the trick, but in the DOS days I used to type in a few characters (5ish IIRC) at the start of text files that allowed them to be renamed and executed as COM files.
- prewett 9y agoIf you read the paper I think you'll find it is something like "ZM~~_#____PRinty__C", where _ is a space, (HTML compresses spaces). See section 8, also the beginning of the paper.
- softbuilder 9y agoNo, COM files had no header. [2] I think that's part of why they were replaced. ZM was for EXEs. I think that one was someone's initials. (Yes, looked it up. [1]) I think what parent is remembering were characters that effectively created a jump instruction at the beginning of the file. [1] https://en.wikipedia.org/wiki/DOS_MZ_executable https://en.wikipedia.org/wiki/DOS_MZ_executable edit: [2] Section 6 of the paper talks about that, just noticed.
- pjmlp 9y agoThey were replaced because they could not handle more than 64KB.
- TickleSteve 9y ago.COM files were straight binary, no header and loaded at address 256 (0x100) into any 64KB segment. All indirections were local to that segment, hence the 64KB limit of .com files. The characters you were typing are (probably) the code for a jump to an entry point somewhere else in the file.
- hprotagonist 9y agoThe good doctor murphy is a mad genius. I laughed very hard indeed when I first read this and got to the last 30 seconds of the video.
- raphlinus 9y agoThe phrase 'For example, on the popular and elegant X86 architecture, the single byte 0xF4 is the "HLT" instruction' slays me every time.
- schoen 9y ago"An elegant weapon... for an age more naive about ISA design"?
- metaobject 9y agoCan you explain this? Is it the "popular and elegant" part?
- raphlinus 9y agoAbsolutely. It's very subtle humor. Students of computer architecture consider x86 to be one of the least elegant architectures around. Its many warts include segment registers (originally a hacky workaround to stretch 64k of memory to 1M), and an extremely complex instruction encoding employing prefix bytes. Many of the legacy issues (such as not having enough registers) have been papered over, leaving traces behind. Many people felt that the complexity would doom the architecture, and that a cleaner, leaner RISC approach would win out. However, Intel has used their advantage in process technology to throw massive amounts of transistors to make up for the problems caused by all this complexity, and has done well. RISC has done well in the mobile space because those transistors tend to be power-hungry, but everywhere else x86 is today almost the only game in town. One reason it's especially funny is that "HLT" is one of those legacy instructions that has pretty much no use in a modern system, yet takes up a whole slot in the byte encoding, while common operations like MOV or ADD often require extra prefix bytes to specify the size of the operands. Hope that helps!
- kazinator 9y agoSegment registers did not evolve from the hacky address space expansion mechanisms. It may look that way looking at nothing but the Intel history, but the descriptor-style segment registers existed in mainframe architectures before the 8086/88 existed. The 8086 has trivial segment registers (which were just scaled offset addresses) which then morphed into mainframe-like descriptors of the successors (registers being indices into tables of segment descriptors). That could have been a plan all along, though. https://en.wikipedia.org/wiki/Memory_segmentation#History https://en.wikipedia.org/wiki/Memory_segmentation#History
- azendent 9y agoThere's a nice video that does a great job of walking through what is happening here: https://www.youtube.com/watch?v=LA_DrBwkiJA https://www.youtube.com/watch?v=LA_DrBwkiJA
- bringtheaction 9y agoThat is demoscene level awesomeness! Kudos to the author. Excellent video as well. And not least, lovely ending <3
- _RPM 9y agoAnyone have a copy of the program? I want to try and run it.
- modeless 9y agoOn a related note, how about C source code that you can chmod +x and execute directly, even with execve: https://gist.github.com/jdarpinian/84a28a1ed8a36313a4e0cad8b3cd347f https://gist.github.com/jdarpinian/84a28a1ed8a36313a4e0cad8b...
- khc 9y agoit's actually much easier than that: https://github.com/kahing/bin/blob/master/cleancache.c https://github.com/kahing/bin/blob/master/cleancache.c
- modeless 9y agoTrue, but there are a few gotchas with that version. It won't work with execve, it doesn't cache the binary, it won't work if called with "source", it doesn't set argv[0] properly when the binary is called, and a few other things. It is nice and terse though.
- khc 9y agoexecve and binary caching are relatively easy to implement, as is argv[0]. Do people actually care about making "source" work?
- modeless 9y agoexecve compatibility is not easy at all, since it requires a shebang line which isn't valid C. However thanks to emmelaich's // idea I just figured out a way to do it using fewer lines than your #if 0 solution. https://gist.github.com/jdarpinian/1952a58b823222627cc1a8b83a7aa4e2 https://gist.github.com/jdarpinian/1952a58b823222627cc1a8b83...
- MaxBarraclough 9y agoI can't decide if that's cute, or eye-bleedingly criminal. Neat though, and I haven't seen it before.
- merraksh 9y agoDo I see a Sierpinski triangle on page 9? It's the code that, according to the description, changes the value of the AL register.
- bonzini 9y agoNo, it is the _data_ that the compiler precomputes to help changing the value of the AL register. It is unused here, in fact it is cropped to 160 columns and it has a caption in the middle so it's wrong even. He included it just because it looks cool.
- pqwEfkvjs 9y agoSo how can I use this to hack FBI, CIA or FSB
- merraksh 9y agoThe histogram on the last page counts the occurrences of each character in the paper (all of them printable, of course). But because the histogram's counts are made of characters too, the author had to add a few extra numbers to make the histogram "converge". Brilliant.
- zippzom 9y agoI must be missing something, but I don't see how the actual text of the paper originates from the source code. Those C instructions actually compile into the sentences of the paper as well?
- moefh 9y agoFrom a quick look at the source[1], it seems the compiler will always generate an executable with the text from the paper (which is read from the "paper/" directory, and some bits hard-coded in the compiler source). Or something. I don't really know SML. From what I can tell, the .exe file generated by the compiler must be really big anyway (since the relevant sizes in the header can't be small because they have to be printable). So there must be some text, it might as well be the paper. [1] https://sourceforge.net/p/tom7misc/svn/HEAD/tree/trunk/abc/exe.sml#l278 https://sourceforge.net/p/tom7misc/svn/HEAD/tree/trunk/abc/e...
- zippzom 9y agoAh so all the x86 bytes that the actual text generates are basically just filler for the actually relevant sections of the paper (i.e. the jumble of bytes that appears)? They're never actually read or executed by the CPU?
- plogik 9y agoIf only i wasn't too lazy I'd buy a hat just to take it for the author.
- theknarf 9y agoMeta literate programs. Not only do you have the code and a descriptive document about the code in the same document, but you also have the executable!
- zmodem 9y agoThe paper/executable starts with "ZM", but shouldn't a DOS .exe file start with "MZ"? (http://www.delorie.com/djgpp/doc/exe/ http://www.delorie.com/djgpp/doc/exe/) What am I missing?
- ChrisLomont 9y agoMZ or ZM works [1] https://en.wikipedia.org/wiki/DOS_MZ_executable https://en.wikipedia.org/wiki/DOS_MZ_executable
- zmodem 9y agoTIL I wonder if there’s any interesting reason for that.