|
 |
Il Processore e il Debugger |
DEBUG 17/22
[45 di 60] |
|
 |
|
Aggiornato
24 settembre 2003 e 17 febbraio 2005 |
 |
|
Comando U - Disassembla il codice di un file eseguibile |
|
 | Ecco la vera bomba! ... il comando U
(UNASSEMBLE, disassembla): di solito ha
senso solo dopo aver specificato il nome (con il comando
N) e caricato in
memoria (con il comando
L) un file
eseguibile, magari dopo aver pulito la memoria chiamata ad ospitarlo
(con il comando
F); se viene dato senza
parametri inizia a tradurre il bytes presenti in
memoria a partire dall'indirizzo CS:0100H; il segmento di default è
ovviamente quello di codice, CS. |
 | E' facile capire la potenza di questo comando:
con esso si possono analizzare le istruzioni di qualunque file eseguibile,
in primis quelli da noi prodotti, in fase di messa a punto o di ricerca
delle rogne... |
 | Ma soprattutto (?!) quelli prodotti da altri
(per esempio dal tuo ben amato autore preferito...); l'ipocrisia è la peggiore delle
essenze umane; i sepolcri imbiancati sono lo sfoggio della peggiore
architettura... |
 | Naturalmente la "traduzione" in
chiaro di un sorgente non è priva di intoppi e malizie: è il prezzo che
bisogna pagare all'esperienza e al colpo d'occhio. |
 |
Il
comando U prova comunque a tradurre in assembly i bytes che trova; se per qualche ragione il programma
contiene tabelle o dati o messaggi (cosa
estremamente probabile..) il risultato sarà del tutto illogico,
cioè verranno mostrate sequenze di istruzioni assurde e
scorrelate. Bisogna quindi saper localizzare le aree dati di
un programma, escludendole dall'indagine con U a beneficio di quella
con il
comando
D. |
 | L'esempio mostra la sequenza di comandi adatti
all'analisi del programma prova.com, usato nel
capitolo 2 per
esercitarci nella sua creazione; nella parte destra è riproposto il codice
sorgente (prova.asm)
mentre a sinistra si può osservare come viene interpretato dal comando U: |
 |
Se fai click sull'icona a
sinistra si apre l'Ambiente Assembly
e puoi
provare DEBUG
on-line.
Scegli
il pulsante di opzione "Aprire il file" o "Esegui
l'applicazione"
e conferma
con
OK. NB: alcuni gestori di protezione (per esempio SP2 di WinXP) non ti consentono questa operazione: in questo caso scrivi c:\arch-lab\bin\sys\assembler.pif direttamente nel campo indirizzo del Browser |
-f 100 1000 00
-n prova.com
-l
-u
11A0:0100 B400 MOV AH,00
11A0:0102 B003 MOV AL,03
11A0:0104 CD10 INT 10
11A0:0106 B400 MOV AH,00
11A0:0108 CD16 INT 16
11A0:010A B44C MOV AH,4C
11A0:010C CD21 INT 21
11A0:010E 0000 ADD [BX+SI],AL |
_prog
SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:_prog,DS:_prog
ORG
0100H
INIZIO: MOV AH,00H ;Pulisci lo
schermo
MOV AL,03H ;(ClearScreen)
INT 10H
;
MOV AH,00H;Aspetta la pressione
INT 16H ;di un tasto
MOV AH,4CH ;Torna al dos
INT 21H
;
_prog ENDS
END INIZIO |
 | Osserviamo con calma il frutto di Unassemble:
 | la pressione di U (ed ogni altra successiva) ha
coinvolto almeno 16 bytes di memoria. |
 | l'indirizzo della locazione di partenza è
CS:0100 (perchè
è la prima volta) ma in generale è sempre dato dal valore corrente di
CS:IP. |
 | i bytes di ciascuna riga visualizzata appartengono ad
una ben precisa istruzione, ad insindacabile giudizio del debugger. |
 | per ogni riga mostrata sono resi disponibili:
 | l'indirizzo logico (CS:IP corrente) del primo dei bytes coinvolti. |
 | la sequenza dei bytes associati all'istruzione
riconosciuta; di essi il primo è certamente un codice operativo. |
 | dopo i bytes che codificano l'istruzione viene
mostrata la loro interpretazione mnemonica: |
 |
Non
dimenticare: in ambiente Debug i numeri mostrati sono
sempre esadecimali anche se non sono dotati della H
finale! |
|
 | in ogni caso il processo continua per tutti i bytes
coinvolti, anche per quelli che non appartengono più al programma
caricato in memoria; ne da dimostrazione l'ultima riga di disassemblato,
nella quale i 2 bytes a 00H sono comunque ritenuti istruzione dal
comando U (un'istruzione del tutto
improbabile e illogica, almeno nel contesto precedente,
ADD
[BX+SI],AL). |
|
 | Ogni volta che si preme U il video si riempie con le
istruzioni corrispondenti ai successivi 16 bytes. |
 | Se desideri
rivedere la traduzione di bytes passati in precedenza è
necessario usare il comando U
con la specifica dell'indirizzo (offset)
desiderato, per esempio U 100, per
tornare a rivedere tutto! |
 | In certi casi (in particolare se si riesce a ridirigere la
videata verso un file....) è conveniente passare 2
parametri, l'indirizzo iniziale e il
numero (espresso con una L seguita dal numero
esadecimale) delle istruzioni da dissassemblare;
per esempio, conoscendo la lunghezza del programma è possibile evitare così la
visualizzazione dell'istruzione fasulla: |
|
-u
100 L7
11A0:0100 B400 MOV AH,00
11A0:0102 B003 MOV AL,03
11A0:0104 CD10 INT 10
11A0:0106 B400 MOV AH,00
11A0:0108 CD16 INT 16
11A0:010A B44C MOV AH,4C
11A0:010C CD21 INT 21 |
 | Naturalmente se si punta l'indirizzo di un bytes
operando (cosa probabile, quando si effettua un'analisi al buio...) il
risultati sono imprevedibili, ma prima o poi il vero programma viene
agganciato; l'esperienza aiuta a trovare il vero indirizzo iniziale; vediamo
il significato di questa osservazione con l'analisi del programma
precedente, puntato male: |
|
-u 101
11A0:0101 00B003CD ADD [BX+SI+CD03],DH
11A0:0105 10B400CD ADC [SI+CD00],DH
11A0:0109 16 PUSH SS
11A0:010A B44C MOV AH,4C
11A0:010C CD21 INT 21
11A0:010E 0000 ADD [BX+SI],AL
11A0:0110 0000 ADD [BX+SI],AL
11A0:0112 0000 ADD [BX+SI],AL |
 | Ci vuole un bel po' per individuare le
istruzioni vere (quelle a 010A e
010C) ma l'assurdità delle prime 3
istruzioni ci ha chiaramente messo sull'avviso che qualcosa è andato
storto! Il buon comando U ci ha comunque provato. |
©
2001-2010 - Studio Tecnico
ing. Giorgio OBER
Tutti i diritti sono riservati
|