Manipulations de la console
Page 1 sur 1
Manipulations de la console
C'est bien beau tout ça !! mais vous m'obligez à avoir toujours une console à l'arrière plan de mon programme et puis la police est trop petite et puis il n'a pas assez de nombre de lignes affichées et puis je veux des lettres en rouge !!
Et en plus cela serait bien si je pouvais saisir du texte et faire une pause dans l'affichage mais en assembleur ça va être très compliqué à écrire !!
Et bien cela est possible et relativement d'une manière simple.
Voyons ce code :
Tout d'abord les constantes windows ont été déportées dans le fichier windowsinc64.inc Nous avons laissé les constantes de couleurs pour vous faciliter la lecture.
Dans la partie .data, nous trouvons les instances des structures COORD, SMALL_RECT et CONSOLE_FONT_INFOEX (les structures elles mêmes sont décrites dans le fichier windowsinc64.inc. En 64 bits, la description de ces structures n'est pas évidente car la documentation windows ne présente que les structures en 32 bits.
Ici ces données vont permettre de gerer les tailles maxi de la console, la position et la taille de la fenêtre d'affichage de la console et les informations concernant la police de caractères.
Comme vous le remarquez, ces instances sont alignées sur des frontières de 8 octets.
Dans la partie code, nous précisons par la directive extern que la procèdure afferreur sera exterieure à ce programme ( et placée dans le fichier routineswin.asm).
Si la console a été allouée par l'option /console, nous appelons la fonction FreeConsole pour desallouée la console crée. Puis dans tous les cas nous créons les consoles par la fonction AllocConsole. Nous récupérerons le handle de la console de sortie par la fonction GetStdHandle et nous le stockons dans la variable hOut.
Nous passons cette donnée et la structure COORD à la fonction SetConsoleScreenBufferSize pour agrandir la console en largeur et en nombre de lignes possible.
Ensuite, nous positionnons la fenêtre de la console sur l'écran de l'ordinateur et sa taille par SetConsoleWindowInfo.
En plus, nous changeons le titre de la console par SetConsoleTitleA et même la position du curseur par SetConsoleCursorPosition. Ici les 2 coordonnées de la position sont forcées directement dans le registre rdx. Normalement il faudrait alimenter une structure COORD et passer le contenu dans le paramètre.
Nous changeons la couleur de la police utilisée par SetConsoleTextAttribute avec le paramètre RED.
Pour changer la taille de la police, nous commençons par récuperer les informations sur la police par la fonction GetCurrentConsoleFontEx qui va alimenter la structure CONSOLE_FONT_INFOEX. Comme cela il ne nous reste plus qu'à modifier les 2 zones de cette structure pour augmenter la taille avant de la passer à la fonction SetCurrentConsoleFontEx.
Il ne nous reste plus qu'à afficher notre message en appelant la fonction WriteConsoleA comme nous l'avons déjà vu.
Et pour terminer, nous appelons la sous procèdure saisieClavier pour faire faire une pause au programme.
Dans cette dernière, nous commençons par récuperer le handle de la console d'entrée par la fonction GetStdHandle mais avec la constante STD_INPUT_HANDLE. Nous lisons la saisie clavier par ReadConsoleA à laquelle nous devons passer 5 paramètres et donc il nous faut aligner correctement la pile. La saisie sera récupérée dans un buffer mais il nous faudra modifier la fin pour remplacer la séquence 0D0A par la fin de chaine standard 0.
La procédure retourne dans le registre rax l'adresse du buffer. Le résultat sera affiché pour controle par un bête MessageBoxA.
Avec tout cela, vous pouvez maitriser les affichages et les saisies dans la console.
Maintenant, il faut utiliser la console pour afficher les outils nécessaires à la recherche des anomalies à savoir le vidage de registres, le vidage d'une zone mémoire puis éventuellement le vidage des piles et du registre des Flags.
REMARQUE : à l'affichage du message en rouge dans la console, vous remarquez que les caractères accentués sont mal affichés. Cela provient du fait que la console utilise la page de code 850 et pas une des pages contenant les codes accentèes ANSI (comme la 1250). J'ai essayé de changer cette page de code par la fonction SetConsoleCP mais rien à faire je n'y suis pas arrivé.
Donc il faut forcer les caractères accentués avec les codes de la page 850 comme par exemple
à 85 , é 82, è 81 ê 88 voir sur https://fr.wikipedia.org/wiki/Page_de_code_850 le reste des codes.
ce qui donne dans notre cas :
Et en plus cela serait bien si je pouvais saisir du texte et faire une pause dans l'affichage mais en assembleur ça va être très compliqué à écrire !!
Et bien cela est possible et relativement d'une manière simple.
Voyons ce code :
- Code:
;************************************
;exemple manipulation console 64 bits
;manipconsole.asm
;************************************
%include "../windowsinc64.inc"
;BLACK equ 0 ; ces constantes ont été deportées dans le fichier ci dessus
;BLUE equ 1 ; mises en commentaires ici pour voir les differentes valeurs
;GREEN equ 2
;CYAN equ 3
;RED equ 4
;PURPLE equ 5
;YELLOW equ 6
;SYSTEM equ 7
;GREY equ 8
;BRIGHTBLUE equ 9
;BRIGHTGREEN equ 10
;BRIGHTCYAN equ 11
;BRIGHTRED equ 12
;BRIGHTPURPLE equ 13
;BRIGHTYELLOW equ 14
;WHITE equ 15
BUFFERSIZE equ 200 ; taille du buffer
;=============================================================================
section .data
;============================================================================
szTitre: db "Mon message",0
szTitreConsole: db 'Ma Console', 0
szMsgFin: db 'Fin programme!', 0
szMsg db "Très bien l'Assembleur Win64!",0
ILGMSG equ $ - szMsg ; donne la longueur du message ci dessus
;structures
coorda: align 8
coord: istruc COORD
at COORD.X, dw 140
at COORD.Y, dw 1000
iend
;instance position et taille de la console
rectconsa: align 8
rectcons:
istruc SMALL_RECT
at SMALL_RECT.Left, dw 0
at SMALL_RECT.Top, dw 0
at SMALL_RECT.Right, dw 100
at SMALL_RECT.Bottom, dw 30
iend
;
cFontExA: align 8 ; contient les information sur la police utilisée
CFontEx: istruc CONSOLE_FONT_INFOEX
iend
ILGCONSINFEX equ $ - CFontEx
;=============================================================================
section .bss
;=============================================================================
;ATTENTION respecter l'alignement des zones
hOut resq 1 ; handle de la console de sortie
iByteLus resq 1
sBuffer resb BUFFERSIZE
;=============================================================================
section .text
;=============================================================================
global Main
extern afferreur
Main:
sub rsp,8h
sub rsp,20h
;allocation des consoles output imput et erreur
;call FreeConsole ; à mettre si vous avez mis l'option /console dans le linker
call AllocConsole
mov r9,__LINE__ - 1
cmp rax,NULL
je .erreur
mov rcx,STD_OUTPUT_HANDLE
call GetStdHandle ; handle de la console de sortie
mov [hOut],rax
;agrandissement de la taille maxi de la console
mov rcx,rax ; handle de la console de sortie
mov rdx,[coord] ; en X la largeur de la console, en Y le nombre de lignes maxi de la console
call SetConsoleScreenBufferSize
mov r9,__LINE__ - 1
cmp rax,NULL
je .erreur
;agrandissement de la console
mov rcx,[hOut] ; handle de la console de sortie
mov rdx,TRUE
mov r8,rectcons ; indique la position et la taille de la fenêtre de la console
call SetConsoleWindowInfo
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
mov rcx,szTitreConsole
call SetConsoleTitleA ; Titre de la console
mov edx,050014h;Y=5 X = 20 : 14h (passage rapide de la position du curseur)
mov rcx,[hOut]
call SetConsoleCursorPosition ; position du curseur
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
mov rdx,RED ;choix de la couleur
mov rcx,[hOut]
call SetConsoleTextAttribute ; changement de la couleur de la police du texte
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
mov dword[CFontEx+CONSOLE_FONT_INFOEX.cbSize],ILGCONSINFEX ; longueur de la structure
mov rcx,[hOut] ; des infos sur la police utilisée
mov rdx,TRUE
mov r8,CFontEx ; passage de la structure en parametre
call GetCurrentConsoleFontEx ; lecture des informations sur la police
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
mov word[CFontEx+CONSOLE_FONT_INFOEX.dwFontSizeY],18 ; forçage de la taille de la police
mov word[CFontEx+CONSOLE_FONT_INFOEX.dwFontSizeX],0 ; il faut mettre à zero cette information.
mov rcx,[hOut]
mov rdx,TRUE
mov r8,CFontEx
call SetCurrentConsoleFontEx ; changement de la taille de la police
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
add rsp,20h ; on rend la place des parametres précédent
sub rsp, 8h ; donc on enleve déjà 8 octets pour preparer la pile
push 0 ; avant le push du parametre qui enleve 8 octets sur la pile
sub rsp, 20h ; puis on enleve les 32 octets pour la place des 4 parametres
; mov qword[rsp+20h],0
lea r9,[sBuffer]
mov r8,ILGMSG
mov rdx,szMsg
mov rcx,[hOut]
call WriteConsoleA ; affichage dans la console
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
call saisieClavier
; et pour finir affichage de la saisie dans un message
mov rcx, 0 ; hWnd = HWND_DESKTOP
mov rdx,sBuffer ; texte a afficher
mov r8,szTitre ; titre de la fenetre
mov r9, MB_OK|MB_ICONINFORMATION ; uType = MB_OK et icone info
call MessageBoxA
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
call FreeConsole;close the console
mov r9,__LINE__ - 1
cmp eax,NULL
je .erreur
mov rax,1 ; pgm OK
jmp .fin
.erreur:
call afferreur
mov rax,0
.fin:
mov rcx,rax
call ExitProcess
;=========================================================
; saisie de données au clavier
;=========================================================
saisieClavier:
sub rsp,8h
sub rsp,20h
mov rcx,STD_INPUT_HANDLE
call GetStdHandle ; recup de handle ( STD_INPUT_HANDLE)
mov r9,__LINE__
cmp eax,NULL
je .erreur
add rsp,20h
sub rsp,8h ; car un seul push
push 0 ; parametre de fin de saisie (ici standard)
sub rsp,20h
mov rcx,rax ; handle fonction précedente
mov rdx,sBuffer ; buffer
mov r8,BUFFERSIZE
mov r9, iByteLus ; nb octets lus
call ReadConsoleA
add rsp,10h ; le push et l'alignement
mov r9,__LINE__ -2
cmp eax,NULL
je .erreur
mov rax,[iByteLus]
sub rax,2
mov byte [sBuffer+rax],0 ; forçage du 00 à la place du 0D final
jmp .fin
.erreur:
call afferreur
.fin:
add rsp,8h
add rsp,20h
mov rax,sBuffer ; retour adresse du buffer
ret
Tout d'abord les constantes windows ont été déportées dans le fichier windowsinc64.inc Nous avons laissé les constantes de couleurs pour vous faciliter la lecture.
Dans la partie .data, nous trouvons les instances des structures COORD, SMALL_RECT et CONSOLE_FONT_INFOEX (les structures elles mêmes sont décrites dans le fichier windowsinc64.inc. En 64 bits, la description de ces structures n'est pas évidente car la documentation windows ne présente que les structures en 32 bits.
Ici ces données vont permettre de gerer les tailles maxi de la console, la position et la taille de la fenêtre d'affichage de la console et les informations concernant la police de caractères.
Comme vous le remarquez, ces instances sont alignées sur des frontières de 8 octets.
Dans la partie code, nous précisons par la directive extern que la procèdure afferreur sera exterieure à ce programme ( et placée dans le fichier routineswin.asm).
Si la console a été allouée par l'option /console, nous appelons la fonction FreeConsole pour desallouée la console crée. Puis dans tous les cas nous créons les consoles par la fonction AllocConsole. Nous récupérerons le handle de la console de sortie par la fonction GetStdHandle et nous le stockons dans la variable hOut.
Nous passons cette donnée et la structure COORD à la fonction SetConsoleScreenBufferSize pour agrandir la console en largeur et en nombre de lignes possible.
Ensuite, nous positionnons la fenêtre de la console sur l'écran de l'ordinateur et sa taille par SetConsoleWindowInfo.
En plus, nous changeons le titre de la console par SetConsoleTitleA et même la position du curseur par SetConsoleCursorPosition. Ici les 2 coordonnées de la position sont forcées directement dans le registre rdx. Normalement il faudrait alimenter une structure COORD et passer le contenu dans le paramètre.
Nous changeons la couleur de la police utilisée par SetConsoleTextAttribute avec le paramètre RED.
Pour changer la taille de la police, nous commençons par récuperer les informations sur la police par la fonction GetCurrentConsoleFontEx qui va alimenter la structure CONSOLE_FONT_INFOEX. Comme cela il ne nous reste plus qu'à modifier les 2 zones de cette structure pour augmenter la taille avant de la passer à la fonction SetCurrentConsoleFontEx.
Il ne nous reste plus qu'à afficher notre message en appelant la fonction WriteConsoleA comme nous l'avons déjà vu.
Et pour terminer, nous appelons la sous procèdure saisieClavier pour faire faire une pause au programme.
Dans cette dernière, nous commençons par récuperer le handle de la console d'entrée par la fonction GetStdHandle mais avec la constante STD_INPUT_HANDLE. Nous lisons la saisie clavier par ReadConsoleA à laquelle nous devons passer 5 paramètres et donc il nous faut aligner correctement la pile. La saisie sera récupérée dans un buffer mais il nous faudra modifier la fin pour remplacer la séquence 0D0A par la fin de chaine standard 0.
La procédure retourne dans le registre rax l'adresse du buffer. Le résultat sera affiché pour controle par un bête MessageBoxA.
Avec tout cela, vous pouvez maitriser les affichages et les saisies dans la console.
Maintenant, il faut utiliser la console pour afficher les outils nécessaires à la recherche des anomalies à savoir le vidage de registres, le vidage d'une zone mémoire puis éventuellement le vidage des piles et du registre des Flags.
REMARQUE : à l'affichage du message en rouge dans la console, vous remarquez que les caractères accentués sont mal affichés. Cela provient du fait que la console utilise la page de code 850 et pas une des pages contenant les codes accentèes ANSI (comme la 1250). J'ai essayé de changer cette page de code par la fonction SetConsoleCP mais rien à faire je n'y suis pas arrivé.
Donc il faut forcer les caractères accentués avec les codes de la page 850 comme par exemple
à 85 , é 82, è 81 ê 88 voir sur https://fr.wikipedia.org/wiki/Page_de_code_850 le reste des codes.
ce qui donne dans notre cas :
- Code:
szMsg db "Tr",81,"s bien l'Assembleur Win64!",0
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
|
|