Bespoke, Artisanal, Hand Made Executables

Programmers and software engineers will always use the latest development environments, the trendiest frameworks, and languages they learned only 21 days ago. What if this weren’t the case? What if developers put care into their craft and wrote programs with an old world charm? What if Windows executables were made with the same patience as artisanal firewood, or free range granola? [Steve] has done it. He’s forging a path into the wilds of truly hand crafted executables.

The simplest executable you could run on a Windows box is just a simple .COM file. This is an extremely simple file format that just contains code and data loaded into 0100h, and a jump to another point in the code. The DOS .EXE file format is slightly more complicated, but not by much. [Steve]’s goal was to build a proper Windows executable without a compiler, assembler, linker, or anything else.

The process of pruning an executable down to its bare minimum began, of course, by creating a program. The test program in this case just returns a number. This program was created with the BuildExe() function that first creates a valid Windows PE header. After this comes an ‘optional’ header with values for each section of the executable, the entry point address, and the offset to the first section’s data. Following the optional header is a section of data directories, and several bytes of book keeping. Finally there are four bytes of [Steve]’s code. The total size for the original executable? 516 bytes.

After a few optimizations to the BuildExe() function, [Steve] managed to get the size of his executable down to 300 bytes, but found anything smaller than 328 bytes wouldn’t work; the OS assumes a minimum size for the optional header and data directories. After stuffing 28 bytes of padding on the end, [Steve] had an executable 328 bytes long.

There was another technique [Steve] could try – overlapping the PE header and part of the optional header with the first DOS header. It turns out the only important part of the DOS header is the first two bytes – ‘MZ’, the magic number and initials for one of the original DOS developers. By keeping that ‘MZ’ and putting other needed data in place of the otherwise empty DOS header, [Steve] managed to get his executable down to 268 bytes. That’s the absolute minimum size for a working executable under Windows 7 64-bit edition. Windows is smart enough to prevent four byte long .COM files from running now, so unless you want to go back to terrible versions of Windows, this is probably the smallest executable Windows will run today.

69 thoughts on “Bespoke, Artisanal, Hand Made Executables

      1. bahahaha! beautiful [RÖB]. [Brian Benchoff] has some awesome moments, but I guess he doesn’t like Ben from Voyage of the Mimi.

        [Bob] can you be so kind as to let us know when you got the libraries built.

        Honestly XKCD has gotten to far into his own head for semblance of reciprocation. (Then again from the timeline life experience based PTSD wouldn’t be so uncommon for him.)

  1. I’d hope that software engineers stick with tried and tested productive tools. “Programmers” and “skript kiddi3z” I can well believe jump on every single bandwagon they see go past.

      1. I’m still writing production VB6 code. Why? It works better and on more platforms than .NET, including under emulation with Wine, and I have a huge library of debugged bespoke industry-specific code that would need to be rewritten.

        1. “I’m still writing production VB6 code. Why? It works better and on more platforms than .NET”

          I think I just vomited in my mouth after reading that.

          Much rather spoon out my eyeballs than have to look at, let alone write, VB6 code on a daily basis.

          1. Although its not in a production environment, I am still compiling batch files into executables in win10! I use them all the time as reminders, to log food and meds intake, to schedule appointments, to reorder prescriptions, backup utilities (yes including across networks) etc…

          1. Why on earth do you assume he’s trolling?
            I was also writing VB6 code up until very recently when our IT department updated all our desktops to Windows 7. So much simpler than .NET, and yes, it works better.

          2. Mark: I wasn’t; it was just a joke.

            I’ve been doing C#/.NET for the last 10 years or so (C++ before that) but only have dabbled with VB6 here and there in the distant past and hated it. I can understand that you’re more familiar with VB6 but that doesn’t make it simpler and it sure as hell doesn’t work better.

    1. This isn’t the sort of thing anyone could do, requires fairly advanced knowledge of the file format, and of course requires you to hand-assemble code into hex. People did that all the time, in the 1980s. But it’s hardly a fad, or idiot work. It’s hand-made, organically-assembled machine-code.

      1. And that is the attitude responsible for my 2GHz 2GB RAM laptop to freeze for a minute or two when I load some fancy e-shop webpage on Firefox, launch Skype or some java based application like MPLABX. Sure, why bother making it efficient, everyone has quadcores and 16GB RAM and SSD’s these days…

  2. We used to use DOS Debug for this (q to exit). I just tried it on Win XP and it’s still there. There was a time when you just didn’t make the grade of ‘hacker’ if you couldn’t use debug to directy enter code into a .com and execute it.

    1. I remember programs being distributed this way, over usenet and such, since you couldn’t count on a user PC having any compilers, assembler, or binary download tools, other than DEBUG that came with DOS…

  3. This article will show you how to hand code ‘executable’ files (*.COM files) at the DOS prompt WITHOUT ANY OTHER 3rd party programming environments, debug tools or hex utilities. All that is required is a PC with MSDOS prompt, ECHO command and a standard 104 keyboard (with keypad). This technique will allow you could create very small programs e.g Viruses, Copy/Dir utilities just by typing in the correct opcodes and values in a programatic way with the keyboard.

    They can also be built and executed directly from batch and script files!

  4. For those of you who haven’t had the pleasure of hearing about the ‘demoscene’, the idea is to cram as much music as special effects as you can in the smallest filesize possible. There are some entries in the 32 byte and even 16 byte competitions!

    Lately, they have been pulling off some /fantastic/ effects in 4K (4096 bytes) – Case in point:

      1. This is really impressive, especially considering the size, everything must be hand made (no fancy libraries) and optimized, probably even in ASM. Are there any good websites or books that explain how to make such graphics “by hand” without any render-engine or stuff like that?

        1. It depends of platform and target size. On new systems like linux or windows you have to deal with PE/ELF headers and use a compressor to get high code density (eg. Windows – old style cab dropping, or newer (~350 bytes for simple MessageBox) , Linux – bash dropping). If you have good knowledge about code optimizing you wouldn’t have to write any line of ASM.
          Most of 1k-96k intros are mainly based on HLSL/GLSL as it looks like to have the best code density.

          With basic DX9 project (rotating 3d cube + light and no crashing or any other weird behaviour) I can get around 1k binary.

        2. “everything must be hand made (no fancy libraries) ”

          That’s often false nowadays. You can use gigabytes of graphics libraries, because using modern hardware is frankly impossible without.

          And yes – it defeats the whole point.

    1. The demoscene is amazing, but depending on the platform many of the demos still require the help of an operating system and use some nice API calls.

      These ‘demos’ don’t have lovely graphics (or any at all) like most of the demoscene, but with only 512 bytes and BIOS calls to work with I think they’re quite impressive:

      BTW if anyone is interested in operating system development, their wiki is the place to start:

    1. The original WordStar word processing program was written in Z-80 machine code by one man, in a month. Would be nice if more people doing commercial software had that kind of skill.

    1. Don’t forget free ranged… My God, won’t someone please consider the little bits! It is so inhumane to stuff them into those tiny little buffers until they’re executed.

      1. Traditional computing is mean and oppressive as binary digits *have* to be a one or a zero. In *free range* quantum computing they can be both a one and a zero at the same time. Traditional programmers should be fined and banned.

  5. This reminds me of playing around with hex editors back in the early 90’s. I used to modify the Command.Com file in DOS 6.22 to say all kinds of wacky things. I once scared the daylights out of a friend when I made it look like one of the more innocuous commands would actually reformat the hard drive…

    1. In MS-DOS 2.2 it was pretty easy to re-execute the command line on a programs exit. You could usually also get away with putting a counter after the null in the buffer so the program would re-launch 2 or 3 times.

    2. Hacking the DIR command to DIE and other fun things in MS-DOS was some fun. Anyone else have the fun of using DEBUG to access the BIOS of an MFM hard drive controller to manually enter all the bad sectors before having it do a low level format?
      >DEBUG g=c800:5.
      How about using EDLIN to write AUTOEXEC.BAT and CONFIG.SYS? Miss one character and you had to start over.
      My first hard drive was a 5.25″ full height Tandon, five megabytes with a stepper motor driven head. Had to find a PARK program to make it move the heads to the park position before it would work the first time.

      1. lol, I remember some of that. The c800:5 was the LL format vector?

        I remember the early 10MB HDD’s and then the 20MB that ran MFM but you could re-format them to 30MB with a RLL card.

        It’s amazing how much digital information was transferred before BBS and the net.

        One of my bosses always had new movie clips that played on a CGA card (pre-VGA). You can probably guess what sort of clips. Today they would be called NSFW.

  6. When I read artisanal firewood I was like WTF thats a thing now? and googled it, came back to the article and saw free range granola and was like Ohhh its a joke. Went to close the google tab and FML this shit sells for $100, you are LITERALLY BURNING MONEY… This is why the average American/Canadian has less than $1k in life savings.

  7. reminds me of the first time i made an assembler program (x86) it was i think only a couple bytes. screenx(BIOS), clearscreen(BIOS), color(BIOS), and finally print(BIOS)

    went on to display BIOS graphics but was bummed out by the slowness of it.
    BIOS graphics are way slower then can be made on such a fast (386) system.
    i guess thats why most BIOS graphics boot-up logo’s have a slight delay before you see em,,, they are hiding it until it’s completely drawn.

  8. I used to write code in Assembly for Windows… when it was 32 bit. Nothing you would want to use, but it got it’s job done. It’s actually quite easy once you get used to it. Most of the code ends up being calls to the OS. And a good programer (like Hutch) can write a reasonable editor in 6K or a really complete editor with nice features in 35K. Which will load as fast as you can click the icon. Or a web server in 8K.

  9. I just had to fire debug to write this. Debug.exe is not found on Win 7 64 bit though.

    13BD:0100 call 103
    13BD:0103 pop bp
    13BD:0104 sub bp,103
    13BD:0108 lea dx,[bp+8888]
    13BD:010C mov ah,9
    13BD:010E int 21
    13BD:0110 mov ax,4c00
    13BD:0113 int 21
    13BD:0115 db ‘Hello World$’
    13BD:0108 lea dx,[bp+115]
    CX 0000
    Writing 00021 bytes
    Hello World

    A fully relocatable Hello World. An AV with heuristics from back in the day used to complain about this technique though.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.