Fenetre simple en asm64

Résolu
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019 - 19 févr. 2013 à 13:18
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019 - 21 févr. 2013 à 16:32
bonjour,
j'essai de créer une simple fenêtre en asm 64
mais j'ai quelques soucis ...
Lors de l'appel à GetModuleHandleA,j'ai le message d'erreur 5 ERROR_ACCESS_DENIED (obtenu avec GetLastError),d'ou rien ne marche.

je suis sous windows 7,j'assemble avec ml64
(ml64 -c asm64.asm),je lie avec link
(link asm64.obj user32.lib kernel32.lib /subsystem:windows /Entry:Main)

voici le prog asm64.asm;


;FENETRE SIMPLE ASM 64 BITS
;--------------------------

extrn __imp_GetModuleHandleA:PROC
extrn __imp_ExitProcess:proc
extrn __imp_RegisterClassExA:proc
extrn __imp_CreateWindowExA:proc
extrn __imp_ShowWindow:proc
extrn __imp_PostQuitMessage:proc
extrn __imp_GetMessageA:proc
extrn __imp_TranslateMessage:proc
extrn __imp_DispatchMessageA:proc
extrn __imp_DefWindowProcA:proc
extrn __imp_GetLastError:proc

.const

CW_USEDEFAULT equ 80000000h
WS_OVERLAPPEDWINDOW equ 0CF0000h
WM_DESTROY equ 2

;----------------
.data

WNDCLASSEX STRUCT
cbSize DWORD ?
style DWORD ?
lpfnWndProc QWORD ?
cbClsExtra DWORD ?
cbWndExtra DWORD ?
hInstance QWORD ?
hIcon QWORD ?
hCursor QWORD ?
hbrBackground QWORD ?
lpszMenuName QWORD ?
lpszClassName QWORD ?
hIconSm QWORD ?
WNDCLASSEX ENDS

POINT struct
x DWORD ?
y DWORD ?
POINT ends

MSG STRUCT
hwnd QWORD ?
message DWORD ?
cpl DWORD ? ;pour alignement
wParam QWORD ?
lParam QWORD ?
time DWORD ?
pt POINT <>
cpl1 dword ? ;pour alignement
MSG ENDS

class BYTE "ASM",0
titre BYTE "asm64",0

;-----------------------------------



;-------------------------------------
.data?

HDL_CreateWindowExA QWORD ?
ID_prog QWORD ?
wc WNDCLASSEX <>
mess MSG <>
;-------------------------------------



;---------------------------------
.code

ALIGN 16
poste proc

mov [rsp+8],rcx ;=HWND_CreateWindow
mov [rsp+16],edx ;=uMsg=DWORD
mov [rsp+24],r8 ;=wParam
mov [rsp+32],r9 ;=lParam

sub rsp,56

cmp edx,WM_DESTROY
jne @f

xor ecx,ecx ;uMsg=dword ++
call QWORD PTR __imp_PostQuitMessage
jmp _stop

@@:

mov r9,[rsp+32] ;lParam
mov r8,[rsp+24] ;Wparam
mov edx,[rsp+16] ;uMsg
mov rcx,[rsp+8] ;HWND_CreateWindow
call QWORD PTR __imp_DefWindowProcA

_stop:

add rsp,56
ret

poste endp
;---------------------------------

ALIGN 16
affiche proc ;ID_prog:QWORD

sub rsp,120

mov eax,CW_USEDEFAULT
xor rbx,rbx
mov [rsp+88],RBX ;lpParam
mov [rsp+80],RCX ;ID_prog
mov [rsp+72],rbx ;hMenu=0
mov [rsp+64],rbx ;hWndParent=0

mov DWORD PTR [rsp+56],eax ;height
mov DWORD PTR [rsp+48],eax ;width
mov DWORD PTR [rsp+40],eax ;Y
mov DWORD PTR [rsp+32],eax ;X

mov r9d,WS_OVERLAPPEDWINDOW ;dwStyle
lea r8,titre
lea rdx,class
xor ecx,ecx
call QWORD PTR __imp_CreateWindowExA
mov QWORD PTR HDL_CreateWindowExA,rax

xor ecx,ecx
call QWORD PTR __imp_GetLastError

mov edx,5 ;SW_SHOW
mov rcx,QWORD PTR HDL_CreateWindowExA
call QWORD PTR __imp_ShowWindow


add rsp,120

ret
affiche endp

;--------------------------------------
ALIGN 16
enregistrement proc ;ID_prog:QWORD

sub rsp,40

mov wc.cbSize,sizeof WNDCLASSEX
mov eax,1
or eax,2
mov wc. style,eax
lea rax,poste
mov wc.lpfnWndProc,rax
mov wc.cbClsExtra,0
mov wc.cbWndExtra,0
mov rcx,qword ptr ID_prog
mov wc.hInstance,rcx
mov wc.hIcon,0
mov wc.hCursor,0
mov wc.hbrBackground,5
mov wc.lpszMenuName,0
lea rax,class
mov wc.lpszClassName,rax
mov wc.hIconSm,0
lea rcx,wc
call QWORD PTR __imp_RegisterClassExA

xor ecx,ecx
call QWORD PTR __imp_GetLastError

add rsp,40

ret
enregistrement endp
;--------------------------------------

ALIGN 16
Main proc

sub rsp,40

;obtention HDL du prog
;---------------------

xor ecx,ecx
call QWORD PTR __imp_GetModuleHandleA
mov QWORD PTR ID_prog,rax

xor ecx,ecx
call QWORD PTR __imp_GetLastError

;RegisterClass
;-------------

mov rcx,rax
call enregistrement


;création et affichage
;--------------------

mov rcx,QWORD PTR ID_prog
call affiche

;boucle des messages
;-------------------

_boucle:

xor r9,r9
xor r8,r8
xor rdx,rdx
xor rcx,rcx
lea rcx,mess
call QWORD PTR __imp_GetMessageA

cmp eax,0
jz @f

lea rcx,mess
call QWORD PTR __imp_TranslateMessage

lea rcx,mess
call QWORD PTR __imp_DispatchMessageA
jmp _boucle

;fin
;---

@@:
xor rcx,rcx ;uExitCode=0
call QWORD PTR __imp_ExitProcess


Main endp
;-----------------------------------

end

Qu'est ce qui ne va pas ?

5 réponses

cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
20 févr. 2013 à 08:19
Merci ToutEnMasm et BruNews pour vos réponses.

Et effectivement BruNews,c'est plus pour comprendre le fastcall que je voulais créer une fenêtre en asm 64.
En tout cas,ton prog fonctionne BruNews (par contre bizarrement lors de l'edition de lien,link me dit "unresolve extern symbol" pour __imp_GetStockObject ,alors que j'inclus bien gdi32.lib dans la ligne de commande de link ???,quand je supprime l'appel à __imp_GetStockObject du prog,ça marche).

Merci à tous les deux.
Bonne prog.
3
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
19 févr. 2013 à 14:24
Verifier librairies 64 et non pas 32.
Verifier les call ou utiliser des fichiers de definition (.h traduits).
call QWORD PTR __imp_TranslateMessage
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 févr. 2013 à 20:49
Typiquement c'est la partie de code où l'ASM n'a rien à faire, je pense meme que c'est nuisible.
Code de fenetre et autres séries d'appels API se font en C, faut penser qu'un prog doit de temps en temps subir des modifs.
Si c'est juste pour entrainement OK.

Exemple minimaliste:

-------------------------------

EXTRN __imp_GetModuleHandleA:PROC
EXTRN __imp_DefWindowProcA:PROC
EXTRN __imp_PostQuitMessage:PROC
EXTRN __imp_GetStockObject:PROC
EXTRN __imp_LoadCursorA:PROC
EXTRN __imp_LoadIconA:PROC
EXTRN __imp_RegisterClassExA:PROC
EXTRN __imp_ExitProcess:PROC
EXTRN __imp_CreateWindowExA:PROC
EXTRN __imp_ShowWindow:PROC
EXTRN __imp_TranslateMessage:PROC
EXTRN __imp_DispatchMessageA:PROC
EXTRN __imp_GetMessageA:PROC


_DATA SEGMENT
szappname DB 'bnWnd', 00H

_DATA ENDS

_TEXT SEGMENT

; call API : 96 CreateWindowEx 12 params
; WNDCLASSEX wcl : 80 [rsp]
; TOTAL = 184 ALIGN 8 NON 16
ALIGN 16
myWinMain PROC
sub rsp, 184
xor ecx, ecx
call qword ptr __imp_GetModuleHandleA
mov rdi, rax ; RDI = hinst
lea rbp, [rsp + 96] ; RBP = &wcl
xor ecx, ecx
mov qword ptr[rbp + 24], rax ; wcl.hInstance = hinst
call qword ptr __imp_GetStockObject
mov qword ptr[rbp + 48], rax ; wcl.hbrBackground = GetStockObject(WHITE_BRUSH)
mov edx, 32512
xor ecx, ecx
call qword ptr __imp_LoadCursorA
mov qword ptr[rbp + 40], rax ; wcl.hCursor = LoadCursor(0, IDC_ARROW)
xor ecx, ecx
mov edx, 32512
mov qword ptr[rbp + 16], rcx ; wcl.cbClsExtra = 0
mov qword ptr[rbp + 56], rcx ; wcl.lpszMenuName = 0
mov qword ptr[rbp + 72], rcx ; wcl.hIconSm = 0
call qword ptr __imp_LoadIconA
mov qword ptr[rbp + 32], rax ; wcl.hIcon = LoadIcon(0, IDI_APPLICATION)
mov dword ptr[rbp], 80 ; wcl.cbSize = sizeof(WNDCLASSEX)
lea rax, AppWndProc
lea rsi, szappname
mov dword ptr[rbp + 4], 3 ; wcl.style = CS_HREDRAW | CS_VREDRAW
mov qword ptr[rbp + 8], rax ; wcl.lpfnWndProc = AppWndProc
mov qword ptr[rbp + 64], rsi ; wcl.lpszClassName = szappname
mov rcx, rbp ; &wcl
call qword ptr __imp_RegisterClassExA
test ax, ax
je progEND

; hmain = CreateWindowEx(0, szappname, szappname, WS_OVERLAPPED | WS_SYSMENU | WS_MAXIMIZEBOX,
; cxScr, cyScr, width, height, 0, 0, hinst, 0)
xor ecx, ecx
mov rdx, rsi ; szappname
mov r8, rsi ; szappname
mov r9d, 589824 ; WS_OVERLAPPED | WS_SYSMENU | WS_MAXIMIZEBOX
mov qword ptr[rsp + 80], rdi ; hinst
mov qword ptr[rsp + 72], rcx ; 0
mov qword ptr[rsp + 64], rcx ; 0
mov dword ptr[rsp + 32], 40 ; cxScr
mov dword ptr[rsp + 40], 40 ; cyScr
mov dword ptr[rsp + 48], 400 ; width
mov dword ptr[rsp + 56], 400 ; height
mov qword ptr[rsp + 88], rcx ; DERNIER PARAM = 0
call qword ptr __imp_CreateWindowExA
test rax, rax
je short progEND

; ShowWindow(hmain, SW_NORMAL)
mov edx, 1
mov rcx, rax
call qword ptr __imp_ShowWindow
add rsp, 96 ; RECUP PLACE EN STACK, ON NE LAISSE QUE 88

mov rsi, qword ptr __imp_TranslateMessage
mov rdi, qword ptr __imp_DispatchMessageA
lea rbx, qword ptr[rsp + 32]
mov rbp, qword ptr __imp_GetMessageA
jmp short goGETMSG
fromMSG:
mov rcx, rbx
call rsi ; TranslateMessage(&msg)
lea rcx, qword ptr[rsp + 32]
call rdi ; DispatchMessage(&msg)
goGETMSG:
mov rcx, rbx
xor r9d, r9d
xor r8d, r8d
xor edx, edx
call rbp ; GetMessage(&msg, 0, 0, 0)
test eax, eax
jne short fromMSG

progEND:
xor ecx, ecx
call qword ptr __imp_ExitProcess
myWinMain ENDP


; LRESULT AppWndProc(RCX HWND hwnd, EDX UINT mssg,
; R8 WPARAM wParam, R9 LPARAM lParam)
ALIGN 16
AppWndProc PROC
cmp edx, 2 ; WM_DESTROY
je short wmDESTROY
jmp qword ptr __imp_DefWindowProcA
wmDESTROY:
sub rsp, 40
; PostQuitMessage(0)
xor ecx, ecx
call qword ptr __imp_PostQuitMessage
xor eax, eax
add rsp, 40
ret 0
AppWndProc ENDP

_TEXT ENDS

END
-------------------------------------

Mon build.bat

@set NameEXE=bnWnd.exe
@set DirProj=%~dp0
@set dirOUT=%DirProj%x64\
@set dirVC=E:\_BINVS2012\
@set INCLUDE=E:\_BINVS2012\include
@set LIB=E:\_BINVS2012\lib\amd64
@set Platform=X64

@if not exist %dirOUT% md %dirOUT%
@if exist %dirOUT%%NameEXE% del %dirOUT%%NameEXE%

@set optASM=/c /nologo /Fo"%dirOUT%"
@%dirVC%ml64.exe %optASM% %DirProj%bnWnd.asm
@if errorlevel 1 goto end

@%dirVC%link.exe ^
/ERRORREPORT:PROMPT /OUT:"%dirOUT%%NameEXE%" ^
/INCREMENTAL:NO /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib ^
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ^
odbc32.lib odbccp32.lib /MANIFEST:NO /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF ^
/TLBID:1 /DYNAMICBASE:NO /NXCOMPAT /MACHINE:X64 /entry:myWinMain ^
%dirOUT%bnWnd.obj

:end
@if exist %dirOUT%*.obj del %dirOUT%*.obj
@if exist %dirOUT%*.res del %dirOUT%*.res
---------------------------------------

ciao...
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
20 févr. 2013 à 09:36
Tes struct WNDCLASS et MSG n'ont rien a faire en data. Moins tu en mets plus ton prog est petit. Un offset RSP est accédé par une instruction plus courte qu'une adresse en data.

Doit y avoir le souk dans tes dossiers du platform SDK, pour cela que j'ai fait MON package dans E:\_BINVS2012 et plus jamais d'embrouilles de link ni quoi que ce soit. De plus je peux le mettre sur une clé USB et travailler nimporte ou sans aucun install.

ciao...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
21 févr. 2013 à 16:32
Effectivement BruNews,après avoir "nettoyé" le SDK le call __imp_GetStockObject ne pose plus de problème.
Encore merci
0
Rejoignez-nous