The other day on pouët, the question came up when people started naming Amiga executable files with an “.exe” suffix, which isn’t really necessary under AmigaOS. Interesting question! I started scanning the disk images I collected for the Amiga Pointer Archive. At least in the TOSEC disk images, .exe files occur as early as 1987, and maybe earlier overall.
While the file names scrolled by, I noticed something funny: Endless
directory structures that seemed to repeat themselves. Take “3-Demon” from 1988,
contained in 3-Demon v1.0 (1988)(Mimetics)[h TBS].adf –
an early 3D editor, apparently:
This specific disk was spread by The Bitstoppers — they put a README file in front of it, added a little intro…
…and also left their name on the disk as a directory name. When you list the disk contents with AmigaDOS, you get:
1> dir df1:
c (dir)
objects (dir)
devs (dir)
s (dir)
fonts (dir)
libs (dir)
** THE BITSTOPPERS ** (dir)
»> BST <« !ReadMe!
.info 3-Demon
3-Demon.info BST
Disk.info Example 1.3demon
However, when you try to list all files recursively with dir df1: all, the system crashes:
Neat! Keep those lamers from listing your directories, hehe!
But is this a clever file system trick, maybe with a directory containing itself, causing the dir command to
exhaust all memory or overflow internal buffers? Kind of like a ZIP bomb –
an Amiga directory bomb?
At least for this disk, it’s not. If we analyze the ADF image in a file system analyzer like vAmigaDOS, we can follow the directory tree. Amiga OFS file contents are split up in 512-byte blocks, with references to their neighbors, parents, and children. Starting from the root block at 880, we get:
[880] 3-Demon: /> block 880
Block : 880
Type : ROOT
Header Key : 0
Checksum : 0x19ca146d
Name : 3-Demon
Created : 18-Mar-88 11:53:49
Modified : 18-Mar-88 11:53:49
Bitmap blocks : 1012
Bitmap extension block : 0
Hash table : 7 -> 883 (.info)
8 -> 925 (c)
10 -> 887 (3-Demon)
13 -> 886 (Example 1.3demon)
17 -> 894 (objects)
22 -> 926 (devs)
24 -> 899 (s)
28 -> 960 (!ReadMe!)
39 -> 924 (fonts)
40 -> 952 ( »> BST <« )
44 -> 932 (BST)
46 -> 954 (libs)
47 -> 958 ( ** THE BITSTOPPERS ** )
54 -> 882 (Disk.info)
[880] 3-Demon: /> block 958
Block : 958
Type : USERDIR
Header Key : 958
Checksum : 0xe48554e4
Name : ** THE BITSTOPPERS **
Comment :
Created : 16-Feb-87 18:45:36
Parent : 880
Next : 0
Hash table : 47 -> 961 ( ** THE BITSTOPPERS ** )
[880] 3-Demon: /> block 961
Block : 961
Type : USERDIR
Header Key : 961
Checksum : 0xe4855475
Name : ** THE BITSTOPPERS **
Comment :
Created : 16-Feb-87 18:45:37
Parent : 958
Next : 0
Hash table : 47 -> 962 ( ** THE BITSTOPPERS ** )
[...many more blocks omitted...]
[880] 3-Demon: /> block 1009
Block : 1009
Type : USERDIR
Header Key : 1009
Checksum : 0xe48555e3
Name : ** THE BITSTOPPERS **
Comment :
Created : 16-Feb-87 18:45:47
Parent : 1008
Next : 0
Hash table :
So it’s turtles directories all the way down – just more
than dir can handle. Listing all the directories in vAmigaDOS
doesn’t crash your browser or gives the “unresponsive JavaScript” warning, it just outputs a very long list:
Still, the question remains: Is it possible to create an evil directory structure? One that contains itself, or maybe a parent and a child that point to each other?
Surprisingly, yes! We can get dir to crash without wasting 512 bytes for each dummy directory, saving
precious disk space! It just
takes some adjustments in a hex editor…
- create a blank ADF disk image
- makedir evil
- makedir evil/evil
block 880 (0x370) = root block
block 881 (0x371) = disk bitmap
block 882 (0x372) = directory "evil" (path: "evil")
block 883 (0x373) = sub-directory "evil" (path: "evil/evil")
- find to the top-level "evil" disk block
882 * 512 bytes = offset 451584 = 0x6e400
0006e400: 0000 0002 0000 0372 0000 0000 0000 0000 .......r........
0006e410: 0000 0000 8f9a 2d16 0000 0000 0000 0000 ......-.........
checksum: need to adjust that by 1
0006e420: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e430: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e440: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e450: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e460: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e470: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e480: 0000 0000 0000 0000 0000 0373 0000 0000 ...........r....
hashtable with child reference
to "evil" sub-directory; let it
point to ourselves = 0372
0006e490: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e4a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e4b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e4c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e4d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e4e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e4f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e500: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e510: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e520: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e530: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e540: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e550: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e560: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e570: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e580: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e590: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e5a0: 0000 0000 0000 44b1 0000 0575 0000 0802 ......D....u....
0006e5b0: 0465 7669 6c00 0000 0000 0000 0000 0000 .evil...........
0006e5c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e5d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e5e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0006e5f0: 0000 0000 0000 0370 0000 0000 0000 0002 .......p........
0006e600: 0000 0002 0000 0373 0000 0000 0000 0000 .......s........
…and voilà!
Here’s the resulting disk. Let’s see what other utilities we can crash with it…
I had a hunch that vAmigaDOS would be cleverer than that, and I was right. It notices something is fishy right away. Boooring! :)
