Newsgroup: it.comp.programmare.win32
Titolo: Disassemblatori

Dal momento che e' una domada frequente, che mi ha anche un poco
stufato, cerco di dare una risposta completa. 
Finalmente potro' poter rispondere a tali post con: "leggiti il thread
dal dei tali!"
I disassemblatori esistono. Sul sito Papero:
http://utenti.tripo.it/papero
c'e' ne uno, e altri ne mettero' dopo averli trovati e provati (solo
se freeware n.d.p.).
N.B.
Praticamente uso assembler e assembly come sinonimi. In teoria
assembly e' il linguaggio, e assembler il compilatore. O e' il
viceversa? Insomma, non me lo ricordo mai.
Un disassemblatore prende un eseguibile e lo "traduce" in assembler.
Questo e' possibile perche' il linguaggio assembler e' *traducibile*
in linguaggio macchina con un rapporto 1 a 1. Anche se non e' proprio
vero ad una istruzione in assembler corrisponde un'instruzione in
linguaggio macchina. Non proprio vero perche' per esempio esistono le
macro.
Un disassemblatore dipende dalla piattaforma di riferimento, perche'
di fatto ogni S.O. ha il suo formato per gli eseguibili. Lo so che il
formato degli eseguibili sulle piattaforme Unix non e' unico e
univoco, ma il discorso non cambia. Se e' vero che ciclo for puo'
essere tradotto nella stessa maniera per tutti i sistemi operativi per
una determinata CPU, p.e., non e' detto che le chiamate a sistema
abbiano la stessa convenzione.
Tanto per *chiarire* NT usa la convenzione Pascal e Linux quella C nel
passaggio dei parametri di una chiamata a funzione di sistema.
Puo' un disassemblatore produrre codice C? Penso di si, pero' non l'ho
mai visto, e non capirei proprio chi potrebbe trarne vantaggio dalla
sua esistenza. Se qualcuno vuole scriverlo pero' puo' farlo :-) 
Esistera' mai un disassemblatore che produce codice C++. Credo proprio
di no. Non vedo su che basi un programma potrebbe scindere una
struttura in formato binario negli oggetti basi.
Esiste un disassemblatore che produce codice Java o VB? Si, anche se
personalmente non li ho mai cercati. In quel caso pero' si ha che fare
con codice P-Code. Cosa ben diversa.
A chi puo' servire un disassemblatore? Al cattivo che vuole craccare
un programma, ma anche a chi vuol semplicemente capire come funziona
qualcosa, p.e., uno non sa cosa fare la notte, e disassembla
msvbvm60.dll [ che porcheria di programma :-) ], o anche a capire cosa
non funziona nel proprio programma.
P.e. a me e' capitato un mio programma che in ufficio funzionava
benissimo, e in produzione a volte andava in crash (in modo
apperentemetne casuale). Il programma era scritto un VB.
L'informazione "Il programma ha eseguito una istruzione non valida
all'indirizzo XXX", insieme al disassemblato che mi diceva cosa ci
fosse a quell'indirizzo mi e' servito moltissimo.
Per la cronaca l'errore era in una mia dll (comunicazione seriale
n.d.p.), e una volta capito il punto nel codice sorgente, ci ho messo
una settimana per capire come potesse fallire
Quali conoscenze bisogna avere per usare un listato di un
disassemblato? Non tante. Io ho imparato quelle pochissime nozioni di
assembler che ho disassemblando il mio codice. Sorgenti da una parte,
e asm dall'altra. Sapere come ottimizza il proprio compilatore puo'
sempre far comodo.
Quale disassemblatore usare? Intanto non bisogna fidarsi dei nomi, per
esempio in giro c'e' un programma dal nome altisonante di HackMan. Non
credo che nessun hacker usi questo programma. Come disassemblatore fa
pieta', pero' e' l'unico editor esadecimale freeware che ho! Nel VC++
e credo anche nell'SDK e' presente un disassemblatore, ma il suo
output fa abbastanza schifo. Da notare che, finalmente, nel VC ++ 6.0
e' possibile produrre oltre che il file target, anche la versione in
asm. Personalmente sono affezionato ad un vecchio programma dos
pedump, che chissa' perche' ho trovato con il nome cambiato in
disassem. Freeware naturalmente. Ne sto provando altri, trovati da
poco, pero' credo che rimmarro al vecchio programma dos.
Dove posso trovare i sorgenti un disassemblatore? Sara' incredibile,
ma ho i sorgenti di un solo disassemblatore, e il suo codice e'
fornito dalla ... dalla Microsoft !! Gia', perche' il dr. Watson e' un
dissassemblatore. Il codice e' tra gli esempi dell'SDK. 
Non so per quale motivo i suoi sorgenti sono abbastanza ignorati
(almeno non l'ho mai visto citato).
Come dovrebbe essere fatto il disassemblatore ideale? Partendo dal
Dr.Watson si potrebbe fare di meglio. Intanto deve potere dissamblare
un programma su file, o in memoria. Naturalmente deve poterlo
disassemblarlo al volo come fa Dr.Watson, ma dovrebbe dare il dump
anche dello stack e della memoria usata, oltre che dei soliti valori
dei registri. Insomma, anche se a prezzo di sudore, con il dump di un
file crashato dovrebbe permettermi di dire "Ho avuto un crash in un
progamma compilato in versione release, ma ti posso dire lo stesso che
il programma si e' fermato esattamente in questo punto, e la variabile
che nel mio codice sorgente chiamo i, e che si trova nello stack alla
posizione X, valeva Z al momento del crash". 
Naturalmente dovrebbe poter estrarre qualsiasi risorsa binaria
infilata dentro un file, e se anzi ci fosse collegato anche un buon
editor binario, e un editor di risorse saremmo a cavallo :-)
Ci capissi qualcosa lo scriverei io. In realta' c'e' gia' tutto,
freeware naturalmente, anche se pero' e' sparso tra piu' programmi.
Cosa posso fare per difendermi dai cattivi che mi disassemblano il
programma? Usare la tecnica polimorfica come fanno certi virus, il
programma e' criptato, e si decripta al volo al momento della
*partenza*.
Come posso fare per aggirare le protezioni di chi scrive programmi
automodificanti? Facendo il dump del programma in memoria (pero'
bisogna avere diritti amministrativi per fare una cosa simile).
Come posso fare per difendermi da chi mi fa il dump dopo che il loader
del S.O. mi ha caricato in memoria? Forse con un programma in P-Code
completamente criptato. Non so di nessuno che usa una tecnica simile
(schifosamente lenta scommetto).
Come posso fare per aggirare le protezioni di chi usa P-Code criptato?
Scrivere una VM ad hoc, oppure usare codice Open Source di altri.
Quello che usava P-Code criptato era sicuramente un paranoico.
Considerazioni personali.
In ditta io uso il VC++. Sia perche' avendo un abbonamento Universal a
MSDN non mi costa niente, sia perche' lo trovo comodo. Lo so che GCC
e' piu' standard, ma per quel che mi serve a me va piu' che bene. Se
mi serve avere il disassemblato io uso sia quello prodotto dal
compilatore che quello fornito da pedump. Quello del VC++ e' compatto,
ma per questo anche incompleto.
Tra gli assemblatori gratis, ce ne sono almeno tre *interessanti*. GAS
(tool GNU), NASM (altro gruppo di indipendenti) e MASM (Microsoft).
Personalmente non conosco l'assembler, quindi non li uso :-)
++++
Aggiunte e commenti sono benvenuti.
-------------------------------------------------------
Se c'e' rimedio, perche' preoccuparsi?
Se non c'e' rimedio, perche' preoccuparsi?

On Sat, 30 Oct 1999 09:24:44 GMT, 
quack....@tin.it
 (Davide Quack)
wrote:
Bel post!
Solo un paio di precisazioni....
Un "compilatore" per assembler (io uso semplicemente assembler
anche se forse il nome del linguaggio e` assembly) viene solitamente
indicato come assemblatore, perche` a differenza di un linguaggio
a piu` alto livello di astrazione (C, C++, Pascal...) la corrispondenza
tra istruzioni e codice generato e` 1 a 1 (le macro non contano perche`
vengono espanse prima).
Infine per quanto riguarda i decompilatori, e` abbastanza difficile
realizzarli per tutti i linguaggi, perche` nellla compilazione c'e`
perdita di informazioni (ad esempio i nomi delle variabili) ma 
soprattutto perche` compilatori diversi generano codice diverso,
e poi ci sono di mezzo le ottimizzazioni...
In parte si puo` rimediare se si dispone di informazioni di debug
(e` il meccanismo utilizzato dai debugger), ma informazioni di debug ed
il solo codice eseguibile non sono comunque sufficienti per rigenerare
il codice sorgente.
Paolo
-----------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------

perdita di informazioni
Appunto. Pero' con linguaggi che ormai ammettono al loro interno una
forma di metalinguaggio cio' e' (per me) virtualmente impossibile.
Prendiamo una classe che manipola gli array. Il decompilatore su che
basi puo' determinare se quello era codice specifico, o se proveniva
da un template?
