Identificare il tipo di processore dal codice binario non elaborato?


19

Non molto legato ai chip, ma spero di ottenere alcune indicazioni da seguire da qui.

Ho un pezzo di codice, ma non so a quale processore fosse destinato. Sono disponibili strumenti che possono aiutarmi a identificare il tipo di codice? Quali metodi statistici possono aiutare? Distribuzione byte? Distribuzione di coppie, ecc.? Catene di Markov forse?


7
Potresti darci i primi 200 byte in esadecimale grezzo?
spazzato

Questa è una domanda divertente Che tipo di dispositivo stai hackerando?
DavidEGrayson,

1
potresti provare a dargli da mangiare un paio di diversi disassemblatori e vedere cosa succede.
JustJeff,

2
Chiamerò quel codice in 100 byte! = P
JustJeff

Ottima domanda Potrebbe essere una soluzione migliore per StackOverflow comunque.
sharptooth,

Risposte:


16

Prova a eseguirlo attraverso il file GNU. Se ha un'intestazione standard, la prenderà.

Per esempio.

jrt@lin:~/src$ file foo
foo: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped

Ci ho provato. Il file GNU dice che sono "dati".
mentalista,

3
Potresti postarne un po '? Hai provato a cercare ASCII in esso con "stringhe"?
Toby Jaffey,

9

Questa è una domanda molto interessante Esistono milioni di istruzioni, ma solo una manciata di quelle molto usate.

La prima cosa che guarderei è l'origine e l'uso previsto. Se sospetti che sia stato progettato negli Stati Uniti, ti rivolgeresti principalmente ai processori con fogli di dati disponibili in inglese, ad esempio. Se è stato progettato in Asia, ci sono un certo numero di processori che usano per dispositivi fabbricati in serie che gli ingegneri statunitensi raramente vedono. Anche l'Europa ha alcuni processori che sono più comuni di altri.

Darei quindi un'occhiata alle dimensioni e alla funzionalità del codice (supponendo che tu sappia cosa fa il codice in una certa misura). Se sono pochi megabyte di codice, puoi praticamente scartare la maggior parte dei processori a 8 bit incorporati e iniziare a guardare dispositivi più grandi con memoria esterna. Se si tratta di pochi kilobyte o meno, ti consigliamo invece di concentrarti su dispositivi più piccoli ed economici. Se la funzionalità è semplice, potrebbe persino essere un codice per un processore a quattro bit.

A questo punto vale la pena guardare la struttura della memoria. È probabile che ci sia almeno una sezione di programma e una sezione di dati. Se si tratta di un file binario (rispetto a Intel hex o record di Motorola), allora si ha una scarsa comprensione di dove vengono collocati alcuni blocchi di dati in memoria. Un editor esadecimale potrebbe mostrare alcuni schemi. Se viene fornito in un formato esadecimale o record, potresti avere maggiori informazioni sulla struttura di memoria del processore per cui è destinato. Alcuni processori si resettano nella posizione di memoria del programma 0, altri nella posizione di memoria più alta. Il programma potrebbe includere i valori iniziali EEPROM in una posizione di memoria separata. Se è pensato per un processore sicuro (come usato nel settore bancario), potrebbe anche avere chiavi di sicurezza per una posizione di memoria dispari.

A seconda della lingua in cui è stato programmato, potresti avere ulteriori indizi. Se è stato programmato in C o in un linguaggio procedurale simile, le funzioni inizieranno quasi sempre con una sequenza di istruzioni per salvare alcuni registri nello stack (molti push) quindi subito prima di restituire molti pop per restituire i valori originali dallo stack . Se riesci a riconoscere alcuni schemi, troverai molte di queste sequenze in tutto e potresti essere in grado di determinare quali istruzioni sono molto probabilmente istruzioni push / pop, return, ecc., Che potrebbero restringere un po 'le tue scelte.

Se si tratta di un dispositivo incorporato con interrupt, potrebbe avere una tabella vettoriale di interrupt, che sembrerà un mucchio di salti verso diverse posizioni di memoria in un blocco di grandi dimensioni, probabilmente in una posizione comoda (indirizzo 0x ??? 0 per esempio) . Le tabelle di salto vengono utilizzate altrove anche per altre cose, ma se riesci a individuare una sequenza di istruzioni che sembrano identiche ad eccezione di quale sarebbe l'indirizzo a cui saltare, potresti essere in grado di dedurre l'aspetto di un'istruzione di salto e di nuovo restringere le tue scelte verso il basso.

A quel punto, vorrei iniziare con le architetture di processore più comuni e vedere se qualcosa è correlato. x86, arm, mips, 8051, avr, pic, powerpc, Z80, 68k, 6502, ecc, ecc. ecc. Ci sono elenchi di processori e set di istruzioni comuni - almeno nel mondo di lingua inglese - che potrebbero rivelarsi utili.

Non sono a conoscenza di strumenti automatizzati che potrebbero aiutare in questo, ma MAME emula un gran numero di architetture di processori e un possibile metodo è quello di eseguire il codice attraverso un numero di processori e guardare i registri per vedere se qualcosa fa clic in base a ciò che conosci il design.


"Anche l'Europa ha alcuni processori che sono più comuni di altri." Vivere in Europa, questo non mi è mai venuto in mente. Puoi fare degli esempi?
Stevenvh,

@stevenvh Grazie alle società Acorn e Sinclair, i sistemi embedded basati su 6502 e Z80 erano molto popolari. E, naturalmente, il processore ARM è stato avviato da Acorn Computers.
Adam Davis,

5

Idea: conosci l' età del codice sorgente, ovvero in quale periodo / anno è stato creato?

Se fosse abbastanza vecchio, potrebbe darti un indizio su quale processore è stato scritto. Puoi prendere l'età / l'anno in cui è stato scritto e determinare quali processori sono stati popolari in quel periodo di tempo, e provare a caricare / eseguire il file esadecimale su quelli.

Ripensandoci, data la proliferazione di massa dei processori negli ultimi 20 anni, questa potrebbe essere una tecnica ad ago nel pagliaio e non essere molto fruttuosa.


4

Molte lune fa, quando non c'erano molti core di processore diversi in giro, ho identificato il codice Z80 alcune volte attraverso l' analisi della frequenza . Per Z80 CDè il codice macchina per call subroutineed C9è return from subroutine(non dimenticherò mai), e questi sono spesso i codici più ricorrenti. Ciò richiede tuttavia la conoscenza delle istruzioni impostate a livello di codice macchina. Avere esperienza nell'assemblaggio a mano aiuta (fatto molto, e posso ancora contare all'indietro in esadecimale per calcolare gli offset).


3

Se il file è per un PIC a 12 o 14 bit, ogni coppia di byte sarà una parola di 12 o 14 bit, in genere memorizzata per prima LSB, con i due o quattro bit più significativi azzerati.


1

Se fosse stato compilato da un linguaggio come C o Pascal, ci sarebbero alcune sequenze standard di binari che potresti cercare. Con C per esempio, quasi tutte le funzioni iniziano con qualcosa che salva il puntatore dello stack in un puntatore "frame" o "link". Per ogni dato processore, di solito ci sono solo un paio di modi per farlo. Quindi potresti rispondere "è questo codice per il processore X" cercando il binario di X per queste sequenze.

Detto questo, ho avuto un po 'di fortuna differenziando tra 8088, 6502 e 68000 binari solo usando gli istogrammi. Ogni dato processore ha alcuni codici operativi delle istruzioni legali, che tendono ad essere usati leggermente più spesso della media. Con un pezzo abbastanza grande di binario, puoi iniziare a vedere alcune tendenze. Ciò è reso difficile, tuttavia, dal fatto che tutti gli operandi in un dato pezzo di binario tendono a non essere correlati al tipo di processore dato, e questo essenzialmente fa solo rumore nei dati dell'istogramma. Inoltre, anche due programmi diversi per lo stesso processore possono avere istogrammi notevolmente diversi. Tuttavia, può darti un punto di partenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.