- Messaggi
- 2,332
- Reazioni
- 1,928
- Punteggio
- 134
MCA - Machine Code Analyzer
Vi avevo già parlato di un mio progetto qualche mese fa. MCA è parte di quel progetto. Si tratta di una parte così importante che ho preferito "scorporare" e pubblicare separatamente, aggiungendo un pò di cose che mi ero perso. Ma andiamo con ordine.
Il compito di MCA è decodificare il codice macchina che ha come target le architetture x86 e x64.
Le architetture CISC hanno un gran numero di opcodes, e la lunghezza delle istruzioni non è fissa (varia da 1 a 15bytes). Quindi se si ha bisogno di decodifcare il codice macchina di queste architetture l'unica soluzione è decodificare ogni byte, per capire di quale operazione si tratta.
La struttura di un'istruzione è mostrata di seguito:
A questi vanno aggiunti anche alcuni altri prefissi, come REX e VEX, che si trovano sempre prima dell'opcode. Gli opcode possono essere a 1byte, 2byte o 3byte (in due forme differenti).
Per mostrarvi il funzionamento di MCA, riporto un esempio preso dal README del progetto:
Decodificando il file binario che contiene quel codice macchina e stampando ogni istruzioni riga per riga (così da riuscire a leggerla meglio), MCA decodifica:
Come si può osservare il codice è quello che si vede sopra (avevo disassemblato un'istruzione in meno, mi sono perso quindi il JMP...). MCA mantiene un array di 15bytes (opzionale) con i byte dell'istruzione; la stampa qui sopra avviene proprio utilizzando quell'array.
Ovviamente mantiene tutte le altre informazioni che riguardano l'istruzione. Ne ho scelte 2 tra quelle mostrate sopra:
Queste sono le informazioni raccolte da MCA sulle due istruzioni:
Attualmente è ancora in versione Beta, e necessita quindi di qualche "prova sul campo".
Manca il supporto per il prefisso EVEX (AVX-512), 3DNow! e XOP (di AMD). Attualmente non è presente una trasformazione in mnemonici, ma diciamo che è tra le cose che vorrei implementare in futuro, dopo al supporto per EVEX.
Per tutte le altre info e il codice vi rimando al README di MCA: https://github.com/DispatchCode/Machine-Code-Analyzer
Vi avevo già parlato di un mio progetto qualche mese fa. MCA è parte di quel progetto. Si tratta di una parte così importante che ho preferito "scorporare" e pubblicare separatamente, aggiungendo un pò di cose che mi ero perso. Ma andiamo con ordine.
Il compito di MCA è decodificare il codice macchina che ha come target le architetture x86 e x64.
Le architetture CISC hanno un gran numero di opcodes, e la lunghezza delle istruzioni non è fissa (varia da 1 a 15bytes). Quindi se si ha bisogno di decodifcare il codice macchina di queste architetture l'unica soluzione è decodificare ogni byte, per capire di quale operazione si tratta.
La struttura di un'istruzione è mostrata di seguito:
Codice:
// con [ ] vengono indicati i campi opzionali
[prefix] opcode [modrm] [sib] [disp] [imm]
A questi vanno aggiunti anche alcuni altri prefissi, come REX e VEX, che si trovano sempre prima dell'opcode. Gli opcode possono essere a 1byte, 2byte o 3byte (in due forme differenti).
Per mostrarvi il funzionamento di MCA, riporto un esempio preso dal README del progetto:
Codice:
008910BC |. C785 68FFFFFF 00000000 MOV DWORD PTR SS:[LOCAL.38],0
008910C6 |. 8D45 CC LEA EAX,[LOCAL.13]
008910C9 |. 8D5D 9C LEA EBX,[LOCAL.25]
008910CC |. 33C9 XOR ECX,ECX
008910CE |> 83F9 30 /CMP ECX,30
008910D1 |. 7D 18 |JGE SHORT 008910EB
008910D3 |. 0F100408 |MOVUPS XMM0,DQWORD PTR DS:[ECX+EAX]
008910D7 |. 0F100C0B |MOVUPS XMM1,DQWORD PTR DS:[ECX+EBX]
008910DB |. 0F58C1 |ADDPS XMM0,XMM1
008910DE |. 0F11840D 6CFFFFFF |MOVUPS DQWORD PTR SS:[ECX+EBP-94],XMM0
008910E6 |. 83C1 04 |ADD ECX,4
008910E9 |.^ EB E3 \JMP SHORT 008910CE
Decodificando il file binario che contiene quel codice macchina e stampando ogni istruzioni riga per riga (così da riuscire a leggerla meglio), MCA decodifica:
Codice:
C7 85 68 FF FF FF 00 00 00 00
8D 45 CC
8D 5D 9C
33 C9
83 F9 30
7D 18
0F 10 04 08
0F 10 0C 0B
0F 58 C1
0F 11 84 0D 6C FF FF FF
83 C1 04
Come si può osservare il codice è quello che si vede sopra (avevo disassemblato un'istruzione in meno, mi sono perso quindi il JMP...). MCA mantiene un array di 15bytes (opzionale) con i byte dell'istruzione; la stampa qui sopra avviene proprio utilizzando quell'array.
Ovviamente mantiene tutte le altre informazioni che riguardano l'istruzione. Ne ho scelte 2 tra quelle mostrate sopra:
Codice:
MOV DWORD PTR SS:[LOCAL.38],0
MOVUPS DQWORD PTR SS:[ECX+EBP-94],XMM0
Queste sono le informazioni raccolte da MCA sulle due istruzioni:
Codice:
RAW bytes (hex): C7 85 68 FF FF FF 00 00 00 00
Instr. length: 10
Print instruction fields:
Located Prefixes 0:
OP: 0xC7
mod_reg_rm: 0x85
disp (4): 0xFFFFFF68
Iimm: 0x0
RAW bytes (hex): 0F 11 84 0D 6C FF FF FF
Instr. length: 8
Print instruction fields:
Located Prefixes 1:
0xF
OP: 0x11
mod_reg_rm: 0x84
SIB byte: 0xD
disp (4): 0xFFFFFF6C
Attualmente è ancora in versione Beta, e necessita quindi di qualche "prova sul campo".
Manca il supporto per il prefisso EVEX (AVX-512), 3DNow! e XOP (di AMD). Attualmente non è presente una trasformazione in mnemonici, ma diciamo che è tra le cose che vorrei implementare in futuro, dopo al supporto per EVEX.
Per tutte le altre info e il codice vi rimando al README di MCA: https://github.com/DispatchCode/Machine-Code-Analyzer