Hi,
.386
.model flat,stdcall
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
s db "Test",0
.code
start:
lea eax,s
push eax
call StdOut
ret
end start
Results in a binary 2,560 bytes long. Can this be reduced at all?
You could save an easy 512 k by merging the data section with the code section.
1024 bytes with polink, /MERGE:.data=.rdata /MERGE:.rdata=.text
This will give you 1.5k with normal assemble and link.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.code
txt db "Howdy",0 ; in CODE section but before "start" label.
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
invoke StdOut,OFFSET txt
invoke ExitProcess,0
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Is there any reason not to merge .data with .code sections?
When I looked in the original EXE with a hex editor I noticed the data (region?) started at offset 0x800 and ended at 0x9ff (EOF), whilst the code (region?) started at offset 0x400, and ended at 0x7ff.
Now the code (region?) starts at 0x200 and ends at 0x5ff (EOF).
That single change knocked 1024 bytes out of it.
I'm just trying to figure out what it is doing/how it is laid out. :)
Quote from: Astro on July 07, 2009, 03:31:19 PM
Is there any reason not to merge .data with .code sections?
Data will be read only...
Hi Jochen,
You can change the attributes of sections with the linker switch /SECTION
Hi Astro,
Here is an example without combining the sections. The final EXE size is 1024 bytes and the it does not import any function but no guarantee that the EXE will work on every version of Windows. You can find other routines to get the base of kernel32.dll
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
szCmp PROTO :DWORD,:DWORD
GetProcAddr PROTO :DWORD,:DWORD
.code
s db "Test",0
LoadLibrary db "LoadLibraryA",0
FreeLibrary db "FreeLibrary",0
ExitProcess db "ExitProcess",0
printf db "printf",0
dll db "msvcrt.dll",0
start:
mov ecx,[esp]
GetKrnlBaseLoop:
xor edx,edx
dec ecx
mov dx,[ecx+03ch]
test dx,0f800h
jnz GetKrnlBaseLoop
cmp ecx,[ecx+edx+34h]
jnz GetKrnlBaseLoop
push esi
push edi
mov esi,ecx ; esi -> handle to kernel32.dll
invoke GetProcAddr,esi,ADDR LoadLibrary
push OFFSET dll
call eax
mov edi,eax
invoke GetProcAddr,eax,ADDR printf
push OFFSET s
call eax
add esp,4
invoke GetProcAddr,esi,ADDR FreeLibrary
push edi
call eax
invoke GetProcAddr,esi,ADDR ExitProcess
pop edi
pop esi
push 0
call eax
include GetProcAddr.inc
include szCmp.inc
END start
[attachment deleted by admin]
Erol (Vortex) suggested to me that using PoLink instead of Link can result in smaller exe's
@Vortex: Thanks for the example! :U I think I'm keeping up so far! :dazzled:
@dedndave: I think this is mentioned in the examples shipped with the MASM package. I'll have a look.
Quote from: jj2007 on July 07, 2009, 01:31:58 PM
1024 bytes with polink, /MERGE:.data=.rdata /MERGE:.rdata=.text
Yep :U
Quote from: jj2007 on July 07, 2009, 05:09:21 PM
Quote from: Astro on July 07, 2009, 03:31:19 PM
Is there any reason not to merge .data with .code sections?
Data will be read only...
So if the data is in the .code section, I
can't modify it progmatically, but could if it appeared in the .data section?
Astro,
If you have some reason to modify your own code at runtime, learn both the linker attributes for setting an app to READ/WRITE/EXECUTE and then test it under DEP to ensure it works correctly. You may have to use VirtualProtect() on at least some memory range if you have some need to write to the code section.
eliminating the data segment shouldn't reduce the exe size by much
i am guessing the align type for the segments is 16 ?
that means it may save you 15 bytes, plus an entry in the PE header
by the time you add the VirtualProtect code, it's a wash
Hi,
@hutch--: Thanks. I don't have a need to at the moment, but was something I just wanted clarifying for the future. :)
@dedndave: I think it knocked 512 bytes off the exe size, but how much space is actually left over before it increases the file size again due to other factors is an interesting point. Could be self-defeating when the file size is really small.
yah - 32-bit doesn't have ".COM" programs like DOS - i miss those - lol
at least half the apps i wrote were .COM programs