Определить тип процессора из необработанного двоичного кода?


19

На самом деле не имеет отношения к фишкам, но, надеюсь, я получу несколько указаний здесь.

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


7
Не могли бы вы дать нам первые 200 байтов в необработанном гексе?
pingswept

Это забавный вопрос. Какое устройство вы взламываете?
DavidEGrayson

1
Вы можете попробовать передать его нескольким разным дизассемблерам и посмотреть, что получится.
JustJeff

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

Отличный вопрос Однако может лучше подойти для StackOverflow.
sharptooth

Ответы:


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-битных процессоров и начать смотреть на большие устройства с внешней памятью. Если он составляет несколько килобайт или меньше, вместо этого вам следует сосредоточиться на более дешевых и дешевых устройствах. Если функциональность проста, это может быть даже код для четырехбитного процессора.

На данный момент стоит посмотреть на структуру памяти. Там, скорее всего, будет раздел программы и раздел данных как минимум. Если это бинарный файл (по сравнению с Intel hex или записями Motorola), у вас мало информации о том, где в памяти находятся определенные куски данных. Шестнадцатеричный редактор может показывать некоторые шаблоны. Если он записан в формате hex или s, вы можете получить больше информации о структуре памяти процессора, для которого он предназначен. Некоторые процессоры сбрасываются в ячейку памяти программы 0, некоторые в самую верхнюю ячейку памяти. Программа может содержать начальные значения EEPROM в отдельной ячейке памяти. Если он предназначен для безопасного процессора (как используется в банковском деле), он может даже иметь ключи безопасности для нечетного места в памяти.

В зависимости от языка, на котором он был запрограммирован, у вас могут быть некоторые дополнительные подсказки. Если он был запрограммирован на C или аналогичном процедурном языке, то функции почти всегда будут начинаться с последовательности инструкций для сохранения определенных регистров в стек (много нажатий), а затем перед возвратом множества всплывающих окон для возврата исходных значений из стека. , Если вы сможете выполнить какое-то распознавание паттернов, вы найдете множество этих последовательностей повсюду и сможете определить, какие инструкции, скорее всего, являются командами push / pop, return и т. Д., Что может немного сузить ваш выбор.

Если это встроенное устройство с прерываниями, оно может иметь таблицу векторов прерываний, которая будет выглядеть как набор переходов в разные области памяти, все в большом блоке, вероятно, в удобном месте (например, адрес 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 почти все функции начинаются с чего-то, что сохраняет указатель стека в указателе «frame» или «link». Для любого данного процессора обычно есть только несколько способов сделать это. Таким образом, вы можете ответить «это код для процессора X», посмотрев двоичный код X для этих последовательностей.

Тем не менее, мне посчастливилось провести различие между двоичным кодом 8088, 6502 и 68000, используя только гистограммы. Любой данный процессор имеет определенные юридические коды операций с инструкциями, и они, как правило, используются немного чаще, чем в среднем. Имея достаточно большой кусок двоичного файла, вы можете начать видеть определенные тенденции. Однако это затрудняется тем фактом, что все операнды в данном бинарном фрагменте имеют тенденцию не соотноситься с данным типом процессора, и это, по сути, просто создает помехи в данных вашей гистограммы. Кроме того, даже две разные программы для одного и того же процессора могут иметь заметно разные гистограммы. Тем не менее, это может дать вам место для начала.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.