Zoom Icon

Tutorial 2: La MessageBox

From UIC

Tutorial 2: La MessageBox

Contents


Infos
Author: Iczelion
Email: Traduttore: -NeuRaL_NoiSE
Website: Mirror
Date: 01/01/2001 (dd/mm/yyyy)
Level: Working brain required
Language: Italian Image:Flag_Italian.gif
Comments:


Introduzione

In questo tutorial, creeremo un programma per Windows completamente funzionante che mostra un box con il messaggio "Win32 assembly is great!". Scaricate il file con l'esempio qui.

Preliminari

Windows prepara una grossa quantita' di risorse per i programmi Windows. Al centro di cio' c'e' la Windows API (Application Programming Interface, Interfaccia per la Programmazione di Applicazioni, NdT). La Windows API e' un'immensa collezione di utilissime funzioni contenute in Windows stesso, pronte ad essere usate da qualsiasi programma per Windows. Queste funzioni risiedono in DLL (dynamic-linked libraries, librerie collegate dinamicamente al programma, NdT) come kernel32.dll, user32.dll e gdi32.dll. Kernel32.dll contiene funzioni API relative alla memoria e alla gestione dei processi. User32.dll controlla gli aspetti dell'interfaccia utente del vostro programma.Gdi32.dll e' responsabile per le operazioni grafiche. Oltre alle "principali tre", ci sono altre DLL che il vostro programma puo' usare, ammesso che voi possediate abbastanza informazioni riguardo alla funzione API desiderata. I programmi per Windows si linkano (collegano, NdT) dinamicamente a queste DLL, in altre parole il codice per le funzioni API non e' incluso nell'eseguibile del programma per Windows. Per comunicare al vostro programma dove trovare le funzioni API desiderate al momento dell'esecuzione, dovrete accludere tale informazione nel file eseguibile. L'informazione risiede nelle import libraries (librerie importate, NdT). Dovrete linkare il vostro programma con le corrette import libraries o esso non sara' capace di localizzare le funzioni API. Esistono due tipi di funzioni API: Uno per ANSI e uno per Unicode. Il nome delle funzioni API per ANSI e' postfissato con "A", ad esempio MessageBoxA. Quelle per Unicode sono postfissate con "W" (per Wide Char, credo). Windows 95 supporta nativamente ANSI e l'Unicode Windows NT. Ma la maggior parte delle volte, utilizzerete un file di include che puo' determinare e selezionare le funzioni API appropriate per la vostra piattaforma. Semplicemente riferitevi alla funzione API senza il postfisso.

Contenuto

Presentero' semplicemente lo scheletro del programma qui sotto. Lo riempiremo successivamente.


.386
.model flat, stdcall
.data
.code
Main:
end Main

Ogni programma per Windows deve chiamare una funzione API, ExitProcess, quando vuole uscire a Windows. In quest'ottica, ExitProcess e' equivalente a int 21h, ah=4Ch in DOS.

Ecco il prototipo per la funzione ExitProcess da winbase.h: void WINAPI ExitProcess(UINT uExitCode);

void significa che la funzione non restituisce nessun valore al caller.
WINAPI e' un alias della convenzione di chiamata STDCALL.
UINT e un tipo di dati, "unsigned integer", che e' un valore a 32-bits sotto Win32 (e' un valore a 16-bits sotto Win16)
uExitCode e' il codice a 32-bits di ritorno a Windows.
Questo valore non e' usato da Windows al momento.

Per chiamare ExitProcess da un programma in assembly, dovrete prima dichiarare il function prototype (prototipo di funzione, NdT) per ExitProcess.


.386
.model flat, stdcall
ExitProcess PROTO ,:DWORD
.data
.code
Main:
INVOKE ExitProcess, 0
end Main

Ecco tutto. Il vostro primo programma funzionante per Win32. Salvatelo come msgbox.asm.

Presupponendo che ml.exe e' nella vostra path, assemblate msgbox.asm con:
ml /c /coff /Cp msgbox.asm
/c dice a MASM di assemblare soltanto. Non invoca Link.
/coff dice a MASM di creare un file .obj in formato COFF.
/Cp dice a MASM di conservare le caratteristiche di formattazione (maiuscole/minuscole) degli identificatori (variabili, NdT) dell'utente.

Quindi procedete con link: link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm611\lib msgbox.obj kernel32.lib
/SUBSYSTEM:WINDOWS dice a Link che tipo di eseguibile e' questo programma.
/LIBPATH:<path delle import libraries> dice a Link dove sono le import libraries. Sul mio PC, sono sotto c:\masm611\lib

Adesso avete ottenuto msgbox.exe. Andate avanti, fatelo partire. Scoprirete che non fa niente. Beh, non ci abbiamo ancora inserito niente di interessante. Ma e' senza ombra di dubbio un programma per Windows. E osservate le sue dimensioni! Sul mio PC, il file e' lungo 1,536 bytes.
La linea:
ExitProcess PROTO ,:DWORD
e' un prototipo di funzione.
Voi dichiarate il nome della funzione seguito dalla parola chiave "PROTO", una virgola, e la lista del tipo di dati dei parametri. MASM usa il prototipo di funzione per controllare il numero e il tipo di parametri della funzione. Il miglior posto per i prototipi di funzione e' un file di include. Potete creare un file di include pieno di prototipi di funzioni e strutture di dati frequentemente usati e includerlo all'inizio del vostro programma asm.

Chiamate le funzioni API usando la parola chiave INVOKE:
INVOKE ExitProcess, 0
INVOKE e' in pratica una specie di call specializzata. Essa controlla il numero e il tipo di parametri e li pusha sulla stack seguendo la convenzione di chiamata predefinita (in questo caso, stdcall). Usando INVOKE invece del normale CALL, potete prevenire gli errori della stack derivanti da un passaggio di parametri incorretto. Molto utile. La sintassi e':
INVOKE espressione [,argomenti]
dove espressione e' un'etichetta o il nome di una funzione.

Successivamente, metteremo su una message box. La dichiarazione per questa funzione e':
int WINAPI MessageBoxA(HWND hwnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
dove hwnd e' l'handle della parent window (finestra-genitrice, NdT :)
lpText e' un puntatore al testo che volete mostrare nella client area (l'area a disposizione della message box, NdT)
lpCaption e' un puntatore al titolo della message box
uType specifica l'icona e il numero e tipo dei bottoni della message box

Sotto la piattaforma Win32, HWND, LPCSTR, e UINT sono tutti valori della dimensione di 32 bits.
Modifichiamo msgbox.asm per includere la message box.


.386
.model flat, stdcall
ExitProcess PROTO ,:DWORD
MessageBoxA PROTO ,:DWORD, :DWORD, :DWORD, :DWORD
.data
MsgBoxCaption db "Iczelion Tutorial No.2",0
MsgBoxText db "Win32 Assembly is Great!",0
.const
NULL equ 0
MB_OK equ 0
.code
Main:
INVOKE MessageBoxA, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK
INVOKE ExitProcess, NULL
end Main

Assemblatelo e fatelo partire. (Dovrete includere user32.lib nel parametro di Link, poiche' le informazioni per linkare MessageBoxA risiedono in user32.lib) Vedrete una message box che mostra il testo "Win32 Assembly is Great!".
Diamo un'altra occhiata al codice.
Definiamo due stringhe terminate con zero (zero-terminated) nella sezione .data . Ricordate che tutte le stringhe in Windows devono essere terminate con zero.
Definiamo due costanti nella sezione .const . Utilizziamo le costanti per rendere piu' chiaro il codice.
Osservate i parametri della funzione MessageBoxA. Il primo parametro e' NULL.
Cio' significa che non c'e' nessuna finestra che possiede questa message box.
L'operatore "ADDR" e' usato per passare l'indirizzo dell'etichetta alla funzione.


Note finali

Questi tutorials erano presenti nel sito di RingZero. Li rimettiamo a disposizione a chiunque voglia poter leggerli nella loro traduzione in italiano che fu curata da NeuralNoise.

phobos


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.