Live data from Hacker News

HelloAssembly: The smallest possible complete Windows application (2021)

github.com

41–50 of 53 posts

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#41
post #36

"smallest possible" is exactly one instruction; possibly 0xc3 [ret] or 0x90 [nop]; the problem lies in how you define "complete Windows application", because the answer really differs depending on if you want to make it ABI compliant. But there's nothing preventing you from creating a custom loader/executor that reads a pure binary file, maps it as exec and runs it.

A .COM file is exactly that, a pure binary that just starts executing at the first byte. Mind you the loader for those has gotten a smidge bigger since its first version.

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#42
You can get a sub 20kb executable with C in MSVC and no weird tricks, i.e. just setting a particular combination of compiler/linker flags, like /NODEFAULTIB, /MERGE, /FILEALIGN:512 etc. Small enough that it's basically nothing, downloads in a couple of seconds over 56k dialup, and you get to use normal tooling. This is the compromise that makes the most sense to me, for products you're actually shipping. If you want to try out the nocrt approach, honestly the LLMs do a fine job of writing you some replacements for the parts of the crt that you likely want i.e. memcpy/memcmp/strlen helpers, with x64/arm64 SIMD and all.

Set /HEAP:4096,4096 and /STACK:65536,4096, write yourself a simple 100 line growable arena implementation, use that, avoid the heap entirely. Very quick and easy way to get a real windows program up and running that uses about 500kb of commit at baseline.

You end up with only ntdll.dll, kernelbase.dll, and kernel32.dll loaded. Trying to eliminate any of these becomes pretty painful and you venture into the territory of weird tricks that are expensive to maintain.

Dave's approach is a fun exercise though.

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#43
post #39

Earlier quoted context omitted.

no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet but also why would you, not much point except for very niche functionality

> no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet I mean officially. Yes, you can find some on the internet, but nothing on the official MSDN. > but also why would you, not much point except for very niche functionality Exactly. Using system DLL API is backward and forward compatible, and just as standardized and well-documented as the POSIX…

>> no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet

> I mean officially. Yes, you can find some on the internet, but nothing on the official MSDN.

It seems that changed. https://learn.microsoft.com/en-us/windows/win32/devnotes/ntq... says

  [This function may be changed or removed from Windows without further notice.]
but it on the official MSDN site, and it does document a call in Ntdll.dll.

It’s easy to find many more examples such as https://learn.microsoft.com/en-us/windows/win32/api/winternl..., so I don’t think that’s an accident.

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#44
post #43
post #39

Earlier quoted context omitted.

> no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet I mean officially. Yes, you can find some on the internet, but nothing on the official MSDN. > but also why would you, not much point except for very niche functionality Exactly. Using system DLL API is backward and forward compatible, and just as standardized and well-documented as the POSIX…

>> no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet > I mean officially. Yes, you can find some on the internet, but nothing on the official MSDN. It seems that changed. https://learn.microsoft.com/en-us/windows/win32/devnotes/ntq... says [This function may be changed or removed from Windows without further notice.] but it on the official MSD…

In addition a bunch are documented in the driver docs, such as https://learn.microsoft.com/en-us/windows-hardware/drivers/d....

> If the call to this function occurs in user mode, you should use the name "NtMapViewOfSection" instead of "ZwMapViewOfSection".

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#45
post #34

The smallest meaningful program for MS-DOS was exactly 2 bytes: FA F4 That's CLI HLT, which effectively deadlocked the machine. Had to be saved as a .com fule obviously, not as an .exe.

Somewhat more meaningful was "INT 19h" (CD 19), which also took 2 bytes and started the boot loader, bypassing the slow boot sequence of most systems.

And wouldn't a single instruction such as NOP or HLT be simply 1 byte?

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#46
I made my own 64-byte MS-DOS stub that uses a shorter message "Win32 Only!" instead of the usual "This program can only be run in DOS mode" message. By using the shorter stub, using the secret flag to omit the Rich header, and possibly merging sections together, I can usually get the PE header to fit within 512 bytes, and the linker won't pad out the PE header to 1024 bytes.

A copy can be found at https://github.com/Dwedit/NoCopilotKey/blob/main/stub.bin

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#47

You can get a sub 20kb executable with C in MSVC and no weird tricks, i.e. just setting a particular combination of compiler/linker flags, like /NODEFAULTIB, /MERGE, /FILEALIGN:512 etc. Small enough that it's basically nothing, downloads in a couple of seconds over 56k dialup, and you get to use normal tooling. This is the compromise that makes the most sense to me, for products you're actually shipping. If you want…

Then you load User32.dll, and you get 2MB of commit and 1MB of private bytes. Throw in a Message Box, and it's 272KB more private bytes and 388K more commit.

Windows 10 makes it literally impossible to write something that uses low memory and uses an actual window.

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#48
post #45
post #34

The smallest meaningful program for MS-DOS was exactly 2 bytes: FA F4 That's CLI HLT, which effectively deadlocked the machine. Had to be saved as a .com fule obviously, not as an .exe.

Somewhat more meaningful was "INT 19h" (CD 19), which also took 2 bytes and started the boot loader, bypassing the slow boot sequence of most systems. And wouldn't a single instruction such as NOP or HLT be simply 1 byte?

>> The smallest meaningful program for MS-DOS was exactly 2 bytes ...

> Somewhat more meaningful was "INT 19h" (CD 19) ...

I seem to remember the smallest MS-DOS program to be CD 20h saved as a `.com`.

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#49
post #45
post #34

The smallest meaningful program for MS-DOS was exactly 2 bytes: FA F4 That's CLI HLT, which effectively deadlocked the machine. Had to be saved as a .com fule obviously, not as an .exe.

Somewhat more meaningful was "INT 19h" (CD 19), which also took 2 bytes and started the boot loader, bypassing the slow boot sequence of most systems. And wouldn't a single instruction such as NOP or HLT be simply 1 byte?

Yeah, but the first one does nothing at all and the second does nothing for a bit :)

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#50
post #43
post #39

Earlier quoted context omitted.

> no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet I mean officially. Yes, you can find some on the internet, but nothing on the official MSDN. > but also why would you, not much point except for very niche functionality Exactly. Using system DLL API is backward and forward compatible, and just as standardized and well-documented as the POSIX…

>> no, you can also call ntdll (or even syscalls although those aren't stable), there's plenty of documentation on the internet > I mean officially. Yes, you can find some on the internet, but nothing on the official MSDN. It seems that changed. https://learn.microsoft.com/en-us/windows/win32/devnotes/ntq... says [This function may be changed or removed from Windows without further notice.] but it on the official MSD…

> but it on the official MSDN site, and it does document a call in Ntdll.dll.

Does it? What's FILE_BASIC_INFORMATION? Link gives me 404. How do you replace kernel32 API with this?

> It’s easy to find many more examples such as https://learn.microsoft.com/en-us/windows/win32/api/winternl..., so I don’t think that’s an accident.

Again, how do you replace kernel32 API with this?

> In addition a bunch are documented in the driver docs, such as https://learn.microsoft.com/en-us/windows-hardware/drivers/d....

This has nothing to do with ntdll at all.

I still don't get it, what's wrong with using the user32 and kernel32 APIs? It's stable, well-documented, and is the official API on Windows. So why not use it?

Post reply on HN