Fenetre win64

Soyez le premier à donner votre avis sur cette source.

Snippet vu 2 244 fois - Téléchargée 16 fois

Contenu du snippet

creation d'une simple fenêtre pour montrer
l'utilisation de la convention fastcall de
l'asm 64 bits.
Un grand merci à BruNews pour son aide.

à assembler avec ml64
à lier avec link et les lib 64 bits (cf sdk lib/amd64)

Source / Exemple :


;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

.data

HDL_CreateWindowExA	QWORD		?
ID_prog			QWORD		?
IDclass byte "WNDasm64",0

.const

CW_USEDEFAULT		equ	80000000h
WS_OVERLAPPEDWINDOW	equ	0CF0000h
WM_DESTROY		equ 	2

.code

ALIGN 16

Main proc

;détermination de la pile
;------------------------
;en fastcall,c'est la fonction appelante qui
;doit préparer la pile pour la fonction appelée

;appel de __imp_RegisterClassExA;
;au mieux d'utiliser wc	WNDCLASSEX <> des .data
;on réserve directement l'espace nécessaire pour wc
;soit 80 octets en tout=10 paquets de 8 octets d'ou
;alignement ok en QWORDS

;appel de __imp_CreateWindowExA;
;on a besoin de 12 paramètres,aligné sur 8 cela
;fait 12*8=96 octets

;appel des API pour le traitement des messages
;struct MSG=48 octets

;on doit donc réserver sur la pile 80+96+48=224 octets

;on doit rajouter 8 octets pour l'adresse de retour

;on arrive donc à 224+8=232 octets,d'ou;

sub rsp,232

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

;en fastcall,l'ordre des registres "pushés" est RCX,RDX,R8,R9

xor ecx,ecx	;lpModuleName=0,d'ou GetModuleHandleA retourne HDL du prog
call QWORD PTR __imp_GetModuleHandleA
mov ID_prog,rax

;enregistrement de la classe
;---------------------------

mov DWORD PTR[rsp+96],80	;wc.cbsize
mov eax,1
or eax,2
mov DWORD PTR[rsp+100],eax	;wc.style
lea rax,poste
mov QWORD PTR[rsp+104],rax	;wc.lpfnWndProc
xor rax,rax
mov DWORD PTR[rsp+112],eax	;wc.cbClsExtra
mov DWORD PTR[rsp+116],eax	;wc.cbWndExtra
mov rcx,ID_prog
mov QWORD PTR[rsp+120],rcx	;wc.hInstance
mov QWORD PTR[rsp+128],rax	;wc.hIcon
mov QWORD PTR[rsp+136],rax	;wc.hCursor
mov QWORD PTR[rsp+144],5	;wc.hbrBackground
mov QWORD PTR[rsp+152],rax	;wc.lpszMenuName
lea rsi,IDclass
mov QWORD PTR[rsp+160],rsi	;wc.lpclassName
mov QWORD PTR[rsp+168],rax	;wc.hIconSM

lea rax,[rsp+96]
mov rcx,rax
call QWORD PTR __imp_RegisterClassExA

;création de la fenètre
;----------------------

xor rax,rax
mov QWORD PTR[rsp+88],rax	;lparam
mov rcx,ID_prog
mov QWORD PTR[rsp+80],rcx	;hInstance
mov QWORD PTR[rsp+72],rax	;hMenu
mov QWORD PTR[rsp+64],rax	;hWndParent
mov DWORD PTR[rsp+56],300	;nHeight
mov DWORD PTR[rsp+48],300	;nWidth
mov DWORD PTR[rsp+40],20	;y
mov DWORD PTR[rsp+32],30	;x
mov r9d,WS_OVERLAPPEDWINDOW	;dwStyle
lea rax,IDclass
mov r8,rax			;lpWindowName
mov rdx,rax			;lpClassName
xor rcx,rcx			;dwExstyle

call QWORD PTR __imp_CreateWindowExA
mov HDL_CreateWindowExA,rax

;affichage de la fenêtre
;------------------------

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

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

_boucle:

xor r9,r9
xor r8,r8
xor rdx,rdx
xor rcx,rcx
lea rcx,[rsp+176]
call QWORD PTR __imp_GetMessageA

cmp eax,0
jz @f

lea rcx,[rsp+176]
call QWORD PTR __imp_TranslateMessage

lea rcx,[rsp+176]
call QWORD PTR __imp_DispatchMessageA
jmp _boucle

;fin
;---

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

Main endp

ALIGN 16
poste proc

cmp edx,WM_DESTROY
jne @f	

;réponse à WM_DESTROY;

	sub rsp,40	;les 4 registres QWORD + adresse retour
			;=5 QWORDS=5*8=40 octets
	
	xor ecx,ecx	
	call QWORD PTR __imp_PostQuitMessage
	add rsp,40	;nettoyage de la pile
	jmp _stop

@@:

;traitement des autres messages

	
	jmp QWORD PTR __imp_DefWindowProcA
	
_stop:
	ret

poste endp

end

A voir également

Ajouter un commentaire

Commentaires

cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019

Autant pour moi...
j'étais mal aligné.
ça passe nickel.

Merci BruNews.
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
18
Je viens de tester, en place du JMP:
sub rsp, 40
call qword ptr __imp_DefWindowProcA
add rsp, 40
ret 0

passe très bien.
Bien entendu c'est ultra contre productif.
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
18
Tu as bien aligné RSP sur 8 et NON 16 avant appel ?
cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019

Bonjour BruNews,

Pourquoi lorsque on appel __imp_DefWindowProcA par un call
et pas par un jmp ça plante ?
Normalement,les 4 paramètres de DefWindowProc doivent être
stockés par CreateWindowEx dans RCX,RDX,R8,R9 d'ou un call
devrait passer.
est ce un problème d'adresse de retour ?
DefWindowProc version 64 bits n'a pas besoin de paramètres ?
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
18
jmp _stop

JAMAIS de saut vers un 'RET xxx', tu RET directement.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.