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.