Zidentyfikować typ procesora na podstawie surowego kodu binarnego?

19

Nie bardzo związane z frytkami, ale mam nadzieję, że otrzymam kilka wskazówek do naśladowania.

Dostałem kawałek kodu, ale nie wiem, do jakiego procesora był przeznaczony. Czy są dostępne narzędzia, które pomogą mi zidentyfikować typ kodu? Jakie metody statystyczne mogą pomóc? Dystrybucja bajtów? Dystrybucja par itp.? Może łańcuchy Markowa?

mentalista
źródło
7
Czy możesz podać nam pierwsze 200 bajtów w postaci nieprzetworzonego heksa?
pingswept
To zabawne pytanie. Jakiego rodzaju urządzenie hakujesz?
DavidEGrayson
1
możesz spróbować nakarmić go kilkoma różnymi deasemblerami i zobaczyć, co się stanie.
JustJeff,
2
Nazwę ten kod za 100 bajtów! = P
JustJeff
Świetne pytanie. Może jednak lepiej pasować do StackOverflow.
sharptooth

Odpowiedzi:

16

Spróbuj uruchomić go za pomocą pliku GNU. Jeśli ma jakikolwiek standardowy nagłówek, to go odbierze.

Na przykład.

jrt@lin:~/src$ file foo
foo: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped
Toby Jaffey
źródło
Próbowałem tego. Plik GNU mówi, że to „dane”.
mentalista
3
Czy mógłbyś opublikować niektóre z nich? Próbowałeś szukać w nim ASCII z „ciągami znaków”?
Toby Jaffey
9

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.

Adam Davis
źródło
„Nawet Europa ma kilka procesorów, które są bardziej popularne niż inne”. Żyjąc w Europie, nigdy nie przyszło mi to do głowy. Czy możesz podać przykłady?
stevenvh
@stevenvh Ze względu na firmy Acorn i Sinclair systemy osadzone oparte na 6502 i Z80 były bardzo popularne. I oczywiście procesor ARM zaczął się w Acorn Computers.
Adam Davis
5

Pomysł: czy znasz wiek kodu źródłowego, tj. W jakim czasie / roku został on utworzony?

Jeśli był wystarczająco stary, może dać ci wskazówkę, dla którego procesora został napisany. Możesz wziąć wiek / rok, w którym został napisany, i określić, które procesory były popularne w tym okresie, i spróbować załadować / wykonać plik hex na nich.

Z drugiej strony, biorąc pod uwagę masowe rozprzestrzenianie się procesorów w ciągu ostatnich 20 lat, może to być technika strzyżenia igły w stóg siana i niezbyt owocna.

J. Polfer
źródło
4

Wiele księżyców temu, kiedy nie było tak wielu różnych rdzeni procesora, kilka razy zidentyfikowałem kod Z80 poprzez analizę częstotliwości . Ponieważ Z80 CDjest kodem maszynowym dla call subroutinei C9jest return from subroutine(nigdy nie zapomnę), i często są to najczęściej występujące kody. Wymaga to jednak zaznajomienia się z instrukcją ustawioną na poziomie kodu maszynowego. Doświadczenie w samodzielnym montażu pomaga (dużo tego zrobiłem, a ja wciąż mogę liczyć wstecz w heksie, aby obliczyć przesunięcia).

stevenvh
źródło
3

Jeśli plik dotyczy 12-bitowego lub 14-bitowego PIC, każda para bajtów będzie 12- lub 14-bitowym słowem, zwykle przechowywanym najpierw LSB, z dwoma lub czterema najbardziej znaczącymi bitami wyczyszczonymi.

supercat
źródło
1

Gdyby został skompilowany z języka takiego jak C lub Pascal, istniałyby pewne standardowe sekwencje plików binarnych, których można by szukać. Na przykład w przypadku C prawie wszystkie funkcje zaczynają się od czegoś, co zapisuje wskaźnik stosu we wskaźniku „frame” lub „link”. W przypadku dowolnego procesora jest to zwykle tylko kilka sposobów. Możesz więc odpowiedzieć „czy to kod dla procesora X”, szukając pliku binarnego X dla tych sekwencji.

To powiedziawszy, miałem trochę szczęścia rozróżniając binarne 8088, 6502 i 68000 za pomocą histogramów. Każdy procesor ma określone kody instrukcji prawnych, które zwykle są używane nieco częściej niż przeciętnie. Z wystarczająco dużą ilością plików binarnych możesz zacząć widzieć pewne trendy. Utrudnia to jednak fakt, że wszystkie operandy w danym pliku binarnym nie korelują z danym typem procesora, co w zasadzie powoduje szum w danych histogramu. Również nawet dwa różne programy dla tego samego procesora mogą mieć zauważalnie różne histogramy. Mimo to może dać ci miejsce do rozpoczęcia.

JustJeff
źródło