The MASM Forum

General => The Campus => Topic started by: StarsInTheSky on May 08, 2015, 12:34:45 PM

Title: small hello world again
Post by: StarsInTheSky on May 08, 2015, 12:34:45 PM
Hi guys,

reading this:
http://www.masmforum.com/board/index.php?PHPSESSID=8d46cd4ecb1688be429ab49694ec53e6&topic=1202.0

I have a couple of questions:

I am trying the same, to minimize my file. I am on windows 7. My first question is I read somewhere with good parameters, link.exe can be as good as polink.exe.

here is my try:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\link.exe" /SUBSYSTEM:WINDOWS /defaultlib:C:\masm32\lib\kernel32.lib /defaultlib:C:\masm32\lib\user32.lib messageboxa2.obj /MERGE:.rdata=.text /MERGE:.data=.text /OPT:REF /OPT:ICF /INCREMENTAL:NO /OUT:messageboxa2c.exe

this is giving me a 2048 bytes file. If I try anything with /ALIGN or /FILEALIGN the messagebox won't run no more.

With polink.exe I get 1536 bytes. So I am not quite there. 1.any ideas?

It seems I can call the libraries two ways. either using

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib

and then "invoke"

or use

extrn MessageBoxA@16 : PROC
extrn ExitProcess@4 : PROC

and then "call". but then I need to use /defaultlib in the linker.

2.is there a middle way? Can I use "call" without need of using /defaultlib for every single library?

ok my third question is about what can be read in the given url. Someone got a lot more advanced and used a packer, and then added an unpacker inside the file. Unfortunately the given link for that is not working anymore. 3.How would I go about doing the same and learn all that?

next when I disassembled my file, I found that my disassembler got all disoriented when I merged the data and text sections. I can no longer easily extract the strings. 4.How do I help my poor disassembler to regain sanity and display the strings? (well you can suggest the disassembler of your choice)
Title: Re: small hello world again
Post by: Mikl__ on May 08, 2015, 03:14:22 PM
Hi, StarsInTheSky !
see Tiny PE in win64 (http://masm32.com/board/index.php?topic=4114.0) msgbox_64 in 345 bytes
for WinXP msgbox can be in 97 bytes (http://www.cyberforum.ru/images/smilies/ap.gif)
Title: Re: small hello world again
Post by: StarsInTheSky on May 08, 2015, 03:44:32 PM
Mikl, oh my so nice!! there is no makeit.bat file, how do you assemble and link this? and is there a 32 bit version?
Title: Re: small hello world again
Post by: Mikl__ on May 08, 2015, 05:10:49 PM
version for ONLY 32-bit WinXP
the text of the program, which received from the boot loader address WinAPI-functions LoadLibraryA and MessageBox, creates a file tiny97.exe, consisting only of minimum PE-header file. Within this heading, in those of his fields, which can be ignored, it is the program code that displays the MessageBox, with a headline and the text "user32".
(http://www.cyberforum.ru/attachments/220076d1357184302)
We proceed to the construction of our PE-file. We take the minimum possible size of the alignment of sections - 4 bytes - and file - 4 bytes.
The image of our program will consist of only one section, which will be published and the data and code
.686P
.model flat
include windows.inc
includelib user32.lib
includelib kernel32.lib
extern _imp__MessageBoxA@16:dword
extern _imp__WriteFile@20:dword
extern _imp__CreateFileA@28:dword
extern _imp__CloseHandle@4:dword
extern _imp__wsprintfA:dword
extern _imp__LoadLibraryA@4:dword
image_base=400000h
.code
start: xor ebx,ebx
mov eax,_imp__MessageBoxA@16
        push eax
sub eax,_MessageBox-buffer+image_base+4
mov _MessageBox,eax
mov eax,_imp__LoadLibraryA@4
        push eax
        sub eax,_LoadLibrary-buffer+image_base+4
mov _LoadLibrary,eax
push offset szInfoText
        push offset cBuff
call _imp__wsprintfA
add esp,4*4
        push MB_ICONINFORMATION OR MB_SYSTEMMODAL;1040h
        push offset szInfoCap 
        push offset cBuff
        push ebx
call _imp__MessageBoxA@16
push ebx ;NULL
push FILE_ATTRIBUTE_ARCHIVE
push CREATE_ALWAYS
push ebx
push FILE_SHARE_READ or FILE_SHARE_WRITE
push GENERIC_READ or GENERIC_WRITE
push offset namefile
call _imp__CreateFileA@28
mov edi,eax     ;hFile
push ebx        ;lpOverlapped
      push offset SizeReadWrite ;lpNumberOfBytesToWrite
push buffer_end-buffer;97 ;nNumberOfBytesToWrite
push offset buffer ;lpBuffer
push edi ;hFile
call _imp__WriteFile@20
push edi ;hFile
call _imp__CloseHandle@4
retn
.data
buffer dd 'ZM','EP';Signantures
dw 14Ch     ;Machine
dw 1     ;count of section
start1: xchg eax,ebx
mov edi,offset user-buffer+image_base
push edi
jmp a1
db 0,0,0
dw buffer_end-optional_header;size of optional header
dw 103h     ;characteristics
optional_header:
dw 10Bh     ;magic optional header
a1:     
db 0E8h     ;call LoadLibraryA
_LoadLibrary dd 0
push ebx
push edi
push edi
push ebx
jmp a2
db 0,0,0
dd start1-buffer ;Entry point
a2:
        db 0E8h     ;call MessageBoxA
_MessageBox dd 0
        ret
dw 0
dd image_base
dd 4     ;section alignment
dd 4     ;file alignment
user db 'user32',0,0
dw 4     ;Image version major
dw 0     ;Image version minor
dd 0     ;reserved
dd 68h     ;size of image
dd 64h     ;size of header
dd 0     ;checksum
db 2     ;subsystem (gui)
; ---------------------------------------------------------------------------
buffer_end:
szInfoCap db "Creator tiny MessageBox",0
szInfoText db "API Addresses:",13,10
   db "LoadLibraryA:  0x%08lX",13,10
   db "MessageBoxA:  0x%08lX",0
cBuff db 70 DUP (0)
namefile db 'tiny97.exe',0
SizeReadWrite dd 0
end start
Title: Re: small hello world again
Post by: StarsInTheSky on May 08, 2015, 05:55:15 PM
aaah, you have given up on link and polink, you are writing your own .exe !!! smart !!
when you say win xp only, what makes it not working in win7 ?
Title: Re: [still open] small hello world again
Post by: Mikl__ on May 08, 2015, 06:10:50 PM
Quotewhat makes it not working in win7 ?
StarsInTheSky,
to get accurate answers to need to send precise questions, for Win seven x64 see Tiny PE in win64 (http://masm32.com/board/index.php?topic=4114.0) (http://www.cyberforum.ru/images/smilies/ap.gif) sorry for my bad English
Title: Re: [still open] small hello world again
Post by: StarsInTheSky on May 08, 2015, 06:27:33 PM
I know it's a bit wide. but I can run 32-bit files on my win7 as well, and I can compile x86 code. so I was wondering for instance, could be requirements on the PE file format that has changed for 64 os's ?

the header directives looks so great in the tiny PE. but you must be using a more potent assembler :)
I tried to add it to my file and my ML.exe got stumped on the first one .Machine  :icon_mrgreen: 
Title: Re: [still open] small hello world again
Post by: Mikl__ on May 08, 2015, 06:35:58 PM
I used masm (ml and link) for msgbox in 97 byte, for Tiny PE x64 I used FASM, but I was afraid to tell about it on the MASM32-forum so as not to start a holy war FASM vs MASM (http://www.cyberforum.ru/images/smilies/ap.gif)
The file format for Win64 is called PE32+. From nearly every viewpoint, the format is structurally identical to the Win32 PE file. A very few fields such as the ImageBase in the header have been widened, one field was deleted, and one field was changed to reflect a different CPU type. Table shows the fields that have changed.

Header FieldChange
MagicSet to 0x20b instead of 0x10b
BaseOfDataDeleted
ImageBaseWidened to 64 bits
SizeOfStackReserveWidened
SizeOfStackCommitWidened
SizeOfHeapReserveWidened
SizeOfHeapCommitWidened
Beyond the PE header, there aren't many changes. A few structures such as IMAGE_LOAD_CONFIG and IMAGE_THUNK_DATA simply had some of their fields widened to 64 bits. The addition of the PDATA section is more interesting, as it highlights one of the major differences between the Win32 and Win64 implementation: exception handling.
Title: Re: [still open] small hello world again
Post by: StarsInTheSky on May 08, 2015, 06:54:25 PM
yes, thanks, so one answer to my q #1 is to use other tools :D
But then I might not be able to use some of the nice libraries available here.
everything has its pros and cons.

What is the best you've got it down to with masm ? I've got it down to 1024 bytes with polink now.

EDIT: ah, just saw your table, thank you for taking the time elaborating.
So with those changes, would it run on an x64 win XP ? and win 7 ?
Title: Re: small hello world again
Post by: hutch-- on May 08, 2015, 06:56:27 PM
> so as not to start a holy war FASM vs MASM

Don't hold your breath waiting for the holy war, there never has been one.

One favour, forget "[still open]", we are a forum of members, not a paid help desk.
Title: Re: small hello world again
Post by: StarsInTheSky on May 08, 2015, 07:05:32 PM
did not mean offending, removed the tag 8)
Title: Re: small hello world again
Post by: Mikl__ on May 08, 2015, 07:11:07 PM
Good evening, hutch--!
I just did not want to break the rules...
Title: Re: small hello world again
Post by: sinsi on May 08, 2015, 07:16:17 PM
> so as not to start a holy war FASM vs MASM
Some of us use both, different tools for different jobs...
Title: Re: [still open] small hello world again
Post by: jj2007 on May 08, 2015, 07:19:51 PM
Quote from: Mikl__ on May 08, 2015, 06:35:58 PMa holy war FASM vs MASM

Just curious: can you do macros such as mov ecx, len(esi) in FASM?
Title: Re: small hello world again
Post by: Mikl__ on May 08, 2015, 07:35:23 PM
Ciao, jj2007!
Non ho potuto scrivere questo macro in FASM o in MASM (http://www.cyberforum.ru/images/smilies/sorry.gif)
Title: Re: small hello world again
Post by: sinsi on May 08, 2015, 07:39:00 PM
jj, the macros in fasm are much more complex.

; example of simplified Windows programming using complex macro features
include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here
.code
  start:
invoke MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK
invoke ExitProcess,0
.end start

Here's how to import functions the raw way

section '.idata' import data readable writeable

  dd 0,0,0,RVA kernel_name,RVA kernel_table
  dd 0,0,0,RVA user_name,RVA user_table
  dd 0,0,0,0,0

  kernel_table:
    ExitProcess dd RVA _ExitProcess
    dd 0
  user_table:
    MessageBoxA dd RVA _MessageBoxA
    dd 0

  kernel_name db 'KERNEL32.DLL',0
  user_name db 'USER32.DLL',0

  _ExitProcess dw 0
    db 'ExitProcess',0
  _MessageBoxA dw 0
    db 'MessageBoxA',0

and the easy way

; import data in any section
data import
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL',\
winmm,'WINMM.DLL'
import kernel32,\
ExitProcess,'ExitProcess'
import user32,\
MessageBoxA,'MessageBoxA'
import winmm,\
mciSendString,'mciSendStringA'
end data


No need for a linker.
Title: Re: small hello world again
Post by: jj2007 on May 08, 2015, 07:44:33 PM
Quote from: sinsi on May 08, 2015, 07:39:00 PM
jj, the macros in fasm are much more complex.

So a simple mov ecx, len(esi) is not possible? I.e. the function form of macros doesn't exist in FASM?
Title: Re: small hello world again
Post by: Mikl__ on May 08, 2015, 07:51:14 PM
jj2007,
and how you can know  the length of the string pointed to by the register ESI before compilation?
Title: Re: small hello world again
Post by: jj2007 on May 08, 2015, 08:54:46 PM
Quote from: Mikl__ on May 08, 2015, 07:51:14 PM
jj2007,
and how you can know  the length of the string pointed to by the register ESI before compilation?

Mysteries of MASM :P

Run this with a debugger:
include \masm32\include\masm32rt.inc

.code
start:
  mov esi, chr$("Hello World")
  MsgBox 0, str$(len(esi)), "Bytes:", MB_OK
  exit
end start
Title: Re: small hello world again
Post by: hutch-- on May 08, 2015, 08:59:58 PM
Mikl__,

Fixed length string lengths are known at assembly time, they do not necessarily need runtime support, even though runtime support will deliver the same answer. The pre-processor in MASM is a bad mannered old pig but it is powerful.
Title: Re: small hello world again
Post by: StarsInTheSky on May 09, 2015, 06:50:07 AM
Just an update on my struggle to understand #2 question...

First this Quickedit is a wonderful, I love the way you easily can change all menues :D

So I am using the makeit.bat option, inside my makeit.bat I put the following:

set PATH=%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin
Set filepath=%1
For %%A in (%filepath%) do (
    Set Folder=%%~dpA
    Set fileName=%%~nxA
)

nmake Name=%filename%
pause


So I am getting the filename from Quickedit and I pass it to nmake. In my MAKEFILE I have:

$(NAME).exe: $(NAME).obj
        "\masm32\bin\poLink.exe /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib /MERGE:.rdata=.text /MERGE:.data=.text /OPT:REF /OPT:NOWIN98 $(NAME).obj
$(NAME).obj: $(NAME).asm
        "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\ml.exe" /c /coff /Cp $(NAME).asm


But the libpath is not working for my code. The calls to MessageBoxA@16 and ExitProcess@4 gives me errors.
So not been succesful in replacing the /defaultlib:C:\masm32\lib\kernel32.lib /defaultlib:C:\masm32\lib\user32.lib yet.
I'm missing something...

EDIT: I got #2 working. Just by including the inc files and the libs, instead of the external declarations, the calls worked. i don't need to write it with the invoke syntax.  :icon_mrgreen: In fact Mikl has given me hints about this with the codes. I can use my external declarations with the libs and omit the includes if I like to. Thanks again Mikl  :t
Title: Re: small hello world again
Post by: StarsInTheSky on May 13, 2015, 08:36:47 AM
For my particular question about #1, I have only found others having problem with the /ALIGN argument as well and no solution. Abandoning Link for polink, I got my hello world to 1K, and I've read that 1 K (1024 bytes) is the lowest you can get a working exe file on win 7 x64. Could someone confirm? Is there a theory behind that? Is it related to that the memory manager handles memory at 1K chunks in x64? I tried to run the upx packer on my 1K messagebox, and indeed it throws this error: upx: messageboxa2e.exe: NotCompressibleException

For learning PE I found this thread:
http://board.flatassembler.net/topic.php?t=1309

Is there a MASM syntax equivalent?

Title: Re: small hello world again
Post by: jj2007 on May 13, 2015, 09:25:42 AM
Quote from: StarsInTheSky on May 13, 2015, 08:36:47 AMI've read that 1 K (1024 bytes) is the lowest you can get a working exe file on win 7 x64. Could someone confirm?

You should not believe all that stuff that people post on the Internet. 929 bytes is possible (http://masm32.com/board/index.php?topic=44.0)  8)
Title: Re: small hello world again
Post by: StarsInTheSky on May 13, 2015, 10:15:39 AM
Hehe dos is dead, long live windows. the dos stub has become the data section  :greenclp: Thanks JJ
Title: Re: small hello world again
Post by: Mikl__ on May 13, 2015, 01:07:53 PM
Hi, StarsInTheSky !
For learning PE see Or Iczelion's PE Tutorials (http://www.cyberforum.ru/images/smilies/rtfm.gif)
or Microsoft Portable Executable and Common Object File Format Specification (http://masm32.com/board/index.php?action=dlattach;topic=4210.0;attach=4047)
or PE a windows executable walkthrough (http://masm32.com/board/index.php?action=dlattach;topic=4210.0;attach=4048)
Title: Re: small hello world again
Post by: K_F on May 14, 2015, 08:38:46 AM
Hey Stars.. sh.tload of stuff to go through...  :biggrin:

Don't worry, we all had to do the same.. takes a bit of time but you'll get there.
.. and when it happens.. there's no looking back !!  :t