I formati com ed exe
Ne abbiamo già parlato nell'ultima edizione, come sapete non basta di certo cambiare l'estensiona da .com ad .exe per convertire i due formati.Sono due tipi di file diversi, l'exe ed il com header li abbiamo già conosciuti.Ora però voglio approfondire tutto ciò usando ovviamente l'assembly.Iniziamo subito con il lavoro.
Per prima cosa diamo uno sguardo a come convertire files .com in files .exe
Le cose che non c'interessano, come il com header o un logo oppure qualsiasi altra cosa che non è importante le possiamo direttamente lasciar via.Progettato per un com file, le cose stanno più o meno così.
pusha ; salviamo i registri
xor ah,ah ; azzera il registro
mov al,ds:80h
cmp ax,6
jl errore
;Dovrebbe essere tutto chiaro, con il compare vediamo se i caratteri sono più ;oppure meno di 5, dopodichè continuremo oppure faremo una piccola visita al ;label "errore".
mov di,ax
mov word ptr ds:(di + 81h),"$" * 256 ; i nostri caratteri
popa ;ripristina i registri
errore: popa
mov al,-1
ret ; ritorna al codice originale
cmp al,-1
je messaggio ; qui si potrebbe continuare con "messaggio", dopo aver controllato che non ci sia stato alcun input , magari si potrebbero far visualizzare le possibili opzioni oppure un piccolo aiuto per come si usa il programma.
Ora bisogno procedere all'apertura del file, useremo il metodo che ormai conosciamo benissimo
mov dx,82h
mov ax,3d00h
int 21h
Ecco che abbiamo aperto il file.Possiamo aggiungerci anche un messaggio di errore, in caso che ci sia stato qualche problema aprendo il file.
mov Nome_file,ax
Qui salviamo il nome del file aperto.Non dimenticate di aggiungere il valore di Nome_file nella sezione delle variabili, come per esempio Nome_file dw ?.
Invece se il file non l'ha trovato proprio basta un semplicissimo jump al messaggio di errore
je non_esiste
non_esiste: lea dx,messaggio
mov ah,9h
int 21h
messaggio db " File non trovato"
Se ci è stato qualche errore aprendo il file ricordatevi però di richiudere il file prima di uscire del tutto dal programma.
mov bx, Nome_file ;carichiamo il nome del file
mov ah,3eh ; e lo chiudiamo
int 21h
Ormai lo sapete, dopodichè potete fare un jump al codice che ritorna al DOS usando la funzione 4c00h, oppure ci potete prima mettere anche un messaggio di come lo si usa il programma, gli opzioni possibili ecc.
Altrimenti continuiamo a scrivere nel nostro com il Header del file exe, che abbiamo già conosciuto nella zine #2.
mov cx,32 ; la quantità di bytes da scrivere
mov ah,40h ;la funzione per scrivere tutto ciò
mov bx, Nome_file ; il file sul quale faremo i cambiamenti
lea dx, Header ; qui carichiamo tutti i dati necessari per il nostro header
int 21h ; esegue tutto quanto.Anche qui ovviamente è possibile inserire un piccolo
messaggio di errore.
Ora vediamo un pò com'è fatto l'header, cioè tutti i dati necessari caricati con
lea dx, header.
Header: db "MZ" ; questo non vi è nuovo, la signatura di ogni file exe
dw 0,0 ; ora dobbiamo settare i bytes dell'ultima pagina
dw 0 ; lo stesso vale per le relocations
dw 2 ; adesso definiamo la grandezza del nostro header
dw 1000h,-1 ; la memoria minima e massima possibile
dw 0fff0h,0fffeh ; Qui settiamo i valori per il stack segment ed il stack pointer
dw 0 ; la variabile del checksum
dw 100h,0fff0h ; i valori dell'instruction pointer ed il code segment
dw 1ch ; ecco che troviamo l'indirizzo alla relocation table
dw 0,0,0 ; ed infine il numero dell'overlay
M continuiamo con il codice.
mov ah,3fh ; funzione per leggere da file
mov bx, Nome_file ;il nome del file da cui leggere
mov cx,63000 ; la quantità di bytes da leggere
lea dx, word_ ; qui carichiamo la word inzilizzata (word dw ?) dove caricare i dati
itn 21h ;esegue tutto questo
or ax,ax ; controlliamo se il valore di ax corrisponde a "0"
jz fine_header ; in questo caso possiamo procedere con la conclusione del head.
add grandezza,ax ; altrimenti iniziamo una specie di loop finchè non abbiamo
raggiunto il valore desiderato.Qui carichiamo la grandezza ( grandezza dw 0)
mov cx,ax ; carica il valore in cx
mov ah,40h ;e ci scriviamo sopra
mov bx, Nome_file ;usando ovviamente sempre il nostro file
lea dx, word_ ;ancora la nostra word
int 21h; ecco che esguiamo il tutto
jmp ; e qui ritorniamo al codice che inizia a leggere il file con la funzione 3fh.Vale
sempre la stessa cosa, cioè in caso di errore si può sempre inserire un messaggio.
Se tutto ciò invece è andato come dovrebbe, continuiamo con la conclusione, cioè fine_header
fine_header:add grandezza,32 ; qui aggiungiamo 32 alla nostra grandezza
xor cx,cx ;azzera il registro cx
mov dx,2 ; dove andremo a puntare con il pointer
mov ax,4200h ; ecco che lo facciamo
mov bx, Nome_file ; sul nostro file
int 21h ; fatto
mov ax, grandezza ; carichiamo di nuovo la grandezza
and ax,511 ; "and" non dovrebbe essere sconosciuto per quello che fa
mov word_,ax ; e carichiamo tutto il valore di ax nella nostra word
mov ax, grandezza ; tutto chiaro
mov cl,9 ; il valore 9 in cl
shr ax,cl ;"shiftiamo" tutto quanto
inc ax ; incrementa ax di 1
mov (word_ + 2 ),ax ; ricopiamo ora il valore di ax
mov cx,4 ; quantità di bytes
mov ah,40h ; e li scriviamo
mov bx, Nome_file ; sempre il nostro file
lea dx, word_ ;caricato nella word
int 21h ; eseguito
Ecco fatto.A questo punto direi che sarebbe opportuno ad inserire forse un piccolo messaggio che il file exe è stato creato, con successo o meno, visto che siamo proprio alla fine.
Adesso invece vediamo come si fa a convertire un fil exe in un file com.Come struttura del programma va benissimo quello di su, solamente dobbiamo far attenzione che questa volta si tratta di un exe.Quindi prima di compiere qualche cambiamento al file, esamineremo esattamente il header del file, così siamo sicuri che si tratti sempre di un file exe originale.
Allora, l'inizio è esattamente lo stesso,però ora implementiamo prima il nostro check ,se si tratta veramente di un file exe.
mov di, offset identificazione ; qui carichiamo la nostra lista tramite la quale
decideremo se si tratta di un file exe valido o meno, usando i seguenti parametri.
identificazione db "MZ" ; questo dovrebbe essere chiaro che identifica l'exe
Ed ecco che continuiamo con qualche messaggio di errore
db " Signatura exe non trovata" ; in caso non ci sia l' MZ
db 20 ; l'indirizzo
dw 0100h ; il nostro valore
db "Instruction pointer non valido" ; IP che non va bene
db 22 ; ora diamo uno sguardo all'offset 22
dw 0fff0h ; controlliamo usando questo valore
db " Code segment non valido" ;se ci sono problemi con il cs
db 6 ; sempre l'indirizzo
dw 0 ; il valore
db " Sono presenti relocations" ; in caso ci fossero delle relocations
db 14 ; offset 14
dw 0fff0h ; il valore usato
db " Errori nel stack segment" ; qualcosa non va con l'ss
db 16 ; ormai lo sapete, l'indirizzo
dw 0fffeh ; anche qui non è cambiato molto nel valore
db " Errore nel stack pointer " ; vuol dire che ci sarà stato qualche problema con
il stack pointer
db 26 ; offset 26
dw 0 ; il valore
db " Sono presenti overlays" ; se sono stati trovati overlays.
Bene, credo che ora dovreste essere in grado di convertire files com ed exe come volete voi.