A smaller world

Mach-0 Memory layout schema

In a previous post, I blogged about Mach-0 binaries, in particular the size of a simple Hello World program. Twelve kilobytes of binary code just to display Hello World, that is a lot. So I wrote a program that parses Mach-0 binaries, displays their content, and tries to compact the file. Compaction is done by shuffling around the different segments in the file, adjusting the offsets of the sections of the segments (see Figure). Using this technique, I brought the Hello World program to 4K. This is quite hacky, because it basically means the same page on file gets mapped into three different memory locations.

The reason I can’t go below with the current technique is that the linker puts the binary code at the end of the first segment between 0f6c and 0fff in memory and in the file (the binary of hello world I’m using does not have a page-zero segment). Even if I rewrite the code section’s offset in the file, the loader basically maps the file into memory, so what ends up in the memory range is 0f6c–0fff is whatever is in the file in that range, and if the file is shorter, this area is filled with zeroes. I could change the entry point address of the program (this is defined in register eip), the problem is that the start function that gets linked in code contains absolute adresses.

So this means that to make the program smaller, I need to change the structure of the code (or rewrite addresses, but this is really annoying) probably by getting rid of the start function. More fun to look forward to.
If you are interested, you can download the archive of the tool along with the code to build the hello-world, this is of course worse than experimental code and should not be used in any way! You can also download the resulting Intel binary.

5 thoughts on “A smaller world”

  1. Je viens d’essayer pour les ELF 32-bit, j’obtiens 6Ko.

  2. Chapeau le magicien !

    1) On parle bien de récupérer quelques kilooctets, même pour de gros exécutables (centaines ou milliers de ko) ?

    2) Y aurait-il un intérêt, même insignifiant, pour de petits exécutables appelés souvent, comme cp, cat, echo ? Quelques fragments de mémoire libérés dans le cache disque ?

  3. 1) À vrai dire, non, la raison pour laquelle ce truc est possible est que l’exécutable est rempli de zéros. Si tu prends le binaire de 4K, tu verra qu’il est rempli de ‘X’, mon programme met la mémoire non utilisé à 58 histoire de voire ce qui est réellement nécessaire.
    2) Je ne pense pas réellement, même si le binaire représente 4K sur le disque, il y a trois pages mappées en mémoire, dont deux qui sont le cas échéant sont swappées sur le disque.

Leave a Reply to Krysztof von MurphyCancel reply

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