/pts-tinype

tiny hello-world Win32 PE .exe

Primary LanguageAssembly

pts-tinype: tiny hello-world Win32 PE .exe
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pts-tinype is a set of tiny hello-world Win32 PE .exe executables for the
console (Command Prompt), with assembly source code. The smallest one,
hh2.golden.exe is just 402 bytes large, and it runs on Windows XP ...
Windows 10.

How to run:

* Download and run hh2.golden.exe in the Command Prompt of any 32-bit (i386)
  or 64-bit (amd64, x86_64) Windows system or Wine. (It has been tested and
  it works on Windows XP, Windows 10 and Wine 1.6.2.)
* Alternatively, if you don't have a Windows system to try it on, run it
  with Wine.
* Alternatively, if you don't have a Windows system to try it on, run it on
  a virtual machine running Windows. Example Windows XP virtual machine with
  QEMU:
  http://ptspts.blogspot.com/2017/09/how-to-run-windows-xp-on-linux-using-qemu-and-kvm.html

Variants:

* hh1.golden.exe (663 bytes): Should work on Windows XP ... Windows 10.
* hh2.golden.exe (402 bytes): Should work on Windows XP ... Windows 10,
  contains some string constants overlapping header fields.
* hh3.golden.exe (2048 bytes): Should work on Windows XP ... Windows 10.
  Built with MinGW GCC from a .c source, doesn't contain assembly or
  linker tricks.
* hh4.golden.exe (268 bytes): Doesn't work on Windows XP, works on Windows
  7, should work on Windows Vista ... Windows 10,
  contains some string constants overlapping header fields. On 32-bit
  Windows 7 the first 256 bytes would have been enough.
* box1.golden.exe (268 bytes): Doesn't work on Windows XP, works on Windows
  7, should work on Windows Vista ... Windows 10,
  contains some string constants overlapping header fields. On 32-bit
  Windows 7 the first 261 bytes would have been enough.

How to compile:

* On a Unix system (e.g. Linux) with the `nasm' and `make' tools installed,
  just run `make' (without the quotes) in the directory containing hh2.nasm.
* Alternatively, on other systems, look at the beginning of the hh2.nasm and
  hh1.nasm source files for compilation instructions. On Windows, you may
  have to run `nasmw' instead of `nasm'.

Related projects and docs:

* https://www.codejuggle.dj/creating-the-smallest-possible-windows-executable-using-assembly-language/
  is a related project from 2015, and its tiny .exe is even smaller: 268
  bytes. Unfortunately it doesn't run on Windows XP (``The application
  failed to initialize properly (0xc0000007b). Click on OK to terminate the
  application.''. It works on Wine 1.6.2, Windows 7 32-bit,
  and its author claims that it runs on Windows 7 64-bit. See
  box1.nasm and box1.golden.exe for a copy of the code.
* The 268-byte PE .exe header pattern:
  http://pferrie.host22.com/misc/tiny/pehdr.htm
* 268-byte amd64 tiny PE .exe where every byte is executed:
  https://drakopensulo.wordpress.com/2017/08/06/smallest-pe-executable-x64-with-every-byte-executed/
* A longer, useful writeup on tiny PE .exe:
  http://www.phreedom.org/research/tinype/tiny.import.209/tiny.asm
  The subpage
  http://www.phreedom.org/research/tinype/tiny.import.209/tiny.asm
  contains 209-byte tiny.exe with an import. Windows XP SP3 says:
  ``Program too big to fit in memory''.
* Crinkler-related discussion of tiny PE .exe and the 268-byte minimum:
  http://www.pouet.net/topic.php?which=9565
* Crinkler (http://www.crinkler.net/), a combined linker and compressor to
  generate tiny Win32 PE .exe files. An .exe files generated by Crinkler 2.0
  (aw50cm8_by_knl__ishy.exe)
  didn't work for the author of hh2.nasm on Windows XP SP3 (even though
  the documentation of Crinkler explicitly says that Windows XP is
  supported). Crinkler 2.0 itself didn't work for the author of hh2.nasm on
  Windows XP SP3 (``The application failed to initialize properly
  (0xc0000022). Click OK to terminate the application.''.) Crinkler 2.0
  started up on Wine 1.6.2, but it failed to create an .exe file
  (``Oops! Crinkler has crashed.'', probably because the dbghelp.dll in Wine
  doesn't work.)
* https://code.google.com/archive/p/corkami/wikis/PE.wiki
  contains older documentation about PE.
* https://stackoverflow.com/questions/33247785/compile-windows-executables-with-nasm
  asks how to create Win32 PE .exe files with nasm.
* https://stackoverflow.com/questions/42022132/how-to-create-tiny-pe-win32-executables-using-mingw
  contains a C hello-world Win32 PE .exe, 2048 bytes.

Windows XP .exe loader limitations:

* SizeOfOptionalHeader must be >= 0x78.
* NumberOfSections must be >= 3.
  2 or 1 don't work, 4 works.
* SectionAlignment must be 0x1000.
  Even 0x2000 doesn't work.
* FileAlignment must be >= 0x200.
  0x400 also works.
* A section cannot be loaded to ImageBase, minimum is ImageBase + 0x1000.
* SizeOfHeaders must be > 0.
* PointerToRawData is 0, then Windows XP doesn't load the section.
* Maybe the limitations above don't apply if we don't need any external
  libraries (not even kernel32.dll). This needs further investigation.

How was hh2.nasm created?

* The .nasm source in
  https://www.codejuggle.dj/creating-the-smallest-possible-windows-executable-using-assembly-language/
  was studied.
* The .exe created from the hello-world .c program in
  https://stackoverflow.com/questions/42022132/how-to-create-tiny-pe-win32-executables-using-mingw
  was manually converted back to .nasm, pointers changed to symbols and
  address computations added one-by-one.
* The 2nd .nasm file was gradually changed to resemble the 1st .nasm file,
  while making sure that the generated .exe still works on Windows XP.

__END__