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
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...
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 (http://masm32.com/board/index.php?topic=3988.0), 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.
Hi, rrr314159!
Hi Miki!
I like your programming: the shorter the better!
Hi Mikl__,
good example. It runs fine under Win7-64. But a few comments would be fine for the newcomers.
Gunther
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
Mikl__,
works fine with Win 64-7. But the text of the message box isn't complete.
Gunther
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
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
a working PE64 with import, size of exe-file is 268 bytes, created in FASM
(http://www.cyberforum.ru/attachments/539842d1433753527)
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: