Susam Pal's Self-Printing Machine Code (on mastussy) demonstrates a 12-byte dos program copying its image to the standard output. This platform lends itself well to the problem, since executables are allowed to be bare code and copied to a fixed offset, naturally advantaging it over real systems like unix. Nevertheless, the unix a.out header is only 32 bytes and the entire image is similarly mapped at a well-known location; too bad Linux doesn't support a.out.
But
Debian GNU/Linux 0.93 will be the last release that uses the a.out binary format.
,
and 0.93R6 is, obviously, readily available to install.
A musty 1995 vintage, for which you
definitely want to consult the installation guide,
but 1995 debian-installer is irrevocably and unfalteringly debian-installer.
There are, of course, some fundamental issues with running a 30-year-old system:
at least four megabytes), but not too much; the qemu default of 128M is too much
a new disk partition of at least 40 megabytes, 128M works
overall qemu-system-i386 -m 32m -fda boot.bin -hda rootfs -boot a -fdb debs.tar
works,
and the most annoying limitation is that the floppy will be truncated at 2.8M, so you can't tar up every deb at once;
not that it really matters because strace/gdb/binutils/gcc are the only relevant ones not on the installation floppies.
This draws heavily from the aforelinked BGGP4 submission, where I had been robbed of my winning submissions for both the binary and shell program categories. Nevertheless, this allows for more interesting packing; given the annotated program:
cut -sf2 < prog | tr a-f A-F | tr -d '[:space:]' | base16 -d
)
0 cc 00 64 00 ; a_midmag
4 0C 00 00 00 ; a_text
8 00 00 00 00 ; a_data
12 b0 04 ; a_bss eax=4 mov al,0x4 number=__NR_write
14 EB 10 ; jmp +16
18 00 00 00 00 ; a_syms
22 0C 10 00 00 ; a_entry
26 00 00 00 00 ; a_trsize
30 00 00 00 00 ; a_drsize
32 31 db ; ebx=0 xor ebx,ebx fd =0
34 31 c9 ; xor ecx,ecx
36 b5 10 ; ecx=0x1000 mov ch,0x10 buf =loadaddr
38 31 d2 ; xor edx,edx
40 b2 2C ; edx=44 mov dl,44 count =progsize
42 cd 80 ; syscall() int 0x80
44
note that a_midmag (the magic), a_text (the size of the program text immediately following the header; Linux has started requiring this (and, thus, the file size) to be page-aligned by 2.6), and a_data (the size of program data, following the text) are fixed parameters while a_trsize and a_drsize must be 0; a_bss can be anything, since it describes the initial allocation to map after the program data, while a_syms can, empirically, sometimes have a non-zero low byte.
While COMs are loaded at 0x100 and a.outs are loaded at 0x1000,
the start address for COMs is also 0x100, while for a.outs it's a_entry
.
"Real" a.outs in the distribution include the libc runtime entry point at start of the program text,
and thus a_entry
is unwaveringly 0x1020 (0x1000 + the 32 header bytes);
except in this case it's a_bss
, into which the first instruxion is packed.
While Susam's program amounts to, effectively, a "write a buffer, then return" implementation (down to exiting with ret
) in 12 bytes,
this is an exercise in zeroing registers, since it amounts to
write(0, 0x1000, 44);
in 44 bytes – conveniently an even 32 more, matching the header size. The astute reader will've noted that it actually executes 16 bytes to do so, but if all registers were clear on entry this would've been just 10.
There is no explicit exit,
since the 270M of zeroes (allocated by a_bss
=0x10eb04b0
)
decode to add byte [eax], al which instantly segfaults,
and, if you don't disable coredumps, fills your disk.
Debian GNU/Linux 0.93R6 Copyright (C) 1993, 1994, 1995 Debian Association, Inc. and others 0.93R6 login: nab Password: Last login: Sat Mar 16 21:15:48 on tty1 Linux 0.93R6 1.2.13 #2 Wed Oct 4 17:35:14 EST 1995 i686 Copyright (C) 1993, 1994, 1995 Debian Association, Inc. and others Everything included with the Debian GNU/Linux system is freely redistributable; the exact distribution terms for each program are described in the individual files in /usr/doc/copyright/. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. $ ulimit -c 0 $ ./newd3 �d �� 1�1ɵ1Ҳ,̀Segmentation fault $ ./newd3 0>&1 | od -tx1 -Ad 0000000 cc 00 64 00 0c 00 00 00 00 00 00 00 b0 04 eb 10 0000016 00 00 00 00 0c 10 00 00 00 00 00 00 00 00 00 00 0000032 31 db 31 c9 b5 10 31 d2 b2 2c cd 80 0000044 Segmentation fault $ < newd3 od -tx1 -Ad 0000000 cc 00 64 00 0c 00 00 00 00 00 00 00 b0 04 eb 10 0000016 00 00 00 00 0c 10 00 00 00 00 00 00 00 00 00 00 0000032 31 db 31 c9 b5 10 31 d2 b2 2c cd 80 0000044
Nit-pick? Correction? Improvement? Annoying? Cute? Anything?
Mail,
post, or open!