Визначте тип процесора з необробленого двійкового коду?


19

Не дуже пов’язана з чіпами, але, сподіваюся, я отримаю декілька вказівок, з яких слід пройти звідси.

Я отримав шматок коду, але не знаю, для якого процесора він призначений. Чи є інструменти, які можуть допомогти мені визначити тип коду? Які статистичні методи можуть допомогти? Розподіл байтів? Розподіл пар тощо? Марківські ланцюги, можливо?


7
Не могли б ви дати нам перші 200 байтів у сирому вигляді?
pingswept

Це цікаве питання. Який пристрій ви зламаєте?
DavidEGrayson

1
ви можете спробувати подати його на пару різних розбирачів і подивитися, що відбувається.
JustJeff

2
Я назву цей код у 100 байтах! = P
JustJeff

Чудове запитання. Однак це може бути краще для StackOverflow.
гострий зуб

Відповіді:


16

Спробуйте запустити його через файл GNU. Якщо у нього є будь-який стандартний заголовок, він підбере його.

Напр.

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

Спробував це. У файлі GNU йдеться про "дані".
менталіст

3
Чи можете ви опублікувати якусь частину? Намагалися шукати в ньому ASCII за допомогою "рядків"?
Тобі Джеффі

9

Це дуже цікаве питання. Є мільйони інструкцій, але лише кілька дуже часто використовуваних.

Перше, на що я звернув увагу, - це походження та призначення. Якщо ви підозрюєте, що він був розроблений у США, ви орієнтуєтесь в основному на процесори з таблицями даних, наприклад, англійською мовою. Якщо він був розроблений в Азії, то існує ряд процесорів, які вони використовують для серійних пристроїв, які американські інженери рідко бачать. Навіть у Європі є кілька процесорів, які є більш поширеними, ніж інші.

Тоді я би поглянув на розмір та функціональність коду (якщо припустити, що ви знаєте, що код робить певною мірою). Якщо це кілька мегабайт коду, ви можете значно знизити більшість вбудованих 8-бітових процесорів і почати дивитися на більші пристрої із зовнішньою пам'яттю. Якщо це кілька кілобайт або менше, то замість цього ви хочете зосередитись на менших, дешевших пристроях. Якщо функціональність проста, це може бути навіть код для чотирибітного процесора.

У цей момент варто переглянути структуру пам'яті. Там, швидше за все, є розділ програми та розділ даних як мінімум. Якщо це двійковий файл (порівняно з шестигранним інтелектуальним записом чи записом Motorola), то ви мало розумієте, де в пам'яті розміщуються певні шматки даних. Шестнадцятковий редактор може показати деякі шаблони. Якщо він надходить у шістнадцятковий або s формат запису, у вас може бути додаткова інформація про структуру пам'яті процесора, для якого він призначений. Деякі процесори скидаються на місце пам'яті програми 0, а деякі - на найвищому місці. Програма може включати початкові значення EEPROM в окремому місці пам'яті. Якщо він призначений для захищеного процесора (як це використовується в банківській справі), він може мати навіть ключі безпеки для непарного місця пам'яті.

Залежно від мови, на якій було запрограмовано, у вас можуть з’явитися додаткові підказки. Якщо він був запрограмований на C або подібній процедурній мові, то функції майже завжди починатимуться з послідовності інструкцій для збереження певних регістрів у стек (багато натискань), то прямо перед поверненням безлічі спливаючих вікон, щоб повернути початкові значення зі стека . Якщо ви можете виконати деяке розпізнавання шаблонів, ви знайдете безліч цих послідовностей на протязі, і, можливо, зможете визначити, які вказівки, швидше за все, інструкції push / pop, повернення тощо, що може трохи зменшити ваш вибір.

Якщо це вбудований пристрій з перериваннями, він може мати векторну таблицю переривань, яка буде схожа на купу стрибків у різні місця пам'яті, все у великому блоці, ймовірно, у зручному місці (наприклад, 0x ??? 0) . Таблиці стрибків використовуються і в інших місцях для інших речей, але якщо ви зможете знайти послідовність інструкцій, які виглядають однаково, за винятком того, яким буде адреса, до якої слід перейти, ви зможете зробити висновок про те, як виглядає інструкція про стрибок, і знову звузити ваш вибір знижений.

У цей момент я почав би з найбільш поширених архітектур процесорів і побачив, чи щось корелює. x86, arm, mips, 8051, avr, pic, powerpc, Z80, 68k, 6502, і т. д., і т. д. і т. д. Існують переліки загальних процесорів та наборів інструкцій - принаймні в англомовному світі - які можуть виявитися корисними.

Мені невідомі будь-які автоматизовані інструменти, які допомогли б у цьому допомогти, але MAME наслідує дуже багато архітектур процесорів, і один із можливих методів - запускати код через декілька процесорів і дивитися регістри, щоб побачити, чи щось клацне відповідно до того, що ви знаєте про дизайн.


"Навіть у Європі є кілька процесорів, які є більш поширеними, ніж інші". Живучи в Європі, мені цього ніколи не приходило в голову. Чи можете ви навести приклади?
stevenvh

@stevenvh Завдяки компаніям Acorn і Sinclair вбудовані системи 6502 і Z80 були дуже популярними. І, звичайно, процесор ARM запустився в Acorn Computers.
Адам Девіс

5

Ідея: чи знаєте ви вік вихідного коду, тобто приблизно в який час / рік його створення?

Якщо він був досить старий, це може дати вам зрозуміти, для якого процесора він написаний. Ви можете взяти вік / рік написання та визначити, який процесор (и) були популярні протягом цього періоду, і спробувати завантажити / виконати шістнадцятковий файл для них.

По-друге, зважаючи на масове розповсюдження процесорів лише за останні 20 років, це може бути технікою «голка в стог» і не бути дуже плідною.


4

Багато місяців тому, коли не було так багато різних процесорних ядер навколо, я кілька разів визначив код Z80 за допомогою частотного аналізу . Для Z80 CDце машинний код call subroutineі C9є return from subroutine(я ніколи не забуду), і це часто коди, що найбільш часто зустрічаються. Однак для цього потрібно ознайомитись із набором інструкцій на рівні машинного коду. Маючи досвід збирання вручну допомагає (зробив це багато, і я все ще можу порахувати зворотно в шістнадцятковій формі, щоб розрахувати компенсації).


3

Якщо файл призначений для 12-бітового або 14-бітного PIC, кожна пара байтів буде 12- або 14-бітним словом, як правило, спочатку зберігається LSB, з чіткими двома або чотирма найбільш значущими бітами.


1

Якби він був складений з такої мови, як C або Pascal, ви могли б шукати певні стандартні послідовності бінарних даних. Наприклад, з C майже всі функції починаються з того, що зберігає вказівник стека на покажчик "кадр" або "посилання". Для будь-якого даного процесора зазвичай існує лише кілька способів зробити це. Отже, ви можете відповісти "це код для процесора X", шукаючи двійкові дані X для цих послідовностей.

Однак, мені вдалося розмежувати 8088, 6502 і 68000 двійкових, використовуючи лише гістограми. Будь-який даний процесор має певні правові інструкції, і вони, як правило, використовуються трохи частіше, ніж в середньому. Маючи досить великий шматок бінарного, ви можете почати бачити певні тенденції. Однак це ускладнюється тим, що всі операнди в даному двійковому фрагменті, як правило, не співвідносяться із заданим типом процесора, і це по суті просто шумить у ваших даних гістограми. Крім того, навіть дві різні програми для одного і того ж процесора можуть мати помітно різні гістограми. Тим не менш, це може дати вам місце для початку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.