Over the last couple of weeks, I have been working on my code
size reduction skills. I always find that a real challenge is good
for expanding ones horizons and forces different points of view.

The challenge is to use FASM (just for fun mind you) to make a
fully functional application window.

Note:
For the purposes of this challenge, my definition of fully functional
means that a cursor must be added to the wndclass struct passed
to RegisterClass (I used IDC_ARROW), but changing the icon from
the default is not needed.

But heres the kicker: :grin:
It must be in a valid PE format runnable right after FASM compiles
it, and it must be no more than 1024 bytes. Small is beautiful
dont ya know.

:eek:
Posted on 2002-09-06 23:55:57 by Graebel
Excuse me. May I ask how you can make a fully executable PE file that's 1k only, with import section?
header + code sec + import sec = 1.5k at the least.
IMHO import section can not be eliminated. Even if you can load user32.dll by some non-standard way in 95/98, win2k still refuses to run any file that's without import section.

Forgive my ignorance where I'm wrong :)
Posted on 2002-09-07 00:41:45 by C.Z.
yes, 1.5k is correct. I'll try some before I go to sleep.

unless of course exe packers are allowed..
Posted on 2002-09-07 00:55:29 by stryker
unless of course exe packers are allowed..

Exe packers still have to call APIs, don't they.
Posted on 2002-09-07 01:10:20 by C.Z.
well, I'm not sure about different methods of different exe packers.

Here's my 1.5kb version.
[size=9]FORMAT PE GUI 4.0

ENTRY START

INCLUDE "\fasm\include\kernel.inc"
INCLUDE "\fasm\include\user.inc"
INCLUDE "\fasm\include\macro\stdcall.inc"
INCLUDE "\fasm\include\macro\import.inc"

SECTION ".code" CODE READABLE WRITEABLE EXECUTABLE

appclass DB "NULL", 0

START:

SIZEOF_WNDCLASSEX = 12 * 4
SIZEOF_POINT = 2 * 4
SIZEOF_MSG = 5 * 4 + SIZEOF_POINT

push ebp
push esp
pop ebp

xor esi, esi

sub esp, SIZEOF_WNDCLASSEX + SIZEOF_MSG
mov DWORD [ebp-SIZEOF_WNDCLASSEX], SIZEOF_WNDCLASSEX
mov DWORD [ebp-SIZEOF_WNDCLASSEX+4], CS_HREDRAW + CS_VREDRAW
mov DWORD [ebp-SIZEOF_WNDCLASSEX+8], WndMsg
mov DWORD [ebp-SIZEOF_WNDCLASSEX+12], esi
mov DWORD [ebp-SIZEOF_WNDCLASSEX+16], esi
mov DWORD [ebp-SIZEOF_WNDCLASSEX+20], 4000h
mov DWORD [ebp-SIZEOF_WNDCLASSEX+32], COLOR_WINDOW+1
mov DWORD [ebp-SIZEOF_WNDCLASSEX+36], esi
mov DWORD [ebp-SIZEOF_WNDCLASSEX+40], appclass
mov DWORD [ebp-SIZEOF_WNDCLASSEX+24], esi
mov DWORD [ebp-SIZEOF_WNDCLASSEX+44], esi
invoke LoadCursor, esi, IDC_ARROW
mov DWORD [ebp-SIZEOF_WNDCLASSEX+28], eax
lea eax, [ebp-SIZEOF_WNDCLASSEX]
invoke RegisterClassEx, eax
mov edi, CW_USEDEFAULT
invoke CreateWindowEx, esi, appclass, appclass, WS_OVERLAPPEDWINDOW, edi, edi, edi, edi, esi, esi, 4000h, esi

push SW_SHOWNORMAL
push eax
call [ShowWindow]

__message_loop:

lea eax, DWORD [ebp-SIZEOF_WNDCLASSEX-SIZEOF_MSG]
invoke GetMessage, eax, esi, esi, esi
test eax, eax
jz __message_loop_exit
lea eax, DWORD [ebp-SIZEOF_WNDCLASSEX-SIZEOF_MSG]
invoke DispatchMessage, eax
jmp __message_loop

__message_loop_exit:

leave
retn

WndMsg:

cmp DWORD [esp+8], WM_DESTROY
je @F
jmp [DefWindowProc]
retn 10h

@@:

invoke PostQuitMessage, NULL
xor eax, eax
retn 10h

SECTION ".idata" IMPORT DATA READABLE WRITEABLE

library user, "user32.dll"

user:
import LoadCursor, "LoadCursorA", \
RegisterClassEx, "RegisterClassExA", \
CreateWindowEx, "CreateWindowExA", \
ShowWindow, "ShowWindow", \
GetMessage, "GetMessageA", \
DispatchMessage, "DispatchMessageA", \
PostQuitMessage, "PostQuitMessage", \
DefWindowProc, "DefWindowProcA"[/size]
Nice! font formatting... :)

Tested on win2k only.
Posted on 2002-09-07 02:01:33 by stryker
only can use
Posted on 2002-09-07 02:03:37 by zjlcc
Got the idea.
Just to combine the code and import sections. :)
Posted on 2002-09-07 02:06:25 by C.Z.
wow, I never thought of placing the code at the idata section. :)
Posted on 2002-09-07 02:07:57 by stryker
The simplest solution is to include everything in the .flat section (automatically generated by fasm). This example shows my "recommended" way to do it.
Posted on 2002-09-07 04:45:02 by Tomasz Grysztar
Here's mine. An old-fashioned pad that sticks to the top of the screen.
Tested on 2k only.
I wanted to make the window caption longer but, when I added another byte to it, the exe turned out to be 1.5 k. :grin: :grin: :grin:
Posted on 2002-09-07 07:03:37 by C.Z.
from Dmitriy Goldobin" <gold@ems.ru>

minimal PE-exe
for most win 548 (224h)
for XP only 117 (75h) without dosstub 97 (61h)

http://www.ems.ru/~gold/pi.exe


Original (rus, sorry):
http://www.ems.ru/~gold/pi.exe
Posted on 2002-09-07 10:16:36 by dreamer2
Cool =)

Just what I was looking for. Now I have some more reading
material to digest hehe.

To Zjlcc:
Does the import section zero out those structures? I notice
that you are not initializing all of the fields before use...

BTW,
Looks like (after some peeking at a couple of the examples)
that I still have a few tricks to add to my feather cap.

Here was my original (bloated) attempt.
Posted on 2002-09-07 17:04:31 by Graebel
i have a question
the pi.exe . does it calculate the pi . or loads it from memory

??
can someone translate the rus?


bye

thanks

eko
Posted on 2002-09-08 08:47:29 by eko

i have a question
the pi.exe . does it calculate the pi . or loads it from memory

??
can someone translate the rus?


bye

thanks

eko


In russian nothing about pi, only about PE sections.
See in debugger...
Posted on 2002-09-08 14:17:03 by dreamer2
To dreamer2:

How can it be so small in XP?
The code is 5Ch = 92 bytes, then just five more of stub to make it 97?
How can this be?
And what five bytes?
I wish I could understand rusian, but right now, can you explain it more?
Posted on 2002-09-25 13:12:44 by slop

To dreamer2:

How can it be so small in XP?
The code is 5Ch = 92 bytes, then just five more of stub to make it 97?
How can this be?
And what five bytes?
I wish I could understand rusian, but right now, can you explain it more?


Ask author about it ;)

Posted on 2002-09-26 03:30:17 by dreamer2
Hi,

All i understand from the code is that the author dumped the import section into the pe header. No wonder my program crash while trying to read the import table.

Anyone understand the code?
Posted on 2002-10-07 09:18:55 by roticv
viktor,
The 65 bytes version only works in XP
Posted on 2002-10-07 12:39:13 by slop
Hi sloppy,

I have no idea but i am looking at the 548 byte verison and it works prefectly okay.


Acutally my name is Victor.
Posted on 2002-10-07 22:38:37 by roticv
Victor,

he has used sort of incredibly wit technoques to 'shrink' the different sections.
For example, he mixes and overlaps the PE header into the MS-stub, and this last is almost inexistent, it only keeps the 'vital' offsets (those that the kernel loader uses), using all the rest, and pointing to it where necessary.

Now I call that a great hack :)
Posted on 2002-10-08 12:55:52 by slop