The MASM Forum

General => The Laboratory => Topic started by: aw27 on October 06, 2017, 05:20:57 AM

Title: Looking for the smallest possible .EXE
Post by: aw27 on October 06, 2017, 05:20:57 AM
 :biggrin:

I have been able to see 32-bit .exes with around 100 bytes, however they don't launch on a 64-bit operating system.

This is as small as I could go for a 32-bit .exe on 64-bit OS - 515 bytes (I could reduce it to 513 bytes leaving only the ret).

It was based on a sample in the Jwasm\Uasm Samples directory:



;--- assemble: UASM -bin -Fo tiny.exe tiny.ASM

    .386
    option casemap:none

    include winnt.inc   ;Use the simplified winnt.inc from Sample folder of UASM.

IMAGEBASE equ 400000h

PEHDR segment dword FLAT
    ORG IMAGEBASE
start_header label near

;--- simplified DOS "MZ" header
IMAGE_DOS_HEADER <"ZM", 0, 0, 0,0,0,0,0,0,0,0,0,0,0,<0>,0,0,<0>,IMAGEREL PEHdr>

;--- define the Win32 "PE" header
PEHdr label byte
    db "PE",0,0
    IMAGE_FILE_HEADER <IMAGE_FILE_MACHINE_I386, num_sections, 0, 0, 0, sizeof IMAGE_OPTIONAL_HEADER32,\
        IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LOCAL_SYMS_STRIPPED>

    IMAGE_OPTIONAL_HEADER32 { 10Bh, ;magic
        6,0,                        ;linker major, minor
        0,0,0,              ;sizeof code, initialized data, uninitialized data
        IMAGEREL main,    ;entry point
        0, 0,  ;baseof code, data
        400000h,    ;imagebase
        1000h,200h,   ;section alignment, file alignment
        5,0,          ;OS major, minor
        0,0,          ;Image major, minor
        5,0,          ;Subsys major, minor
        0,            ;win32 version
        2000h,        ;sizeof image
        1000h,        ;sizeof header
        0,            ;checksum
        IMAGE_SUBSYSTEM_WINDOWS_CUI,
        0,            ;dll characteristics
        100000h,1000h,;stack res,com
        100000h,1000h,;heap res, com
        0,            ;loader flags
        16,           ;number of directories
  16 dup (<0,0>)}
;--- define the section table

sectiontable label byte
    IMAGE_SECTION_HEADER <".text", <sizeof_text>, IMAGEREL start_text, sizeof_text,\
        200h, 0, 0, 0, 0, 060000020h >
num_sections equ ( $ -  sectiontable ) / sizeof IMAGE_SECTION_HEADER

    ORG IMAGEBASE+200h   ;forces physical size of header to 200h and sets VA to 400200h

PEHDR ends


_TEXT segment dword public FLAT 'CODE'
ORG 0E00h   ; change pc to RVA 1000h, section alignment and file alignment are different
start_text label near

;--- entry
main proc c
xor eax, eax
ret
main endp

sizeof_text equ $ - start_text

_TEXT ends

    END


Note: Most of the PE fields are not used at all by the launcher, so you may be surprised to find them zeroed here.
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 06, 2017, 06:12:25 PM
I attach a 32-bit .exe with 358 bytes, but it will only run on a 32-bit Operating System.
This is probably as short as we can go without using the ultra "dirty" tricks elaborated here:
http://www.phreedom.org/research/tinype/

In the attachment I include a batch file to confirm that the .Exe actually works (it should echo the returned value which in this case is 33).

Title: Re: Looking for the smallest possible .EXE
Post by: jj2007 on October 06, 2017, 06:39:05 PM
Eight bytes should be enough to print "hello world" (http://www.masmforum.com/board/index.php?topic=10947.msg80459#msg80459) ;)
Title: Re: Looking for the smallest possible .EXE
Post by: hutch-- on October 06, 2017, 08:05:38 PM
 :biggrin:

You guys must be bored.  :P
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 06, 2017, 09:03:28 PM
Quote from: jj2007 on October 06, 2017, 06:39:05 PM
Eight bytes should be enough to print "hello world" (http://www.masmforum.com/board/index.php?topic=10947.msg80459#msg80459) ;)
Yes, I miss as well those days where .com were not top level domains.  :(

Quote
You guys must be bored.  :P
sights.  :(
Title: Re: Looking for the smallest possible .EXE
Post by: jj2007 on October 06, 2017, 09:27:55 PM
Quote from: hutch-- on October 06, 2017, 08:05:38 PMYou guys must be bored.  :P

And proudly so :bgrin:
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 06, 2017, 11:13:23 PM
Cool topic.

aw27, thanks for the link to phreedom.org.
One thing on my To-Do list is to create an executable file Compressor/Packer/Cruncher.
You triggered me to finally start studying this topic.
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 06, 2017, 11:43:30 PM
Since I was at it I decided to use some of the "dirty" tricks from phreedom.org and I reduced the file size to 130 bytes! It was tested in Windows XP 32-bits and worked.
Basically the dirty tricks consist in moving structures to the middle of unused (by the loader) structure parts.
I did not try the last part, where phreedom.org states that we could save a further 26 bytes by using the zeros of the page after the end of the file because according to him it was not working for Windows 2000, so I did not expect miracles for XP.
Also I did not move the executable code to the middle of a structure because the benefit would not be important, only 3 bytes less.

Quote
One thing on my To-Do list is to create an executable file Compressor/Packer/Cruncher.
Excellent idea, Siekmanski!  :t
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 07, 2017, 02:37:42 AM
Now working on 64-bit.  :bgrin:
Smallest file without stripping anything will be 520 bytes.


;--- assemble: UASM64 -bin -Fo tiny64.exe tiny64.ASM

.x64
option casemap:none

include winnt64.inc   ; Modification for 64-bit of winnt.inc from Sample folder of UASM.

IMAGEBASE equ 140000000h

PEHDR segment dword FLAT

;--- define the DOS "MZ" header

    ORG IMAGEBASE

    IMAGE_DOS_HEADER <"ZM", 80h, 1, 0,4,0,-1,0,200h,0,0,0,0,0,<0>,0,0,<0>,IMAGEREL PEHdr>

;--- define the "PE" header

PEHdr label byte
    db "PE",0,0
    IMAGE_FILE_HEADER <IMAGE_FILE_MACHINE_AMD64, num_sections, 0, 0, 0, sizeof IMAGE_OPTIONAL_HEADER64,\
        IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_LARGE_ADDRESS_AWARE or IMAGE_FILE_LOCAL_SYMS_STRIPPED>

    IMAGE_OPTIONAL_HEADER64 { 20Bh, ;magic for PE+ 64-bit
        0Eh,0Ah,                          ;linker major, minor
        1000h,1000h,0,                 ;sizeof code, initialized data, uninitialized data
        IMAGEREL main,    ;entry point
        IMAGEREL start_text,  ;baseof code
        IMAGEBASE,    ;imagebase
        1000h,200h,    ;section alignment, file alignment
        6,0,          ;OS major, minor
        0,0,          ;Image major, minor
        6,0,          ;Subsys major, minor
        0,                    ;win32 version
        2000h,        ;sizeof image
        1000h,        ;sizeof header
        0,            ;checksum
        IMAGE_SUBSYSTEM_WINDOWS_CUI,
        0,            ;dll characteristics
        100000h,1000h, ;stack res,com
        100000h,1000h, ;heap res, com
        0,            ;loader flags
        16,            ;number of directories
        16 dup (<0,0>)}

;--- define the section table

sectiontable label byte
    IMAGE_SECTION_HEADER <".text", <sizeof_text>, IMAGEREL start_text, sizeof_text,\
        200h, 0, 0, 0, 0, 060000020h >
num_sections equ ( $ -  sectiontable ) / sizeof IMAGE_SECTION_HEADER

    ORG IMAGEBASE+200h   ;forces physical size of header to 200h and sets VA to IMAGEBASE + 200h

PEHDR ends

_TEXT segment dword public FLAT 'CODE'
ORG 0E00h   ; change pc to RVA 1000h section alignment and file alignment are different
start_text label near

main proc
mov rax,33
ret
main endp

sizeof_text equ $ - start_text

_TEXT ends



Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 07, 2017, 04:37:03 AM
This is the final and tiniest x64 file I was able to obtain that runs without crashing and without under the table tricks. Size=376 bytes.
And this ends my quest for the smallest .exes  possible :dazzled:

Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 13, 2017, 08:08:28 AM
Hi all,

The aw27 32 bit examples did not run on my 64 bit Windows 8.1 machine.
I'm new to this topic, but did a lot of reading and testing the last few days.
The smallest 32 bit example that runs now on my Windows 8.1 is 268 bytes.
The code size is only 128 bytes. ( padded with zeros to 268 bytes )

You can run the RUN.bat to execute the small exe to get the result, it should be: 55
If it runs on Windows XP <-> Windows 10, I could use this as a template for an executable packer/cruncher.

Would you guys be so nice and test if it runs on other Windows versions?  :t

Included the source ( fully commented ) for the PE32 writer, which creates the executable file.

Marinus
Title: Re: Looking for the smallest possible .EXE
Post by: hutch-- on October 13, 2017, 08:40:59 AM
Result on Win 10 64.

Executing Small_PE32.exe

Result is: 55

Press any key to continue . . .
Title: Re: Looking for the smallest possible .EXE
Post by: jj2007 on October 13, 2017, 12:28:03 PM
Same on Win7-64, but it fails with a c5 exception in my XP VM.
Title: Re: Looking for the smallest possible .EXE
Post by: felipe on October 13, 2017, 12:40:12 PM
All good here in windows 8.1 64 bits
:icon14:
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 13, 2017, 04:35:57 PM
The first of my samples, with 515 bytes was tested and run on Windows 10 64-bit.
The others failed on 64-bit OS, as I mentioned.

I will check the  Siekmanski work.
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 13, 2017, 05:21:36 PM
Fails in Vista 64-bit with:
Problem signature:
  Problem Event Name:   APPCRASH
  Application Name:   Small_PE32.exe
  Application Version:   0.0.0.0
  Application Timestamp:   00000000
  Fault Module Name:   ntdll.dll
  Fault Module Version:   6.0.6002.19594
  Fault Module Timestamp:   56ac2982
  Exception Code:   c0000005
  Exception Offset:   000355d6
  OS Version:   6.0.6002.2.2.0.256.1
  Locale ID:   1033
  Additional Information 1:   e51a
  Additional Information 2:   4c0d4d78887f76d971d5d00f1f20a433
  Additional Information 3:   e51a
  Additional Information 4:   4c0d4d78887f76d971d5d00f1f20a433


Fails in XP 64-bit with 0xC0000005

I did not test with others because have been done already.
Title: Re: Looking for the smallest possible .EXE
Post by: sinsi on October 13, 2017, 05:37:17 PM
Windows 7 32/64 OK
Windows 10 64 OK

As per aw27, Vista 32/64 and XP64 error C0000005, but - Vista 32/64 print the correct figure 55, XP (and 2000, FWIW) print 128
Title: Re: Looking for the smallest possible .EXE
Post by: hutch-- on October 13, 2017, 06:40:30 PM
This is what I can get with Pelle's linker, alignment at 16 bytes, merge data with text and bare minimum code to make a MessageBox run, 768 bytes.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    xor rcx, rcx
    mov r9, rcx
    lea r8, titl
    lea rdx, text
    call MessageBox

    xor rcx, rcx
    call ExitProcess

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    text db "How D",0
    titl db "Title",0

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end


The batch file.


@echo off

set appname=HowD

if exist %appname%.obj del %appname%.obj
if exist %appname%.exe del %appname%.exe

\masm32\bin64\ml64.exe /c %appname%.asm

\masm32\bin64\polink.exe /SUBSYSTEM:WINDOWS /MERGE:.data=.text /MACHINE:X64 /ALIGN:16 /ENTRY:entry_point /nologo /LARGEADDRESSAWARE %appname%.obj

dir %appname%.*

pause


Build your own stub file and you save an extra 64 bytes. 704 bytes and I think its still a legal 64 bit PE.


00000000 :4D 5A 90 00 03 00 00 00 - 04 00 00 00 FF FF 00 00
00000010 :B8 00 00 00 00 00 00 00 - 40 00 00 00 00 00 00 00
00000020 :00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030 :00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 13, 2017, 08:22:08 PM
Thanks guys,

I have to learn a lot more about this topic.
I'll have to study, how other exe packers handle the PE collapsing and if they run on all windows versions.
It's interesting but worthless if it doesn't run on all machines.
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 13, 2017, 08:53:34 PM
A last request, to test this one.

To be sure, code alignment and file size makes a difference?
Code starts now at offset 128 and the file is padded with zeros to 1024 bytes.
Title: Re: Looking for the smallest possible .EXE
Post by: jj2007 on October 13, 2017, 09:55:51 PM
The application failed to initialise properly, code C000005. On XP, that is - everything OK on 7-64.
Title: Re: Looking for the smallest possible .EXE
Post by: hutch-- on October 13, 2017, 10:58:04 PM
Mrinus,

2nd version on win10 64 professional.



Executing Small_PE32.exe

Result is: 55

Press any key to continue . . .
Title: Re: Looking for the smallest possible .EXE
Post by: Mikl__ on October 13, 2017, 11:34:51 PM
Tiny MessageBox x64 in FASM (http://masm32.com/board/index.php?topic=4190.msg57973#msg57973)  Size of exe-file x64 is 298 bytesformat binary as 'exe'
include 'win64a.inc'

struc dbs [data]
{
  common
  . db data
  .size = $ - .
}

IMAGE_DOS_SIGNATURE equ 5A4Dh
IMAGE_NT_SIGNATURE equ 00004550h
PROCESSOR_AMD_X8664 equ 8664h
IMAGE_SCN_CNT_CODE equ 00000020h
IMAGE_SCN_MEM_WRITE equ 80000000h
IMAGE_SCN_MEM_READ equ 40000000h
IMAGE_SCN_CNT_INITIALIZED_DATA equ 00000040h
IMAGE_SUBSYSTEM_WINDOWS_GUI equ 2
IMAGE_NT_OPTIONAL_HDR64_MAGIC equ 20Bh
IMAGE_FILE_RELOCS_STRIPPED equ 1
IMAGE_FILE_EXECUTABLE_IMAGE equ 2
IMAGE_BASE equ 0x400000
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h
use64
org 0
;--------DOS-stub-------------------------------
Signature dw IMAGE_DOS_SIGNATURE,0
;-------PE-header--------------------------------------------------
ntHeader dd IMAGE_NT_SIGNATURE;'PE'
;image_header----
Machine dw PROCESSOR_AMD_X8664;CPU Type
Count_of_section dw 0;Number of sections
TimeStump dd 0;Information about the time when the PE-file was compiled
Symbol_table_offset dd 0;A pointer to the size of debug information
Symbol_table_count dd 0;A pointer to the COFF symbol table-PE-format
Size_of_optional_header dw begin-optional_header;The size of optional header
Characteristics dw IMAGE_FILE_RELOCS_STRIPPED or \
IMAGE_FILE_EXECUTABLE_IMAGE;file attributes
;-------Standard field NT
optional_header:
Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC;Status Display File
Linker_version_major_and_minor dw 9;Contain the linker version that created the file.
Size_of_code dd 0;The total size of the code sections
Size_of_init_data dd 0x70;The total size of initialized data
Size_of_uninit_data dd 0;The total size of the uninitialized data
entry_point dd start
base_of_code dd begin
;------Additional fields NT-----------------------------------------------
image_base dq IMAGE_BASE
section_alignment dd 4
file_alignment dd ntHeader
OS_version_major_minor dw 5,2
image_version_major_minor dd 0
subsystem_version_major_minor dw 5,2
Win32_version dd 0
size_of_image dd end_import
size_of_header dd begin
checksum dd 0
subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI
DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
Stack_allocation dq 0x100000
Stack_commit dq 0x1000
Heap_allocation dq 0x100000
Heap_commit dq 0x1000
loader_flag dd 0
number_of_dirs dd (begin-export_RVA_size)/8
export_RVA_size dq 0
import_RVA_size dd _import,end_import-import
;--------code and data-----------------------------------------
begin:
MsgBoxText dbs 'Win64 Assembly is Great!',0
MsgCaption db "Win64 Iczelion's lesson #2: MessageBox",0
start:
push rbp; <-- not sub rsp,28h
xor ecx,ecx
mov edx,MsgBoxText+IMAGE_BASE
lea r8d,[rdx+MsgBoxText.size]; <-- not mov r8d,offset MsgCaption
xor r9d,r9d; MB_OK
call [MessageBox]
pop rbp
retn
;---------import---------------------------------------
Import_Table:
user32_table:
MessageBox  dq _MessageBox
_import:
dd 0,0,0,user32_dll,user32_table,0
user32_dll db "user32",0,0 ;<-- not "user32.dll"
dw 0
_MessageBox db 0,0,"MessageBoxA"
end_import:
Creator of tiny exe for Win32 Size of exe-file x86 is 97 bytes.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__LoadLibraryA@4:dword
.code
start:  xor ebx,ebx
        push MB_ICONINFORMATION OR MB_SYSTEMMODAL;1040h
        push offset szInfoCap
        push offset namefile
        push ebx
    call _imp__MessageBoxA@16
    mov eax,_imp__LoadLibraryA@4
    sub eax,offset _LoadLibraryA-buffer+ImageBase+size _LoadLibraryA;400023h
    mov _LoadLibraryA,eax
    mov eax,_imp__MessageBoxA@16
    sub eax,offset _MessageBoxA-buffer+ImageBase+size _MessageBoxA;400035h
    mov _MessageBoxA,eax
    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
    push eax    ;hFile для CloseHandle
    push ebx        ;lpOverlapped
        push offset SizeReadWrite   ;lpNumberOfBytesToWrite
    push sizeof_image;a4-buffer ;nNumberOfBytesToWrite=97
    push offset buffer  ;lpBuffer
    push eax    ;hFile for WriteFile
    call _imp__WriteFile@20
    call _imp__CloseHandle@4
QUIT:   retn
ImageBase equ 400000h
buffer  dd 'ZM','EP'
    dw 14Ch ;Machine (Intel 386)
    dw 0    ;NumberOfSection
EntryPoint: xor ebx,ebx ; ebx = 0
    mov edi,offset namedll-buffer+ImageBase
    push edi        ;push offset user32
    jmp short @f
    db 0,0  ;       UNUSED
    dw a4-optheader ;SizeOfOptionalHeader
    dw 103h ;Characteristics (no relocations, executable, 32 bit)
optheader:
    dw 10Bh ;Magic PE32
@@:
    db 0E8h         ;call LoadLibraryA
_LoadLibraryA dd 0
    push ebx        ;push 0
    push edi        ;push offset user32
    push edi        ;push offset user32
    push ebx        ;push 0
    jmp short @f
    db 0,0,0
    dd EntryPoint-buffer
@@:
    db 0E8h         ;call MessageBoxA
_MessageBoxA dd 0
    retn
    dw 0    ;           UNUSED
    dd ImageBase    ;ImageBase
    dd 4    ;SectionAligment
    dd 4    ;FileAligment
namedll db 'user32',0,0 ;       UNUSED
    dd 4    ;MinorSubsystemVersion  UNUSED
    dd 0    ;Win32VersionValue  UNUSED
    dd 68h  ;SizeOfimage
    dd sizeof_image;64h ;SizeOfHeader
    dd 0    ;CheckSum       UNUSED
    db 2    ;Subsystem (Win32 GUI)
a4:
;---------------------------------------------------------------------------
sizeof_image=$-buffer
szInfoCap db "Creator tiny MessageBox",0
namefile db 'tiny97.exe',0
SizeReadWrite dd 0
end start
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 14, 2017, 12:00:08 AM
@Siekmanski
The latest version does not improve.  :(

@Mikl__
:t
Title: Re: Looking for the smallest possible .EXE
Post by: jj2007 on October 14, 2017, 12:38:19 AM
Quote from: Siekmanski on October 13, 2017, 08:22:08 PMI'll have to study, how other exe packers handle the PE collapsing and if they run on all windows versions.

RichMasm is UPXed so that the MB package fits into the 512kB limit. There is also kkrunchy version 7 with better compression than UPX, but it is slow on decompression, so the load time increases a little bit.
126976 RichMasm.exe uncompressed
73728 UPXed
68608 KKrunchy --best
62464 KKrunchy 7 --best
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 14, 2017, 02:09:41 AM
Thanks again,

@Mikl__, can you post the exe for the win32 example? Does it run on all windows versions?

@jochen, I have downloaded the sources for UPX and kkrunchy.  :t

@aw27, downloaded all the examples from phreedom.org http://www.phreedom.org/research/tinype/tinype.zip
Only tiny.c.1024 and tiny.c.45056 work on my Win8.1 machine, the rest return error codes: 5 or c0000018

My main goal is not to produce the smallest executable, but the smallest working PE loader which can be used for an exe packer/cruncher routine.
The clue is to make it work on all windows versions, I need to study this a bit more I'm afraid.  :biggrin:
Title: Re: Looking for the smallest possible .EXE
Post by: Mikl__ on October 14, 2017, 04:42:09 AM
Hi, Siekmanski!
I do not know whether it will work on all 32-bit Windows versions. I checked on WinXP only...
If you create a tiny file creator in my asm-text, then you will have a tiny exe-file that can be run only on your system since it has not import and the address of the MessageBox function corresponds only to your version of the user32.dll
Title: Re: Looking for the smallest possible .EXE
Post by: jj2007 on October 20, 2017, 01:10:04 AM
Quote from: Siekmanski on October 14, 2017, 02:09:41 AM@jochen, I have downloaded the sources for UPX and kkrunchy.  :t

Upx  : 4/18, https://virusscan.jotti.org/en-US/filescanjob/0nvara556y
KK   : 2/17, https://virusscan.jotti.org/en-US/filescanjob/bw265a2sh9
KK7  : 8/17, https://virusscan.jotti.org/en-US/filescanjob/aa1iei3omx

KK7 hits the roof with false positives :P
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 20, 2017, 06:53:08 AM

Virus Killers have become very paranoid....  :biggrin:

Just watched this informative movie about Portable Executable File Format on youtube https://www.youtube.com/watch?v=Vhiip1ZA-2w
Title: Re: Looking for the smallest possible .EXE
Post by: hutch-- on October 20, 2017, 10:01:26 AM
I had a quick look and it looks like decent material but I found the guy hard to listen to and it runs for just over an hour so I might do it later.
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 20, 2017, 10:15:09 AM
This one is also very good, but even harder to listen to than the previous guy.  :biggrin:
https://www.youtube.com/watch?v=3duSgr5b1yc
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 21, 2017, 01:35:13 AM

For people that prefers to read (1st video) (https://media.blackhat.com/bh-us-11/Vuksan/BH_US_11_VuksanPericin_PECOFF_WP.pdf)
Title: Re: Looking for the smallest possible .EXE
Post by: hutch-- on October 21, 2017, 04:00:55 AM
Thanks Jose, this is a good read in this format.
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 21, 2017, 05:22:47 AM
Quote from: hutch-- on October 21, 2017, 04:00:55 AM
Thanks Jose, this is a good read in this format.
YVW, Hutch
Title: Re: Looking for the smallest possible .EXE
Post by: Siekmanski on October 21, 2017, 05:40:49 AM
Thanks Jose.
Title: Re: Looking for the smallest possible .EXE
Post by: Mikl__ on October 21, 2017, 10:35:52 AM
Thanks, Jose! (https://wasm.in/styles/smiles_s/good3.gif)
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 21, 2017, 10:37:37 PM
YVW, Siekmanski and Mikl__
Title: Re: Looking for the smallest possible .EXE
Post by: Mikl__ on October 22, 2017, 01:37:30 AM
Hi, aw27!
I understand English bad, but the google-translator suggested that "YVW" means "You're Very Welcome" - "don't thank us". aw27, you are very modesty!
Title: Re: Looking for the smallest possible .EXE
Post by: LiaoMi on October 22, 2017, 02:26:08 AM
Hi Amigos :P,

how can I describe the import table, for example, for a MessageBoxA, with the technique of binary output it probably will not work, in this case, we need a builder?
Title: Re: Looking for the smallest possible .EXE
Post by: Mikl__ on October 22, 2017, 02:35:18 AM
¡Hola amigo LiaoMi!
MessageBox for 64-bits Windows or 32-bits Windows? FASM x64format binary as 'exe'
include 'win64a.inc'

struc dbs [data]
{
  common
  . db data
  .size = $ - .
}

IMAGE_DOS_SIGNATURE equ 5A4Dh               ;'MZ'
IMAGE_NT_SIGNATURE equ 00004550h        ;'PE',0,0
PROCESSOR_AMD_X8664 equ 8664h
IMAGE_SCN_CNT_CODE equ 00000020h
IMAGE_SCN_MEM_WRITE equ 80000000h
IMAGE_SCN_MEM_READ equ 40000000h
IMAGE_SCN_CNT_INITIALIZED_DATA equ 00000040h
IMAGE_SUBSYSTEM_WINDOWS_GUI equ 2
IMAGE_NT_OPTIONAL_HDR64_MAGIC equ 20Bh
IMAGE_FILE_RELOCS_STRIPPED equ 1
IMAGE_FILE_EXECUTABLE_IMAGE equ 2
IMAGE_BASE equ 0x400000
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h
use64
org 0
;--------DOS-stub-------------------------------
Signature dw IMAGE_DOS_SIGNATURE,0
;-------PE-header--------------------------------------------------
ntHeader dd IMAGE_NT_SIGNATURE;'PE'
;image_header----
Machine dw PROCESSOR_AMD_X8664;CPU Type
Count_of_section dw 0;Number of sections
TimeStump dd 0;Information about the time when the PE-file was compiled
Symbol_table_offset dd 0;A pointer to the size of debug information
Symbol_table_count dd 0;A pointer to the COFF symbol table-PE-format
Size_of_optional_header dw begin-optional_header;The size of optional header
Characteristics dw IMAGE_FILE_RELOCS_STRIPPED or \
IMAGE_FILE_EXECUTABLE_IMAGE;file attributes
;-------Standard field NT
optional_header:
Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC;Status Display File
Linker_version_major_and_minor dw 9;Contain the linker version that created the file.
Size_of_code dd 0;The total size of the code sections
Size_of_init_data dd 0x70;The total size of initialized data
Size_of_uninit_data dd 0;The total size of the uninitialized data
entry_point dd start
base_of_code dd begin
;------Additional fields NT-----------------------------------------------
image_base dq IMAGE_BASE
section_alignment dd 4
file_alignment dd ntHeader
OS_version_major_minor dw 5,2
image_version_major_minor dd 0
subsystem_version_major_minor dw 5,2
Win32_version dd 0
size_of_image dd end_import
size_of_header dd begin
checksum dd 0
subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI
DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
Stack_allocation dq 0x100000
Stack_commit dq 0x1000
Heap_allocation dq 0x100000
Heap_commit dq 0x1000
loader_flag dd 0
number_of_dirs dd (begin-export_RVA_size)/8
export_RVA_size dq 0
import_RVA_size dd _import,end_import-import
;--------code and data-----------------------------------------
begin:
MsgBoxText dbs 'Win64 Assembly is Great!',0
MsgCaption db "Win64 Iczelion's lesson #2: MessageBox",0
start:
push rbp; <-- not sub rsp,28h
xor ecx,ecx
mov edx,MsgBoxText+IMAGE_BASE
lea r8d,[rdx+MsgBoxText.size]; <-- not mov r8d,offset MsgCaption
xor r9d,r9d; MB_OK
call [MessageBox]
pop rbp
retn
;---------import---------------------------------------
Import_Table:
user32_table:
MessageBox  dq _MessageBox
_import:
dd 0,0,0,user32_dll,user32_table,0
user32_dll db "user32",0,0 ;<-- not "user32.dll"
dw 0
_MessageBox db 0,0,"MessageBoxA"
end_import:
Title: Re: Looking for the smallest possible .EXE
Post by: LiaoMi on October 22, 2017, 03:12:07 AM
Quote from: Mikl__ on October 22, 2017, 02:35:18 AM
¡Hola amigo LiaoMi!
MessageBox for 64-bits Windows or 32-bits Windows? FASM x64format binary as 'exe'
include 'win64a.inc'

struc dbs [data]
{
  common
  . db data
  .size = $ - .
}

IMAGE_DOS_SIGNATURE equ 5A4Dh               ;'MZ'
IMAGE_NT_SIGNATURE equ 00004550h        ;'PE',0,0
PROCESSOR_AMD_X8664 equ 8664h
IMAGE_SCN_CNT_CODE equ 00000020h
IMAGE_SCN_MEM_WRITE equ 80000000h
IMAGE_SCN_MEM_READ equ 40000000h
IMAGE_SCN_CNT_INITIALIZED_DATA equ 00000040h
IMAGE_SUBSYSTEM_WINDOWS_GUI equ 2
IMAGE_NT_OPTIONAL_HDR64_MAGIC equ 20Bh
IMAGE_FILE_RELOCS_STRIPPED equ 1
IMAGE_FILE_EXECUTABLE_IMAGE equ 2
IMAGE_BASE equ 0x400000
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h
use64
org 0
;--------DOS-stub-------------------------------
Signature dw IMAGE_DOS_SIGNATURE,0
;-------PE-header--------------------------------------------------
ntHeader dd IMAGE_NT_SIGNATURE;'PE'
;image_header----
Machine dw PROCESSOR_AMD_X8664;CPU Type
Count_of_section dw 0;Number of sections
TimeStump dd 0;Information about the time when the PE-file was compiled
Symbol_table_offset dd 0;A pointer to the size of debug information
Symbol_table_count dd 0;A pointer to the COFF symbol table-PE-format
Size_of_optional_header dw begin-optional_header;The size of optional header
Characteristics dw IMAGE_FILE_RELOCS_STRIPPED or \
IMAGE_FILE_EXECUTABLE_IMAGE;file attributes
;-------Standard field NT
optional_header:
Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC;Status Display File
Linker_version_major_and_minor dw 9;Contain the linker version that created the file.
Size_of_code dd 0;The total size of the code sections
Size_of_init_data dd 0x70;The total size of initialized data
Size_of_uninit_data dd 0;The total size of the uninitialized data
entry_point dd start
base_of_code dd begin
;------Additional fields NT-----------------------------------------------
image_base dq IMAGE_BASE
section_alignment dd 4
file_alignment dd ntHeader
OS_version_major_minor dw 5,2
image_version_major_minor dd 0
subsystem_version_major_minor dw 5,2
Win32_version dd 0
size_of_image dd end_import
size_of_header dd begin
checksum dd 0
subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI
DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
Stack_allocation dq 0x100000
Stack_commit dq 0x1000
Heap_allocation dq 0x100000
Heap_commit dq 0x1000
loader_flag dd 0
number_of_dirs dd (begin-export_RVA_size)/8
export_RVA_size dq 0
import_RVA_size dd _import,end_import-import
;--------code and data-----------------------------------------
begin:
MsgBoxText dbs 'Win64 Assembly is Great!',0
MsgCaption db "Win64 Iczelion's lesson #2: MessageBox",0
start:
push rbp; <-- not sub rsp,28h
xor ecx,ecx
mov edx,MsgBoxText+IMAGE_BASE
lea r8d,[rdx+MsgBoxText.size]; <-- not mov r8d,offset MsgCaption
xor r9d,r9d; MB_OK
call [MessageBox]
pop rbp
retn
;---------import---------------------------------------
Import_Table:
user32_table:
MessageBox  dq _MessageBox
_import:
dd 0,0,0,user32_dll,user32_table,0
user32_dll db "user32",0,0 ;<-- not "user32.dll"
dw 0
_MessageBox db 0,0,"MessageBoxA"
end_import:


Hi Mikl,

Thanks! I did not use fasm, but I think there are built-in tools for compiling this code. I would like to do something similar for uasm or masm, how to make the import table for UASM programs? You need to specify that this is an import variable, like "_import:
dd 0,0,0,user32_dll,user32_table"  ::)
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 22, 2017, 06:42:27 AM
Quote from: Mikl__ on October 22, 2017, 01:37:30 AM
Hi, aw27!
I understand English bad, but the google-translator suggested that "YVW" means "You're Very Welcome" -
When I played Poker online, it was common  to read in the chat:
nh
ty
yvw

:biggrin:
Title: Re: Looking for the smallest possible .EXE
Post by: aw27 on October 22, 2017, 06:49:07 AM
Quote from: LiaoMi on October 22, 2017, 03:12:07 AM
I would like to do something similar for uasm or masm, how to make the import table for UASM programs?

Have a look at this. (http://masm32.com/board/index.php?topic=6601.msg70809#msg70809)

It is a modification of the sample for Win32_5.
I believe there is still something to fix, though.
Title: Re: Looking for the smallest possible .EXE
Post by: LiaoMi on October 22, 2017, 09:46:45 AM
Quote from: aw27 on October 22, 2017, 06:49:07 AM
Quote from: LiaoMi on October 22, 2017, 03:12:07 AM
I would like to do something similar for uasm or masm, how to make the import table for UASM programs?

Have a look at this. (http://masm32.com/board/index.php?topic=6601.msg70809#msg70809)

It is a modification of the sample for Win32_5.
I believe there is still something to fix, though.

Hi aw27,

cool! How could I miss this master post!  :t
Title: Re: Looking for the smallest possible .EXE
Post by: Mikl__ on October 22, 2017, 11:32:07 AM
Hi, LiaoMi!
will look this post Import x64 (https://translate.google.ru/translate?sl=ru&tl=en&js=y&prev=_t&hl=ru&ie=UTF-8&u=https%3A%2F%2Fwasm.in%2Fthreads%2Fimport-x64.32146%2F&edit-text=)
Compilers FASM and NASM allow you to create pure binary files. ML64.exe and LINK.exe will add to the commands and data a standard PE-header and a standard export/ import/ resource/ exception/ security/ fixups/ debug/ description/ MIPS GP/ TLS/ Load config/ bound import/ import table/ delay import/ COM runtime/ reserved sections. Problems can be solved if you use older versions of compiler ml.exe and link.exe that allow you to create COM-files and independently write the owner PE-header and the owner import section as I did in the example above.
Title: Re: Looking for the smallest possible .EXE
Post by: LiaoMi on October 23, 2017, 01:01:53 AM
Quote from: Mikl__ on October 22, 2017, 11:32:07 AM
Hi, LiaoMi!
will look this post Import x64 (https://translate.google.ru/translate?sl=ru&tl=en&js=y&prev=_t&hl=ru&ie=UTF-8&u=https%3A%2F%2Fwasm.in%2Fthreads%2Fimport-x64.32146%2F&edit-text=)
Compilers FASM and NASM allow you to create pure binary files. ML64.exe and LINK.exe will add to the commands and data a standard PE-header and a standard export/ import/ resource/ exception/ security/ fixups/ debug/ description/ MIPS GP/ TLS/ Load config/ bound import/ import table/ delay import/ COM runtime/ reserved sections. Problems can be solved if you use older versions of compiler ml.exe and link.exe that allow you to create COM-files and independently write the owner PE-header and the owner import section as I did in the example above.

Great article! Thank you  :t