News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Tiny PE in win64

Started by Mikl__, March 24, 2015, 06:59:20 PM

Previous topic - Next topic

Mikl__

format binary as "exe"

IMAGE_DOS_SIGNATURE equ 5A4Dh
IMAGE_NT_SIGNATURE equ 00004550h
PROCESSOR_AMD_X8664 equ 8664h
IMAGE_SCN_CNT_CODE equ 00000020h
IMAGE_SCN_MEM_READ equ 40000000h
IMAGE_SCN_MEM_WRITE equ 80000000h
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_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h

include 'win64a.inc'
org 0
use64

Signature: dq IMAGE_DOS_SIGNATURE,0
ntHeader dd IMAGE_NT_SIGNATURE;'PE'
;image_header--------------------------
.Machine dw PROCESSOR_AMD_X8664
.Count_of_section dw 1;2
.TimeStump dd 0
.Symbol_table_offset dd 0;ntHeader
.Symbol_table_count dd 0
.Size_of_optional_header dw section_table-optional_header
.Characteristics dw 0x20 or IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE
;20h Handle >2Gb addresses
;-------------------------------------
optional_header:
.Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC
.Linker_version_major_and_minor dw 9
.Size_of_code dd 0
.Size_of_init_data dd 0xC0
.Size_of_uninit_data dd 0
.entry_point dd begin
.base_of_code dd ntHeader
.image_base dq 0x140000000
.section_alignment dd 0x10
.file_alignment dd 0x10
.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 (section_table-export_RVA_size)/8
export_RVA_size dq 0
.import_RVA dd import_
.import_size dd end_import-import_
;------------------------------------------------
section_table: dq '.text'
.virtual_size dd 0x55
.virtual_address dd begin
.Physical_size dd end_import-begin
.Physical_offset dd begin
.Relocations dd 0
.Linenumbers dd 0
.Relocations_and_Linenumbers_count dd 0
.Attributes dd IMAGE_SCN_MEM_WRITE or IMAGE_SCN_CNT_CODE;0x80000020
;-------------------------------------------------
begin:
    sub rsp, 28h ; space for 4 arguments + 16byte aligned stack
    xor r9d, r9d ; 4. argument: r9d = uType = 0
    lea r8, [MsgCaption]; 3. argument: r8  = caption
    lea rdx,[MsgBoxText]; 2. argument: edx = window text
    xor ecx, ecx ; 1. argument: rcx = hWnd = NULL
    call [MessageBox]
    add rsp, 28h
    ret
;------------------------------------------------
MsgCaption db "Iczelion's tutorial #2", 0
MsgBoxText db "Win64 Assembly is Great!",0
;------------------------------------------------
Import_Table:
user32_table:
MessageBox  dq _MessageBox
import_:
dd 0,0,0,user32_dll,user32_table
dd 0
user32_dll    db "user32",0,0
dw 0
_MessageBox db 0,0,"MessageBoxA"
end_import:
Size is 345 bytes

Mikl__

I wanted to create a window with a menu for Win64. In  FASM-dialect, it looks like this.
format PE64 GUI 5.0
entry WinMain
include 'win64a.inc'
ZZZ_TEST equ 0
ZZZ_OPEN equ 1
ZZZ_SAVE equ 2
ZZZ_EXIT equ 3

section '.text' code readable writeable executable
  _title TCHAR 'Iczelion Tutorial #8',0 ;name of our window
  _class TCHAR 'FASMWIN64',0;name of class
  wc WNDCLASSEX sizeof.WNDCLASSEX,0,WindowProc,0,0,IMAGE_BASE,0,10005h,COLOR_WINDOW,NULL,_class,NULL

     menu_name  db      'ZZZ_Menu',0
test_msg        db      'You select menu item TEST',0
open_msg        db      'You select menu item OPEN',0
save_msg        db      'You select menu item SAVE',0
menu_handlers dq test_msg, open_msg, save_msg

proc WinMain
IMAGE_BASE = $-rva $
local msg:MSG
          ; +------------------------------+
          ; | registering the window class |
          ; +------------------------------+
          sub rsp,20h
          xor ebx,ebx
          lea ecx,[wc]
          call [RegisterClassEx]
          mov edx,30
          mov ecx,IMAGE_BASE
          call [LoadMenu]
          ; +--------------------------+
          ; | creating the main window |
          ; +--------------------------+
          sub rsp,40h
          xor ecx,ecx
          lea edx,[_class]
          lea r8,[_title]
          mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
          mov [rsp+58h],rbx
          mov qword [rsp+50h],IMAGE_BASE
          mov [rsp+48h],rax
          mov [rsp+40h],rbx
          mov eax,CW_USEDEFAULT
          mov [rsp+38h],rax
          mov [rsp+30h],rax
          mov [rsp+28h],rax
          mov [rsp+20h],rax
          call [CreateWindowEx]
          add rsp,40h
          lea edi,[msg]
          ; +---------------------------+
          ; | entering the message loop |
          ; +---------------------------+
window_message_loop_start:
          mov ecx,edi
          xor edx,edx
          mov r8,rbx
          mov r9,rbx
          call [GetMessage]
          mov ecx,edi
          call [DispatchMessage]
          jmp  window_message_loop_start
endp



          ; +----------------------+
          ; | the window procedure |
          ; +----------------------+
          proc WindowProc,hWnd,uMsg,wParam,lParam
               cmp  edx,WM_COMMAND
               je   wmCOMMAND
               cmp  edx,WM_DESTROY
               je   wmDESTROY
wmDEFAULT:     leave
               jmp [DefWindowProc]
wmDESTROY:     xor ecx,ecx
               call [ExitProcess]
wmCOMMAND:     cmp r8,ZZZ_EXIT
               je   wmDESTROY
show_msg:      sub rsp,20h
               mov r9,rbx;r9=MB_OK
               mov rdx,[menu_handlers+r8*8]
               lea r8,[menu_name]
               call [MessageBox]
               add rsp,20h
wmBYE:         ret
          endp

section '.idata' import data readable writeable
     library   KERNEL32, 'KERNEL32.DLL',\
               USER32,   'USER32.DLL'

     import    KERNEL32,\
               ExitProcess,        'ExitProcess'

     import    USER32,\
               RegisterClassEx,    'RegisterClassExA',\
               CreateWindowEx,     'CreateWindowExA',\
               DefWindowProc,      'DefWindowProcA',\
               LoadMenu,           'LoadMenuA',\
               GetMessage,         'GetMessageA',\
               MessageBox,         'MessageBoxA',\
               DispatchMessage,    'DispatchMessageA'

section '.rsrc' resource data readable
     directory RT_MENU,appMenu

     resource  appMenu,\
               30,LANG_ENGLISH,menuMain

     menu menuMain
          menuitem '&File',0,MFR_POPUP
          menuitem '&Test',ZZZ_TEST,MFT_STRING
          menuitem '&Open',ZZZ_OPEN,MFT_STRING
          menuitem '&Save',ZZZ_SAVE,MFT_STRING
          menuseparator
          menuitem '&Exit',ZZZ_EXIT,MFR_END

          menuitem '&Exit',ZZZ_EXIT,MFR_END
The app compiles and runs.
How to write a similar application in masm-dialect? If possible, show the contents of the bat-file to build such an application by ml64, link and rc...

rrr314159

Hi miki, dunno if this helps,

Have you looked in JWasm samples? Win64_2.asm is a simple window sample, except it doesn't have menus. Menus work the same as with 32-bit; I think, literally no difference. I can put together a menu sample but won't be able to get around to it for a day or so ...

For the "make files" i.e. batch files u could look at  my thread about Invoke Macros, which includes that JWasm sample modified a bit to use my invoke macros. There are two batch files, for ML64 and JWasm, run them with e.g. "makeJ Win64_2" from a command window. Of course you'll have to fix the paths for your set-up. To use without my invoke macros simply change every occurrence of "nvk" to "invoke" - but then u can only compile with JWasm.

If this doesn't help it's because you need the menu commands specifically. I can get around to that, but meanwhile u could just get a 32-bit example and graft it onto JWasm64_2.asm. Ask dedndave, he has plenty of examples no doubt.



I am NaN ;)

Mikl__


rrr314159

Hi Miki!

I like your programming: the shorter the better!
I am NaN ;)

Gunther

Hi Mikl__,

good example. It runs fine under Win7-64. But a few comments would be fine for the newcomers.

Gunther
You have to know the facts before you can distort them.

Mikl__

#6
The text of program, wich received from the boot loader address WinAPI-functions LoadLibraryA and MessageBox, program creates tinyPE64.exe with size 280 bytes. Probably 280 byte is a limit on the size of PE64-files, reduction of even 1 byte making a system message "version is not compatible with the version Windows working on this computer".
  • run program
  • program creates tinyPE64.exe
  • you run tinyPE64.exe
  • enjoy
OPTION DOTNAME
include temphls.inc
include win64.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.code
ImageBase equ 400000h
WinMain proc
          sub esp,9*8
xor ebx,ebx
xor ecx,ecx
mov r9,rbx
mov r8d,offset namefile
mov edx,offset szInfoCap
call MessageBox
mov rax,LoadLibrary
sub eax,offset _LoadLibraryA-buffer+ImageBase+size _LoadLibraryA;=773E0BC0h
mov _LoadLibraryA,eax
mov rax,MessageBox
sub eax,offset _MessageBoxA-buffer+ImageBase+size _MessageBoxA;=77551188h
mov _MessageBoxA,eax
        mov [rsp+30h],rbx ;NULL
mov qword ptr [rsp+28h],FILE_ATTRIBUTE_ARCHIVE
mov qword ptr [rsp+20h],CREATE_ALWAYS
mov r9,rbx
mov r8d,FILE_SHARE_READ or FILE_SHARE_WRITE
mov edx,GENERIC_READ or GENERIC_WRITE
mov ecx,offset namefile
call CreateFile
mov hFile,rax ;hFile для CloseHandle

mov [rsp+20h],rbx        ;lpOverlapped
      mov r9d,offset SizeReadWrite ;lpNumberOfBytesToWrite
mov r8d,sizeof_image ;nNumberOfBytesToWrite=230
mov edx,offset buffer ;lpBuffer
mov ecx,eax ;hFile for WriteFile
call WriteFile
mov rcx,hFile
call CloseHandle
xor ecx,ecx
call ExitProcess
WinMain endp

buffer:
Signature dq IMAGE_DOS_SIGNATURE,0
ntHeader dd IMAGE_NT_SIGNATURE;'PE'
;image_header--------------------------
.Machine dw PROCESSOR_AMD_X8664
.Count_of_section dw 1
.TimeStump dd 0
.Symbol_table_offset dd 0;ntHeader
.Symbol_table_count dd 0
.Size_of_optional_header dw section_table-optional_header
.Characteristics dw 20h or IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE
;20h Handle >2Gb addresses
;-------------------------------------
optional_header:
.Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC
.Linker_version_major_and_minor dw 9
.Size_of_code dd 0
.Size_of_init_data dd 0C0h
.Size_of_uninit_data dd 0
.entry_point dd begin-buffer
.base_of_code dd ntHeader-buffer
.image_base dq ImageBase;0x400000
.section_alignment dd 10h
.file_alignment dd 10h
.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_prog-buffer
.size_of_header dd begin-buffer
.checksum dd 0
.subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI
.DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
.Stack_allocation dq 100000h
.Stack_commit dq 1000h
.Heap_allocation dq 100000h
.Heap_commit dq 1000h
.loader_flag dd 0
.number_of_dirs dd 0
;------------------------------------------------
section_table dd 'xet.','t'
.virtual_size dd 55h
.virtual_address dd begin-buffer
.Physical_size dd end_prog-begin
.Physical_offset dd begin-buffer
.Relocations dd 0
.Linenumbers dd 0
.Relocations_and_Linenumbers_count dd 0
.Attributes dd IMAGE_SCN_MEM_WRITE or IMAGE_SCN_CNT_CODE
;-------------------------------------------------
begin:
    sub esp, 28h ; space for 4 arguments + 8 byte aligned stack
    mov ecx,offset user32_dll-buffer+ImageBase
db 0E8h         ;call LoadLibraryA
_LoadLibraryA dd 0
    xor ecx, ecx ; 1. argument: rcx = hWnd = NULL
    mov r9,rcx ; 4. argument: r9d = uType = MB_OK = 0
    mov r8d,offset MsgCaption-buffer+ImageBase; 3. argument: r8  = caption
    mov edx,offset MsgBoxText-buffer+ImageBase; 2. argument: edx = window text
db 0E8h    ;call MessageBox
_MessageBoxA dd 0
    add esp, 28h
    ret
;------------------------------------------------
user32_dll db "user32",0
MsgCaption      db "Iczelion's tutorial #2",0
MsgBoxText      db "Win64 Assembly is Gr"
end_prog:
sizeof_image=$-buffer
szInfoCap db "Creator tiny MessageBox",0
namefile db 'tinyPE64.exe',0
SizeReadWrite dq 0
hFile dq ?
end

Gunther

Mikl__,

works fine with Win 64-7. But the text of the message box isn't complete.

Gunther
You have to know the facts before you can distort them.

Mikl__

QuoteBut the text of the message box isn't complete.
this is done on purpose, I checked how short file can be. If remove one char yet, then the file not runs

Mikl__

Size of tinyPE64.exe is 268
DOS-stub = 4 bytes, Count of section = 0, section alignment = file alignment = 4OPTION DOTNAME
include temphls.inc
include win64.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.code
ImageBase equ 400000h
PROCESSOR_AMD_X8664_ equ 8664h
WinMain proc
          sub esp,9*8
xor ebx,ebx
xor ecx,ecx
mov r9,rbx
mov r8d,offset namefile
mov edx,offset szInfoCap
call MessageBox
mov rax,LoadLibrary
sub eax,offset _LoadLibraryA-buffer+ImageBase+size _LoadLibraryA;400023h
mov _LoadLibraryA,eax
mov rax,MessageBox
sub eax,offset _MessageBoxA-buffer+ImageBase+size _MessageBoxA;400035h
mov _MessageBoxA,eax
        mov [rsp+30h],rbx ;NULL
mov qword ptr [rsp+28h],FILE_ATTRIBUTE_ARCHIVE
mov qword ptr [rsp+20h],CREATE_ALWAYS
mov r9,rbx
mov r8d,FILE_SHARE_READ or FILE_SHARE_WRITE
mov edx,GENERIC_READ or GENERIC_WRITE
mov ecx,offset namefile
call CreateFile
mov hFile,rax ;hFile для CloseHandle

mov [rsp+20h],rbx        ;lpOverlapped
      mov r9d,offset SizeReadWrite ;lpNumberOfBytesToWrite
mov r8d,sizeof_image;a4-buffer ;nNumberOfBytesToWrite=97
mov edx,offset buffer ;lpBuffer
mov ecx,eax ;hFile для WriteFile
call WriteFile
mov rcx,hFile
call CloseHandle
xor ecx,ecx
call ExitProcess
WinMain endp

buffer:
Signature dw IMAGE_DOS_SIGNATURE,0
ntHeader dd IMAGE_NT_SIGNATURE;'PE'
;image_header--------------------------
.Machine dw PROCESSOR_AMD_X8664_
.Count_of_section dw 0
.TimeStump dd 0
.Symbol_table_offset dd 0
.Symbol_table_count dd 0
.Size_of_optional_header dw begin-optional_header
.Characteristics dw 20h or IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE
;20h Handle >2Gb addresses
;-------------------------------------
optional_header:
.Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC
.Linker_version_major_and_minor dw 9
.Size_of_code dd 0
.Size_of_init_data dd 0
.Size_of_uninit_data dd 0
.entry_point dd begin-buffer
.base_of_code dd ntHeader-buffer
.image_base dq ImageBase
.section_alignment dd 4
.file_alignment dd 4
.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_prog-buffer
.size_of_header dd begin-buffer
.checksum dd 0
.subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI
.DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
.Stack_allocation dq 100000h
.Stack_commit dq 1000h
.Heap_allocation dq 100000h
.Heap_commit dq 1000h
.loader_flag dd 0
.number_of_dirs dd 0
;------------------------------------------------
begin:
    sub esp, 28h ; space for 4 arguments + 16byte aligned stack
    mov ecx,offset user32_dll-buffer+ImageBase
db 0E8h         ;call LoadLibraryA
_LoadLibraryA dd 0
    xor ecx, ecx ; 1. argument: rcx = hWnd = NULL
    mov r9,rcx ; 4. argument: r9d = uType = MB_OK = 0
    mov r8d,offset MsgCaption-buffer+ImageBase; 3. argument: r8  = caption
    mov edx,offset MsgBoxText-buffer+ImageBase; 2. argument: edx = window text
db 0E8h    ;call [MessageBox]
_MessageBoxA dd 0
    add esp, 28h
    ret
;------------------------------------------------
user32_dll db "user32",0
MsgCaption      db "Iczelion's tutorial #2",0
MsgBoxText      db "Win64 Assembly is Great!"
db 36 dup(0)
end_prog:
sizeof_image=$-buffer
szInfoCap db "Creator tiny MessageBox",0
namefile db 'tinyPE64.exe',0
SizeReadWrite dq 0
hFile dq ?
end

Mikl__

#10
a working PE64 with import, size of exe-file is 268 bytes, created in FASM

format binary as 'exe'

IMAGE_DOS_SIGNATURE             equ 5A4Dh
IMAGE_NT_SIGNATURE              equ 00004550h
PROCESSOR_AMD_X8664             equ 8664h
IMAGE_SCN_CNT_CODE              equ 00000020h
IMAGE_SCN_MEM_READ              equ 40000000h
IMAGE_SCN_MEM_WRITE             equ 80000000h
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_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h

include 'win64a.inc'
org 0
use64
IMAGE_BASE = 400000h
Signature:              dw IMAGE_DOS_SIGNATURE,0
ntHeader                dd IMAGE_NT_SIGNATURE;'PE'
;image_header--------------------------
.Machine                dw PROCESSOR_AMD_X8664
.Count_of_section       dw 0;2
.TimeStump              dd 0
.Symbol_table_offset    dd 0;ntHeader
.Symbol_table_count     dd 0
.Size_of_optional_header dw EntryPoint-optional_header
.Characteristics        dw 0x20 or IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE
;20h Handle >2Gb addresses
;-------------------------------------
optional_header:
.Magic_optional_header  dw IMAGE_NT_OPTIONAL_HDR64_MAGIC
.Linker_version_major_and_minor dw 9
.Size_of_code           dd 0
.Size_of_init_data      dd 0;xC0
.Size_of_uninit_data    dd 0
.entry_point            dd EntryPoint
.base_of_code           dd ntHeader
.image_base             dq IMAGE_BASE
.section_alignment      dd 4
.file_alignment         dd 4
.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 EndOfImage
.size_of_header         dd EntryPoint
.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 (EntryPoint-export_RVA_size)/8
export_RVA_size        dq 0
.import_RVA             dd import_
.import_size            dd end_import-import_
;------------------------------------------------
EntryPoint:
   enter 20h,0        ; space for 4 arguments + 16byte aligned stack
   xor ecx, ecx                   ; 1. argument: rcx = hWnd = NULL
   mov r9, rcx                    ; 4. argument: r9d = uType = MB_OK = 0
   mov edx,MsgCaption+IMAGE_BASE  ; 2. argument: edx = window text
   mov r8,rdx                     ; 3. argument: r8  = caption
   call [MessageBox]
   leave
   ret
;------------------------------------------------
MsgCaption      db "Iczelion's tutorial #2a",0
;-------------------------------------------------
Import_Table:
user32_table:
MessageBox  dq _MessageBox
import_:
dd 0,0,0,user32_dll,user32_table
dd 0
user32_dll    db "user32",0,0
dw 0
_MessageBox     db 0,0,"MessageBoxA"
end_import:
times 268-end_import db 0  ;filling up to 268 bytes
EndOfImage: