Hello forum :)

I'm always eager to size optimize stuff so I've started to write a tool that
optimizes PE exes :)
So far it zeroes all unneeded stuff in the header, moves some stuff around, and the import table(s) are also optimized saving a few bytes per imported function. A couple of nights ago I wrote some code that moves the imports to unused/ignored space in the PE header (there's lots of it :) wherever it fits..
Now I thought well I might as well move the import descriptors. But this results either in a crashing program or in a program refusing to start. Does anyone happen to know why? I'm sure I updated all pointers/RVAs and all that. I can't understand why it works just fine when moving the import strings but not with the descriptors..
Too hacky perhaps? :)

Any ideas on this or on how to further optimize it are welcome!
Every byte counts :grin:

/Nico
Posted on 2003-08-14 17:50:08 by snq
I guess you're trying to optimize for size and not for speed? ;)
Posted on 2003-08-14 20:20:24 by Tola
Just try linker option "merge", for ex.
/merge:.rdata=.text,
and don't waste your time - generally you can't optimize PE Header.
Posted on 2003-08-15 02:30:42 by masquer
linker option /STUB optimizes my proc by adding 50H bytes after my own 40H bytes lenght DOS stub

this seems to me like M$ has a deal with HDD manufacturers:grin:

and i belive linker adds some garbage into PE, may be it's my "only-for me" data :mad:
Posted on 2003-08-15 03:04:54 by S.T.A.S.
S.T.A.S.

"linker option /STUB optimizes my proc by adding 50H bytes after my own 40H bytes length DOS stub
this seems to me like M$ has a deal with HDD manufacturers
and i belive linker adds some garbage into PE, may be it's my "only-for me" data"

There is a similar thread without an answer about the "garbage":

"What is the data between the DOS-stub-code and the PE-header in MASM-linked files?"
http://www.asmcommunity.net/board/showthread.php?threadid=11182&

masquer,

"and don't waste your time - generally you can't optimize PE Header."


If our exe is big we can put some code&data&resource
in the DOS stub and use it in our Win32 program later

So, we can "optimize" DOS stub rather than PE header



Regards,
Lingo
Posted on 2003-08-15 08:41:25 by lingo12
lingo12,

do we talking about DOS stub optimization or PE header (see Subject)? I'm about the last one.
Btw, I'm easily create working (at least on win2k) executables with size of 1024 bytes.

If our exe is bigger we can put some code&data&resource
in the DOS stub and use it in our Win32 program later


And what's the gain? Don't see any point of such perversion :)
Posted on 2003-08-15 09:15:15 by masquer

Just try linker option "merge", for ex.
/merge:.rdata=.text,
and don't waste your time - generally you can't optimize PE Header.

Of course I use all possible optimizations during linking as well yes.. Throw all sections into one and use my own stub.
But the last thing you say is BS. Like 80% of the space in the header is totally ignored so it leaves lots of space for putting in other things. Like names of imported functions, so you save space elsewhere. In my case the import names are at the end of the file, so you can just remove those bytes. Windows doesn't care that the section is not complete.

Like I said every byte counts, no matter how perverse it may sound :grin:

I need all these tricks for a 4k intro.. Kinda got inspired to do one thanks to this one.
So far I got a minimal D3D8 framework (sets up device and clears/presents) with an even more minimal softsynth in 890 bytes :)
Posted on 2003-08-15 10:40:42 by snq
masquer,
"Btw, I'm easily create working (at least on win2k) executables with size of 1024 bytes."
Try it on WinXP
I'm easily create working executables with size of 7 bytes too
Here: db 4Dh, 5Ah, 0B8h, 1, 4Ch, 0CDh, 21h
Save it in file, rename it to exe and that's all

"And what's the gain? Don't see any point of such perversion"
As you saw the "optimize" is put in quotes
Posted on 2003-08-15 11:23:57 by lingo12
How about completly deleting dos stub. How many users running win32 programs in dos? But if you delete it you can save 192 bytes, jaaaaahuuuu! :grin:

lingo12, if I'm not mistaken you can compress that 7B program ofyours to 5B by using .com extension :)
Posted on 2003-08-15 15:35:59 by iwabee

How about completly deleting dos stub. How many users running win32 programs in dos? But if you delete it you can save 192 bytes, jaaaaahuuuu! :grin:


Actually you can't delete completely it. or at least not the "MZ" and PE header offset (which is at offset 60). You can also move the PE header, as long as you have data that is ignored at offset 60-63 in the file.
My little tool already supports header moving :) by default it moves it to 64 but it works just as well when moving it to 12 or whatever :)
Posted on 2003-08-15 15:49:30 by snq
I wasn't talking about deleting IMAGE_DOS_HEADER, because you need e_magic at 00h and e_lfanew at 3ch. I was thinking about moving PE right after MZ header will decrease program size by 176-448 bytes depending on the linker originally used.

BTW Is my terminalogy lacking? As I know dos stub is code that displays error message in dos and located at 40h in file, right after mz header.
Posted on 2003-08-15 16:29:37 by iwabee
Lingo, thanks a lot!

i've pathced my "Microsoft (R) Incremental Linker Version 5.12.8078":

:0044510C E86FABFFFF call 0043FC80
:00445111 8B8DE0010000 mov ecx, dword ptr
:00445117 89442410 mov dword ptr , eax
:0044511B 90 nop ; 03
:0044511C 90 nop ; C8
:0044511D 898DE4010000 mov dword ptr , ecx
:00445123 FF1510114000 call _tzset

it works just fine!

I think if people are interesting in reducing the size of PE (like you), snq does good job
:alright:
Posted on 2003-08-15 18:44:20 by S.T.A.S.
pft
Posted on 2003-08-15 19:29:24 by f0dder

pft

:confused:

some day i've writen tic-tac toe game for calulator with 107bytes of RAM and w/o even PFT :grin:
so i'm still counting bytes for now, but missing imporrtant things :o
Posted on 2003-08-15 22:21:35 by S.T.A.S.
The best method to optimise:Using a smaller stub + merging sections
Posted on 2003-08-16 04:47:32 by Vortex
Lingo , thank you very much for your interesting post about the encrypted data in the DOS stub.

Do you have an idea how Microsoft generates the "@comp.id" identifier? How can I extract the version number of the compiler that was used? Or do we need a big table with all "@comp.id" values that
Microsoft ever used?

I also wonder why Microsoft's linker writes the "@comp.id" value several times, encryped (XORed) with different constants...
Posted on 2003-09-17 07:38:04 by CodeTester

I'm easily create working executables with size of 7 bytes too
Here: db 4Dh, 5Ah, 0B8h, 1, 4Ch, 0CDh, 21h
Save it in file, rename it to exe and that's all


Why so long?
Here: db 0c3h
Save it in file, rename it to exe and that's all :grin:
Posted on 2003-09-17 12:15:16 by MazeGen
masquer,
"And what's the gain? Don't see any point of such perversion"

Here is my bin2obj program with source code
Where is the text "bin2obj by lingo" and why?

Regards,
Lingo
Posted on 2003-09-17 22:57:07 by lingo12
Sorry for dragging up an old thread, but I'm back :D

I started working on my size optimizer app again today, it produces a bit more reliable results now, it seems. I got inspiration when I couldn't get my binary clock thingy under 1k, and the tool refused to work with the exe.. Before optimizing (but still using all optimized linker settings) it was 1232 bytes, after it's 934, thats 25% off..

Lingo12: nice job, we should start a club for coders obsessed by the size of their programs ;)
But:
If our exe is 2048 bytes I agree with you (I assume we can't create working (WinXP)
Try this one, it works fine on my winxp :)
Posted on 2004-03-11 19:52:11 by snq
hi,

here?s a 589 bytes valid w32 PE file. tested in w95, w95, w2k and XP

size can be smaller, if you put strings in header (put strings before the align 512,db 0 and change +reloc to +imagebase)

ancev
Posted on 2004-03-11 21:10:21 by ancev