Boite de dialogue win32 - affichage du contenu du programme en cours

Description

Bonjour, pour commencer je vous prie d'être indulgents car c'est ma première source asm sur le site. J'ai voulu faire un petit programme utilisant les boites de dialogue pour reconnaitre un texte saisi (une adresse memoire entre 00400000 et 00405F00), d'afficher 256 octets à partir de l'adresse et les caractères ascii correspondant.

Source / Exemple :


;programme à compiler avec Nasm et alink
;
;nasmw -fobj memoire.asm			compile le programme (donne memoire.obj)
;alink -oPE memoire.obj memoire.res		link avec memoire.res (fichier ressource)

extern GetModuleHandleA
import GetModuleHandleA Kernel32.dll
extern ExitProcess
import ExitProcess Kernel32.dll
extern MessageBoxA
import MessageBoxA user32.dll
extern DialogBoxParamA
import DialogBoxParamA user32.dll
extern LoadIconA
import LoadIconA user32.dll
extern SetClassLongA
import SetClassLongA user32.dll
extern GetDlgItem
import GetDlgItem user32.dll
extern GetWindowTextA
import GetWindowTextA user32.dll
extern EndDialog
import EndDialog user32.dll
extern SendMessageA
import SendMessageA user32.dll
extern SetDlgItemTextA
import SetDlgItemTextA user32.dll

segment code public use32 class=CODE

..start:
   	push dword 0
	call [GetModuleHandleA]
	push dword 0			;valeur d'initialisation pour WM_INITDIALOG
	push dword AppDlgProc		;adresse de la procédure de traitement
	push dword 0			;hWndParent
	push dword 101			;identifiant DialogBox
	push eax			;hInstance,	// handle of application instance
	call [DialogBoxParamA]

	push dword 0
	call [ExitProcess]

AppDlgProc:
	mov eax,[esp+8]   		; EAX = message
	mov edx,[esp+12]  		; EDX = wParam
	mov ecx,[esp+4]   		; ECX = hdlg
	mov [hdlg],ecx
	cmp eax,0x111			;WM_COMMAND
	je  short onCOMMAND
	cmp eax, 0x110			;WM_INITDIALOG
	je  short onINITDIALOG
	xor eax,eax
	ret 16

onINITDIALOG:
	lea eax,[esp-44]
	xor edx,edx
	mov dword [eax+4],32512		;IDI_APPLICATION
	mov dword [eax+12],-14 		;GCL_HICON
	mov [eax+8],ecx
	mov [eax],edx
	mov [eax+20],ecx
	mov dword [eax+24],1000		;ID_TXT
	mov [eax+40],edx
	mov esp,eax
	mov dword [eax+36],8		;nb maxi de caractères (sans zéro terminal)
	mov dword [eax+32],0xC5		;EM_SETLIMITTEXT
	call [LoadIconA]
	mov [esp+8],eax
	call [SetClassLongA]
	call [GetDlgItem]
	mov [esp],eax
	mov [htxt],eax
	call [SendMessageA]
	ret 16

onCOMMAND:     ; EDX = wParam
	cmp edx,1			;IDOK
	je  short onOK
	cmp edx,2			;IDCANCEL
	je  short onCANCEL
	ret 16

onCANCEL:
   	push dword 0
	push ecx
	call [EndDialog]
	ret 16

onOK:
	sub esp, 32  			; szbuff[20]+GetWindowText(12)
	mov ecx,[htxt]
	lea eax, [esp+12]  		; adr szbuff(ma chaine)
	mov dword [esp+8],20		; nb maxi de caractères
	mov [esp],ecx			; handle du contrôle
	mov [esp+4],eax			; adresse chaine
	call [GetWindowTextA]		; copie la chaine dans le buffer, la valeur de retour est le nb de caractères
					; esp pointe sur la chaine

;xxxxxx	Procédure de traitement xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

;	convertit la chaine de caractère en une adresse placée dans depart

   	push ebx			;sauvegarde les registres utilisés par W32
	push edi			;	"	"	"	"	"
	xor edi,edi
	mov ecx,4			;4x2 octets à traduire
boucle	mov ah,[esp+2*edi+8]		;esp+8 pointe sur la chaine de caractères
	call asciihexa			;convertit un caractère en sa valeur numérique
	mov al,ah
	shl al,4
	mov ah,[esp+2*edi+9]
	call asciihexa			;est effectué 2 fois par octet
	add al,ah			;digit de poids fort et digit de poids faible
	mov [depart+ecx-1],al
	inc edi
	loop boucle

	mov eax,[depart]
	mov [memcour],eax
	mov edx,Adresse			;adresse de la chaine qui devra être affichée

;	convertit l'adresse en une chaine ascii (fait l'opération inverse de précédemment) caractères 0123456789ABCDEF

cchaine	mov ebx,memcour			;pointe sur memcour (emplacement de l'adresse de la ligne courante)
	xor edi,edi
	mov ecx,4			;met 0 dans edi et 4 dans ecx 
boucle1	mov al,[ebx+edi]		;lit les octets, du plus faible au plus élevé
	call hexascii			;et le convertit en 2 caractères ascii
	mov [edx+2*ecx-2],ax		;met l'octet de poids le plus faible à droite et celui le plus fort à gauche
	inc edi				;passe à l'octet suivant
	loop boucle1			;terminé ?

;	lit 16 octets à partir de la ligne courante, affiche les valeurs et le caractère ascii correspondant (si imprimable)
	mov ebx,[memcour]
	xor edi,edi			;met pointeur à zéro
	mov ecx,16			;par tranche de 16 octets
boucle2	mov al,[ebx+edi]		;lit la valeur pointée à adresse+pointeur

;	vérifie si imprimable
	cmp al,31
	jna nimp			;caractère non imprimable
	mov [edx+edi+80],al
	jmp suite
nimp	mov [edx+edi+80],byte 46	;remplacé par .

suite	;convertit la valeur en chaine ascii
	call hexascii			;convertit en caractères ascii
	mov [edx+4*edi+12],ax		;affiche deux digits par octet
	mov [edx+4*edi+14],word "  "	;2 espaces
	mov al,[ebx+edi]		;caractère ascii correspondant
	inc edi
	loop boucle2			;les 16 octets sont ils terminés ?
	
	mov [edx+8],dword " |  "	;séparateur adresse - valeurs
	mov [edx+76],dword " |  "	;séparateur valeur - ascii
	mov [edx+96],dword 0x0A0D2020	;espace,espace,13,10		fin de la ligne

	add [memcour],dword 16		;16 caractères suivants
	add edx,100			;100 caractères par ligne
	lea eax,[Adresse+1600]		;16 lignes x 100 caractères par ligne
	cmp eax,edx
	jbe affiche			;a-t-on tout affiché ?
	jmp cchaine

affiche	mov [edx],byte 0		;fin de la chaine
	push dword Adresse		;chaine à afficher
	push dword 1001			;id contrôle
	mov eax,[hdlg]			;handle dialogbox
	push eax
	call [SetDlgItemTextA]		;envoie dans le contrôle
	

;	restaure les registres et retourne à la DialogBox

	pop edi
	pop ebx
	add esp,20
	ret 16

asciihexa: 			;convertit le caractère mis dans ah en une valeur hexa   						clc
	sub ah,0x30
	and ah,ah
	jb erreur		;<30h (avant 0)
	cmp ah,0x9
	jbe fin			;numérique
	sub ah,0x7
	cmp ah,0xA
	jb erreur		;39h<<41h (entre 9 et A)
	cmp ah,0xF
	jbe fin			;alpha	(A-F)
	sub ah,0x20
	cmp ah,0xA
	jb erreur		;<61h (entre G et <a)
	cmp ah,0xF
	ja erreur		;>f
fin	ret			;retourne à la procédure de traitement

erreur	push dword 0
	push dword error
	push dword messerr
	push dword 0
	call [MessageBoxA]
	mov edi,[esp+4]		;restaure les registres et retourne à la DialogBox
	mov ebx,[esp+8]
	add esp,32
	ret 16

hexascii:			;convertit la valeur mise dans al en 2 octets al et ah (al=poids fort, ah=poids faible)
	mov ah,al
	shr al,4		;lit les 4 bits de poids fort
	cmp al,0x9		;vérifie si numérique
	jna num1		;si <=9
	add al,"A"-"0"-10	;sinon ajoute 7
num1	and ah,0xf		;lit les 4 bits de poids faible
	cmp ah,0x9
	jna num2
	add ah,"A"-"0"-10
num2	add ax,"00"		;rajoute "0"-0 à chacun des octets
	ret

segment data public use32 class=DATA

htxt    dd 0
hdlg	resd 1
error	db "Erreur",0
messerr	db "Adresse Hexa de 8 caractères requise",0
Titre	db "Examen de la mémoire",0
depart	resd 1	;adresse de base
memcour resd 1	;adresse de la ligne courante (bloc de 16 caractères)
Adresse resb 1601

Conclusion :


Plusieurs routines pourront être récupérées:
conversion ascii/hexa et vice versa
lecture des données saisies
envoi d'un texte dans une EditBox

nb si vous reconnaissez des morceaux de code, je les ai peut-être récupérés ailleurs (il faut parfois procéder ainsi pour voir comment celà marche). J'ai également effectué des transcriptions MASM/NASM

Le code est commenté pour permettre d'aider (peut-être) de plus Newbie que moi

Codes Sources

A voir également

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.