0

The smallest program I could think to make is one that loops indefinitely. In fasm it looks like this:

format PE console
entry start

section '.text' code readable executable
start:
    JMP start

When compiled and run from the command prompt, taskmanger reports it takes 108kb of physical memory. When run from Explorer it reports 116kb. I tried a similar program in nasm and also tried different linker options but 108kb was always the smallest memory footprint.

Is this the absolute minimum memory footprint an active process can have? Is it possible to go smaller?

ChrisD
  • 3,378
  • 3
  • 35
  • 40
  • Which linker are you using? And linker options used? – Anders Mar 01 '17 at 23:15
  • this is very related to windows version. in your process loaded `ntdll.dll` and `kernel32.dll` (+`kernelbase.dll` begin from win7 ). initialized different memory structures.. this ~100kb take not your tiny exe but system dlls, PEB, TEB, stack, etc. in what is actual problem ? – RbMm Mar 01 '17 at 23:27
  • @Anders for fasm, I just straight complied it with fasm. With nasm I used GoLink as well as Microsoft's linker. I played about with the heap/stack sizes but couldn't reduce that minimum. – ChrisD Mar 01 '17 at 23:28
  • @RbMm it's not a problem, I'm just interested. – ChrisD Mar 01 '17 at 23:29

1 Answers1

1

Not really sure why this is a useful exercise, any application that actually does anything useful is going to load at least a couple of Windows .DLLs and that will probably increase the memory usage quite a bit.

108kb does not tell us much when you don't say which application you measured it with.

The memory footprint also depends on the Windows version. On Windows 7 and later there are 3 core .DLLs; ntdll, kernelbase and kernel32 while previous versions only have ntdll and kernel32. If you are running a 32-bit app on 64-bit Windows you also get wow64, wow64cpu and wow64win loaded in your process. On every version except Windows 2000 the loader will load kernel32 and its dependencies automatically for you. There is some unavoidable overhead for each .DLL. There is a linked list of loaded .DLLs stored in the PEB and the loader will probably modify the import table in each .DLL (unless this is a fresh never updated Windows install) even if all other pages can be shared with other processes.

In theory the only thing you really have control over in a "do nothing" .EXE is the SizeOfStackCommit and SizeOfHeapCommit members of the optional header but the default for the stack is usually just one page and these values are rounded up so setting them lower will not gain you anything. You cannot control the size of the PEB and TEB(s) and I don't think you can avoid creating the default process heap.

Most people tend to focus on smaller file size, not memory footprint. The smallest usable PE EXE file you can create is 133 bytes on 32-bit Windows. If you don't import anything you can get it down to 97 bytes but then it will not run on Windows 2000 because it assumes that you import something from kernel32. These files are hacks and place the PE header on top of the DOS header etc.

If you goal is simply to get under 108kb then I would try the 97 byte EXE file on Windows 95 or perhaps NT 4. On Windows 95 all the major system .DLLs are shared by all processes.

Community
  • 1
  • 1
Anders
  • 97,548
  • 12
  • 110
  • 164
  • Thanks. As I mentioned, I used Window's Task Manager to measure the physical memory. This is on 32bit Windows 10. – ChrisD Mar 02 '17 at 00:39
  • Task Manger has changed its meaning of different columns over the years so it is perhaps not the best tool to use. Try Process Explorer and VMMap from SysInternals/TechNet. – Anders Mar 02 '17 at 00:48