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
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
I guess you're trying to optimize for size and not for speed? ;)
Just try linker option "merge", for ex.
/merge:.rdata=.text,
and don't waste your time - generally you can't optimize PE Header.
/merge:.rdata=.text,
and don't waste your time - generally you can't optimize PE Header.
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:
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:
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
"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
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.
And what's the gain? Don't see any point of such perversion :)
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
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 :)
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 :)
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
"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
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 :)
lingo12, if I'm not mistaken you can compress that 7B program ofyours to 5B by using .com extension :)
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 :)
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.
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.
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:
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:
pft
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
The best method to optimise:Using a smaller stub + merging sections
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...
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...
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:
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
"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
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:
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 :)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
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