что такое реверсивный инжиниринг
Обратный инжиниринг
Обра́тная разрабо́тка (обратный инжиниринг, реверс-инжиниринг; англ. reverse engineering ) — исследование некоторого устройства или программы, а также документации на них с целью понять принцип его работы и, чаще всего, воспроизвести устройство, программу или иной объект с аналогичными функциями, но без копирования как такового.
Применяется обычно в том случае, если создатель оригинального объекта не предоставил информации о структуре и способе создания (производства) объекта. Использование обратной разработки может противоречить закону об авторском праве и патентному законодательству.
В настоящее время под словами «reverse engineering» чаще всего понимается т. н. «clean room reverse engineering», то есть процесс, при котором одна группа разработчиков анализирует машинный код программы (в сленге хакеров для этого процесса используется также выражение «обратный инжиниринг» или «реверсный инжиниринг»), составляет алгоритм данной программы на псевдокоде, либо, если программа является драйвером какого-либо устройства, составляет исчерпывающие спецификации интересующего устройства. После получения спецификаций другая группа разработчиков пишет собственный драйвер на основе полученных спецификаций или алгоритмов. Такой подход позволяет избежать обвинений в нарушении авторских прав на исходную программу, так как по законам, к примеру в США, подпадает под понятие «fair use», то есть добросовестного использования оригинальной программы. Результат обратной разработки редко идентичен оригиналу, что и позволяет избежать ответственности перед законом.
Содержание
Сферы применения обратной разработки
Электроника
Копирование различных электронных блоков без фактической разработки. Известно, что часть советской цифровой электроники копировалась. Например, американская серия интегральных схем 74 и её советский аналог К(Р)155.
Ещё один пример обратной разработки — создание компанией AMD процессора Intel 80386.
Программное обеспечение
С развитием Интернета популярные операционные системы и программы всё интенсивнее исследуются на предмет обнаружения в них уязвимостей или т. н. дыр. В дальнейшем найденные дыры могут использоваться для получения несанкционированного доступа к удалённому компьютеру или компьютерной сети.
Одним из широко известных примеров обратной разработки является исследование IBM, ставшее серьёзным шагом на пути развития производства IBM-совместимых компьютеров сторонними производителями. Создание сервера GNU/Linux и работающего с серверами на базе ОС Microsoft Windows) также потребовало обратной разработки используемого SMB.
Обратная разработка программного обеспечения производится с помощью следующих методик.
Базы данных
может использоваться при создании реляционной модели базы данных.
Промышленность
Обратная разработка продукта конкурента с целью узнать его устройство, принцип работы и оценить возможности создания аналога.
Военная промышленность
Самыми известными фактами обратной разработки во время второй мировой войны являлись:
Для анализа исходного кода
Существуют программы, которые предоставляют как возможность восстановления (обратный, reverse) по исходному коду общего системного проекта (классы, связь между ними и т.п.), так и прямой генерации исходного кода на основе созданного проекта (функциональных блоков бизнес-процесса):
Реверс-инжиниринг для самых маленьких: взлом кейгена
Вначале было слово. Двойное
Открыв файл кейгена в Ida, видим список функций.
Проанализировав этот список, мы видим несколько стандартных функций (WinMain, start, DialogFunc) и кучу вспомогательных-системных. Все это стандартные функции, составляющие каркас.
Пользовательские функции, которые представляют реализацию задач программы, а не ее обертку из API-шных и системных вызовов, дизассемблер не распознает и называет попросту sub_цифры. Учитывая, что такая функция здесь всего одна — она и должна привлечь наше внимание как, скорее всего, содержащая интересующий нас алгоритм или его часть.
Давайте запустим кейген. Он просит ввести две 4-значных строки. Предположим, в функцию расчета ключа отправляются сразу восемь символов. Анализируем код функции sub_401100. Ответ на гипотезу содержится в первых двух строках:
Вторая строка недвусмысленно намекает нам на получение аргумента функции по смещению 8. Однако размер аргумента — двойное слово, равное 4 байтам, а не 8. Значит, вероятнее всего за один проход функция обрабатывает одну строку из четырех символов, а вызывается она два раза.
Вопрос, который наверняка может возникнуть: почему для получения аргумента функции резервируется смещение в 8 байт, а указывает на 4, ведь аргумент всего один? Как мы помним, стек растет вниз; при добавлении в стек значения стековый указатель уменьшается на соответствующее количество байт. Следовательно, после добавления в стек аргумента функции и до начала ее работы в стек добавляется что-то еще. Это, очевидно, адрес возврата, добавляемый в стек после вызова системной функции call.
Найдем места в программе, где встречаются вызовы функции sub401100. Таковых оказывается действительно два: по адресу DialogFunc+97 и DialogFunc+113. Интересующие нас инструкции начинаются здесь:
В чем смысл этих операций? Выяснить очень просто даже на практике, без теории. Поставим в отладчике брейкпойнт, например, на инструкции push eax (перед самым вызовом подфункции) и запустим программу на выполнение. Кейген запустится, попросит ввести строки. Введя qwer и tyui и остановившись на брейкпойнте, смотрим значение еах: 72657771. Декодируем в текст: rewq. То есть физический смысл этих операций — инверсия строки.
Теперь мы знаем, что в sub_401100 передается одна из исходных строк, перевернутая задом наперед, в размере двойного слова, целиком умещающаяся в любом из стандартных регистров. Пожалуй, можно взглянуть на инструкции sub_401100.
Следующая команда LEA ecx, [eax+eax*8] элегантно и непринужденно умножает еах на 9 и записывает результат в есх. Затем это значение копируется в edx и сдвигается вправо на 13 разрядов: получаем 73213 в еdx и E6427B23 в есх. Затем — снова ксорим есх и edx, записывая в есх E6454930. Копируем это в еах, сдвигаем влево на 9 разрядов: 8А926000, затем инвертируем это, получая 756D9FFF. Прибавляем это значение к регистру есх — имеем 5BB2E92F. Копируем это в еах, сдвигаем вправо аж на 17 разрядов — 2DD9 — и ксорим с есх. Получаем в итоге 5BB2C4F6. Затем… затем… что там у нас? Что, все.
Итак, мы сохраняем это значение в область памяти по смещению var_4, загружаем из стека состояния регистров, снова берем из памяти итоговое значение и окончательно забираем из стека оставшиеся там состояния регистров, сохраненные в начале. Выходим из функции. Ура. впрочем, радоваться еще рано, пока что на выходе из первого вызова функции мы имеем максимум — четыре полупечатных символа, а ведь у нас еще целая необработанная строка есть, да и эту еще к божескому виду привести надо.
Перейдем на более высокий уровень анализа — от дизассемблера к декомпилятору. Представим всю функцию DialogFunc, в которой содержатся вызовы sub_401100, в виде С-подобного псевдокода. Собственно говоря, это дизассемблер называет его «псевдокодом», на деле это практически и есть код на С, только страшненький. Глядим:
Эпилог
bash-реализация пресловутой sub_401100:
Основная функция кейгена:
Промышленный реверс-инжиниринг
Рассказ о процессе заимствования при разработке электроники на наглядном примере.
Запись лога работы лифта самодельным сниффером
Однажды мне понадобилось скопировать довольно простое устройство. Компания-производитель перестала существовать, но по всей стране ещё был спрос на замену сломанных или отработавших свой ресурс девайсов.
Само устройство — кнопка вызова лифта на фото слева. Для опытов мне дали два экземпляра, один из которых можно было полностью разобрать.
Общий план работы выглядел примерно так:
При неудаче пункта 4, дальнейший план выглядел бы сложнее, но мне повезло.
Изучаем подопытного
Основной микроконтроллер
Кусок электросхемы лифта, на которой наши платы обведены красным
Плата собрана на микроконтроллере 1997 года выпуска AT89C2051, в основе которого лежит архитектура Intel MCS-51. В 2020 году она празднует свой 40-летний юбилей на рынке встраиваемых систем.
Небольшое пояснение: микроконтроллер — это такая микросхема, содержащая вычислительное ядро и набор периферии для управления внешними устройствами. Например, в современной стиральной машине микроконтроллер опрашивает кнопки управления, датчики, выводит информацию на экран и управляет насосами, нагревателем, клапанами и приводом барабана. Для большинства перечисленных функций ему не требуются промежуточные устройства, только набор пассивных электронных компонентов.
Разбираем плату для срисовывания электросхемы
Срисовывание оригинальной электросхемы платы в будущем поможет узнать назначение пинов микроконтроллера, которое необходимо для разбора кода прошивки.
Оригинальное устройство разработано китайской компанией, а потому его схема крайне запутана и со множеством лишних компонентов. Например, включение реле производилось через тройной каскад из биполярного транзистора, оптопары и полевика (именно в таком порядке).
Знакомый, работающий с китайскими производствами, рассказал мне, что китайцы занимаются подобным усложнением схем для увеличения стоимости разработки и производства, если то и другое делают одни люди. После такого я склонен ему верить:
Одно и то же место на китайской двухслойной плате с обеих сторон. Три огромных резистора ни к чему не подключены. Я даже просвечивал плату мощным фонариком, чтобы убедиться.
Схема срисована, загадочные места смоделированы в мультисиме, берёмся за прошивку.
Пытаемся считать прошивку
Мне очень повезло, что на обоих платах в контроллерах не включена защита от чтения, поэтому я успешно слил два варианта прошивки подобной порнографией:
Фото из личного блога американского энтузиаста
Дизассемблирование прошивки
Следующим этапом нам нужно преобразовать этот машинный код во что-то более читаемое:
Берём известный инструмент IDA Pro, в котором уже есть наш контроллер со всеми регистрами периферии, и открываем HEX файл прошивки:
Обработка принимаемых платой данных на языке ассемблера
После этого идёт довольно нудный процесс изучения набора команд нашего вычислительного ядра, комментирование и расшифровка ассемблерного кода.
По адресам таблицы векторов прерываний нашлись сами обработчики прерываний, записи в регистры периферии дали информацию о конфигурации интерфейса связи. Шаг за шагом безымянный ассемблерный код превратился в то, что можно читать.
Извлечение алгоритма работы
Так как мне нужно было разработать новое устройство на другой элементной базе, из кода необходимо было извлечь алгоритм. Некоторое время спустя родился такой псевдокод:
Та же самая обработка принимаемых данных на языке Си
Кому интересен протокол передачи:
Станция управления лифтом общалась с платами кнопок вызовов по полнодуплексному 24-вольтовому интерфейсу. В обычном режиме платы кнопок слушали линию, ожидая 9-битный пакет данных. Если в этом пакете приходил адрес нашей платы (задавался DIP-переключателем на плате), то плата переключалась на 8-битный режим приёма, и все последующие пакеты аппаратно игнорировались остальными платами.
Последним байтом шла контрольная сумма, которая представляет собой простой XOR всех байт после адреса.
После контрольной суммы плата опять переходила в режим ожидания своего адреса.
Разработка новой платы
Для этапа разработки новой электросхемы и печатной платы у меня нет картинок, но всё было примерно так:
Составление электросхемы и разводка платы делались в Altium Designer. Изготовление печатной платы заказывалось в зеленоградском «Резоните».
Написание новой прошивки
Пока наша новая плата на изготовлении, едем на объект, где установлены такие кнопки вызова, и проверяем правильность разобранного протокола передачи с помощью собранного на ардуине сниффера:
Кусок схемы передатчика, электрически эквивалентный оригиналу. На приёмнике просто оптопара.
Говнокодим в ICC AVR наш сниффер
Дальше нужно было действовать крайне аккуратно, чтобы не спалить ничего в лифте и не допустить его остановки.
Лезем в кнопку вызова. Толстые жёлтые провода — питание платы и интерфейс передачи. Белые на 4-пиновом разъёме — подключение кнопки и её подсветки.
Проверяем, что всё работает как надо, исправляем косяки и пишем новую прошивку под наше устройство:
Код на Си для новой платы на основе микроконтроллера AVR ATmega328P
Простоту устройства и прошивки можно оценить по объёму кода, он содержит всего лишь около 600 строк на языке Си.
Процесс сборки выглядел так:
Плата другая, но принцип тот же
Фотографию готового устройства приложить не могу, просто поверьте, что оно до сих пор производится и продаётся.
Лирическое заключение
По поводу кнопок лифта «вверх» и «вниз» на этаже. Я заметил, что многие люди совершенно не понимают их назначение и жмут обе сразу.
Отсюда
У лифта есть два набора кнопок: в кабине — панель приказов, и на этаже — панель вызова. Уже по названию можно догадаться, что панель приказов имеет более высокий приоритет управления.
Все лифты, имеющие панели вызовов с кнопками «вверх» и «вниз», работают с каким-то из вариантов алгоритма оптимизации поездок, целью которых является перевозка максимального числа пассажиров за минимальное время и отдельное условие максимального времени ожидания на этаже (регулируется госстандартом).
Такой алгоритм обычно предполагает подбор пассажиров на этажах, если они едут в том же направлении, которое указывают нажатием кнопки вызова «вверх» или «вниз».
Представим ситуацию, что лифт с пассажирами едет вниз и по пути получает с этажа ниже вызов «вниз». Лифт остановится для подбора пассажира (да, есть ещё учёт загрузки кабины по весовому датчику, но его мы опустим).
Лифт едет дальше и получает с этажа ниже вызов «вверх». Логично, что лифт не остановится для подбора пассажира, так как не будет менять направление движения (это тоже регулируется стандартом), а подбирать пассажира, чтобы поехать вниз, а затем вверх — бесполезный расход энергии и места в лифте.
Лифт едет дальше и получает с этажа ниже сразу два вызова «вверх и «вниз», которые нажал какой-то нетерпеливый пассажир, которому нужно ехать вверх. Логично, что лифт остановится на этом этаже, но пассажир в него не войдёт, зато потратит время людей в кабине на замедление и остановку лифта, открытие дверей, ожидание, закрытие дверей и разгон до номинальной скорости.
Если у лифта только одна кнопка на этаже, то в 99% случаев он работает по алгоритму «собирательный вниз», и при наличии приказов в кабине останавливается только при движении вниз.
Если у вас есть навыки программирования на JS, то можете попробовать реализовать подобный алгоритм управления в онлайновой игре Elevator Saga. В ней есть все аспекты оптимизации поездок без углубления в хардкор вроде работы цепей безопасности лифта.
В своём телеграм-канале я выкладываю подобные материалы. Прямо сейчас там можно следить за разработкой очередного устройства.
Реверс-инжиниринг на производстве при помощи 3D-сканирования
Интервью с экспертом по 3D-технологиям Георгием Казакевичем
– Если мы хотим понимать, что такое реверс-инжиниринг, что нам нужно знать в первую очередь?
– Прежде всего надо разобраться, в чем состоит задача 3D-сканирования. Термин этот на самом деле расплывчатый, поскольку 3D-сканирование как таковое подразумевает просто сбор информации, которую надо обработать. «Сырые» данные не дают нам никакого практического результата.
Вспомните, какими были компьютерные игры лет пятнадцать-двадцать назад: на плоском экране прыгает несколько пикселей. Компьютеры того времени не могли обсчитать информацию больше, чем на эти несколько пикселей. За прошедшие годы вычислительные мощности неимоверно возросли. У любого из нас в кармане мобильный телефон, который мощнее, чем компьютер, который рассчитывал полет американцев на Луну. Поэтому сейчас, сидя за своим рабочим столом, вы можете обрабатывать колоссальные массивы информации. А 3D-сканирование, как я уже сказал, – ничто иное, как сбор информации.
– С какой целью мы собираем эту информацию?
– Для решения задач по двум направлениям – контроля геометрии и обратного проектирования (реверс-инжиниринга). Это два совершенно независимых процесса, и ими обычно занимаются разные отделы. Обратное проектирование – миссия конструкторского отдела. Его применяют, если необходимо отмасштабировать или изменить геометрию изделия, а конструкторская документация отсутствует. Объект сканируется, и на основе данных сканирования мы получаем CAD-модель, которую можно редактировать. То есть обратное проектирование – это, условно говоря, перевод материального объекта в цифровую форму. Но это не только заимствование, но также и возможность перенести сделанный вручную объект в чертежи.
Обратное проектирование в промышленном дизайне в автомобильной промышленности
– Значит, обратное проектирование – не всегда копирование?
– Да, не всегда. И здесь мы имеем дело с промышленным дизайном. Возьмем автомобильную промышленность. Во-первых, корпуса автомобилей создаются дизайнерами. Во-вторых, очень важно, чтобы поток воздуха правильно распределялся вокруг машины – это влияет на экономию топлива. Естественно, есть цифровые модели, которые позволяют производить продув в виртуальной аэродинамической трубе и проверять корпус на обтекаемость. Но любая цифровая модель – это всегда допущение. Удешевление технологии сканирования позволяет крупным производителям, таким как BMW или Mercedes, использовать ее для разработки новых корпусов. Они воссоздают полноразмерный макет машины и продувают его в реальной трубе. После этого они могут провести какую-то мелкую дополнительную обработку, чтобы добиться оптимальной схемы потока воздуха. Потом корпус просто сканируется и переносится в CAD/CAM-систему. То есть из реального объекта мы получаем виртуальный, который потом тиражируется. Это как раз наглядный пример того, что реверс-инжиниринг – не только копирование.
Но если вы где-то будете рассказывать про обратное проектирование, обязательно найдутся люди, которые скажут: «Так делают в Китае. Это плохо». Почему плохо, они объяснить не могут, и с ними не имеет смысла спорить. Просто нужно смотреть на показатели. Факт в том, что Китай сейчас – одна из самых быстрорастущих мировых экономик. Последние десять лет эта страна занимает первое место в мире по использованию 3D-сканеров.
Возьмем тот же самый BMW. Чертежей у вас нет, но вы можете их получить с помощью 3D-сканера. Да, безусловно, методика производства вам не будет известна, ее придется разрабатывать. И это еще один ответ тем, кто говорит, что обратное проектирование – это просто копирование. На самом деле, это лишь подсказка, в каком направлении надо двигаться. Нормальному предприятию очень важно разработать технологию производства, а это стоит гораздо больших денег, чем создать чертеж.
– Давайте поговорим о том, что в себя включает процесс обратного проектирования.
– Он наглядно представлен на схеме, начиная со сканирования и заканчивая испытаниями полученной детали. Реверс-инжиниринг – это, естественно, не просто получение чертежей. И даже не столько получение чертежей, сколько изготовление по ним определенной детали и понимание того, что вы добились поставленной цели.
В качестве примера мы взяли крыльчатку, которая является компонентом узла, используемого на нефтегазовых предприятиях. Допустим, этот узел иностранного производства (что встречается сплошь и рядом). Поскольку нефтегазовый сектор сейчас находится под санкциями, многие предприятия пытаются самостоятельно изготавливать запчасти для устройств, которые раньше поставлялись из-за рубежа. Итак, у нас есть узел, он исправно работает, но у него сломалась крыльчатка. А новую закупить мы не можем. Если приобрести отечественную, значит, придется менять всю периферию вокруг. Соответственно, если есть такой же узел с исправной крыльчаткой, мы можем ее отсканировать и создать 3D-модель в CAD. Затем, в зависимости от желаемого метода производства, либо экспортируем модель в САМ-систему, чтобы обработать стандартным образом на станке с ЧПУ, либо передаем на аддитивную установку. Во втором случае, как видим, производственный цикл сокращается. К тому же, надо понимать, что экспорт в САМ-систему и создание CAM-модели происходят не в автоматическом режиме (хотя для этого существует специальное ПО). Это всё трудозатраты человека.
Нижняя часть корпуса насоса и ее CAD-модель
– Расскажите, пожалуйста, о Вашем практическом опыте реверс-инжиниринга.
– Упомяну несколько интересных проектов, выполненных экспертами компании iQB Technologies.
Вот, например, корпус насоса. Он находится внутри некой сборки. С этими корпусами были проблемы – они трескались и лопались. Покупать новый – значит менять всю периферию, что, естественно, намного дороже. Выяснилось, что лопается нижняя часть, на которой насос стоит, – возможно, из-за слишком больших нагрузок или некачественного металла. При этом ни внутренняя, ни верхняя части не повреждались. По требованию заказчика мы отсканировали нижнюю часть корпуса и сделали ее CAD-модель. На основе этой модели предприятие своими силами изготавливает соответствующую деталь и использует ее в качестве запчасти.
Обратное проектирование картера трансмиссии
Еще один пример. Заказчик предоставил нам картер трансмиссии. Была поставлена задача получить CAD-модель и чертежи с реально существующей трансмиссии, что нами и было сделано.
3D-сканирование и получение 3D-модели цоколя фонарного столба
А здесь вы видите цоколь фонарного столба, знакомый всем москвичам. Существует проект по замене всех таких цоколей в Москве. Требовалось получить модель современного цоколя и внести в нее определенные изменения. Мы создали 3D-модель и полностью ее оцифровывали. Зачем это делалось? Необходимо было соблюсти точные размеры, поскольку под цоколями находится электрика и разнообразное дополнительное оборудование. Кроме того, крепежи, которые смыкаются на столбе, заменены не будут. Таким образом, проект нового цоколя с применением обратного проектирования позволил минимизировать изменения и, соответственно, сократить расходы на них.
Защита картера двигателя мотоцикла
И наконец, такой проект. Нашими клиентами были коллекционеры редких мотоциклов. Если происходит поломка, детали надо заказывать из-за рубежа – в России их купить практически невозможно. Мы получали запчасти, аналогичные поврежденным (снятые с другого мотоцикла такой же модели), или детали, которые часто ломаются. Мы сканировали эти детали, строили по ним CAD-модель, и теперь они изготавливаются в России.
Подытожу: реверс-инжиниринг – это когда у нас есть нечто физическое, но нет цифрового, и мы объект из физического мира переносим в цифровой, где уже можем его дорабатывать, подготавливать к чему-либо, либо просто отправлять на производство.
Компания iQB Technologies приглашает вас на выставку «Металлообработка-2019» в ЦВК «Экспоцентр»! Мы представим уникальные 3D-решения на нашем стенде в павильоне 5.1, а также проведем практическую конференцию с демонстрацией 3D-сканирования и моделирования (29 мая с 11:00 до 14:00). Подробности и регистрация на конференцию по ссылке.