To bardzo interesujące pytanie. Istnieją miliony instrukcji, ale tylko kilka bardzo często używanych.
Pierwszą rzeczą, na którą patrzę, jest pochodzenie i przeznaczenie. Jeśli podejrzewasz, że został on zaprojektowany w Stanach Zjednoczonych, kierowałbyś się głównie na procesory z arkuszami danych dostępnymi na przykład w języku angielskim. Jeśli został zaprojektowany w Azji, istnieje wiele procesorów, których używają do masowych urządzeń, których amerykańscy inżynierowie rzadko widzą. Nawet Europa ma kilka procesorów, które są bardziej popularne niż inne.
Następnie przyjrzałbym się rozmiarowi i funkcjonalności kodu (zakładając, że wiesz, co robi kod do pewnego stopnia). Jeśli jest to kilka megabajtów kodu, możesz prawie zdyskontować większość wbudowanych 8-bitowych procesorów i zacząć szukać większych urządzeń z pamięcią zewnętrzną. Jeśli jest to kilka kilobajtów lub mniej, to zamiast tego chcesz skupić się na mniejszych, tańszych urządzeniach. Jeśli funkcjonalność jest prosta, może to być nawet kod czteroprocesorowego procesora.
W tym momencie warto przyjrzeć się strukturze pamięci. Prawdopodobnie będzie sekcja programu i sekcja danych. Jeśli jest to plik binarny (kontra zapis heksadecymalny lub rekord motoroli), masz niewielki wgląd w to, gdzie w pamięci umieszczane są określone fragmenty danych. Edytor szesnastkowy może pokazywać niektóre wzorce. Jeśli jest zapisany w formacie szesnastkowym lub s, możesz mieć więcej informacji na temat struktury pamięci procesora, dla którego jest przeznaczony. Niektóre procesory resetują się w miejscu pamięci programu 0, niektóre w najwyższym miejscu pamięci. Program może zawierać wartości początkowe EEPROM w osobnym miejscu w pamięci. Jeśli jest przeznaczony dla bezpiecznego procesora (używanego w bankowości), może nawet mieć klucze bezpieczeństwa dla nieparzystej lokalizacji pamięci.
W zależności od języka, w jakim został zaprogramowany, możesz mieć dodatkowe wskazówki. Jeśli został zaprogramowany w C lub w podobnym języku proceduralnym, funkcje prawie zawsze zaczynają się od sekwencji instrukcji, aby zapisać określone rejestry na stosie (wiele wypychań), a następnie tuż przed zwróceniem wielu popów, aby zwrócić oryginalne wartości ze stosu . Jeśli potrafisz rozpoznać wzór, znajdziesz wiele tych sekwencji w całym tekście i możesz określić, które instrukcje najprawdopodobniej są instrukcjami push / pop, return itp., Co może nieco zawęzić twój wybór.
Jeśli jest to urządzenie wbudowane z przerwaniami, może mieć tablicę wektorów przerwań, która będzie wyglądać jak skok skoków do różnych lokalizacji pamięci w dużym bloku, prawdopodobnie w dogodnej lokalizacji (na przykład adres 0x ??? 0) . Tabele skoków są również używane w innych miejscach, ale jeśli potrafisz zlokalizować sekwencję instrukcji, które wyglądają identycznie, z wyjątkiem adresu, pod który należy przejść, możesz być w stanie wywnioskować, jak wygląda instrukcja skoku, i ponownie zawęzić twoje wybory w dół.
W tym momencie zacznę od najbardziej popularnych architektur procesorów i sprawdzę, czy coś jest ze sobą powiązane. x86, arm, mips, 8051, avr, pic, powerpc, Z80, 68k, 6502 itp. itd. itp. Istnieją listy popularnych procesorów i zestawów instrukcji - przynajmniej w świecie anglojęzycznym - które mogą okazać się pomocne.
Nie znam żadnych zautomatyzowanych narzędzi, które by w tym pomogły, ale MAME emuluje wiele architektur procesorów, a jedną z możliwych metod jest uruchomienie kodu przez kilka procesorów i obserwowanie rejestrów, aby sprawdzić, czy coś kliknie zgodnie z tym, co wiesz o projekcie.