Код
#статьи

Ревёрс-инжиниринг: что это такое и зачем нужно

Загадочная история Бенджамина Баттона, который решил стать программистом.

Кадр: фильм «Игра в имитацию» / The Weinstein Company

Если вы в детстве любили разбирать игрушки, возможно, вы прирождённый специалист по ревёрс-инжинирингу, но пока не знаете об этом. Ведь занимаются они примерно тем же самым, только вместо игрушек у них программы и техника, а вместо молотка и отвёртки — специальные приложения.

Рассказываем об основах ревёрс-инжиниринга и показываем, как специалисты по кибербезопасности анализируют вирусы. А в конце статьи попробуем разобрать на винтики простенькую программу на C++, чтобы вы смогли понять, как этот процесс выглядит изнутри.

Предупреждаем: то, о чём вы сейчас узнаете, может вызвать соблазн перейти на тёмную сторону. Не надо так: лучше становитесь белым хакером и помогайте компаниям бороться с киберпреступностью.

Что такое ревёрс-инжиниринг

Представьте, что вы работаете программистом в компании по производству беспилотных автомобилей. К вам приходит руководитель отдела разработки и говорит: «Мы получили прототип программы нашего главного конкурента. Вот тебе файл в формате EXE. Сможешь разобраться, как она работает?» Что будете делать?

Решить задачу не так-то просто, если размышлять в парадигме обычной (прямой) разработки. А состоит она в следующем:

  • программист пишет код на понятном для него языке — например, Java, Python или C++;
  • затем он отдаёт файл компилятору, который превращает код из понятного для человека в бинарный файл — чтобы его мог прочитать компьютер;
  • Пользователь скачивает скомпилированную программу — например, в вышеупомянутом формате EXE и запускает её на компьютере.

Бинарный файл, или, как его ещё называют, исполняемый файл, — это набор нулей и единиц, машинный код. Простой человек со стороны не сможет прочитать его, а значит, и разобраться в устройстве программы.

Чтобы не попасть в тупик в таких ситуациях, придумали ревёрс-инжиниринг. Слово «ревёрс» означает, что процесс разработки идёт в обратную сторону — то есть бинарный файл переводят обратно в человекочитаемый формат. Вот как это выглядит:

  • разработчик получает бинарный файл, который понимает только компьютер;
  • затем он прогоняет этот файл через специальную программу и превращает в код на знакомом ему языке программирования;
  • дальше программист изучает этот файл и пытается разобраться во внутреннем устройстве программы.

Процесс ревёрс-инжиринига может показаться простым — но это иллюзия. Даже опытные специалисты по обратной разработке могут анализировать одну и ту же программу месяцами. И не факт, что её удастся расшифровать полностью.

Зачем нужно обратное проектирование

С помощью ревёрс-инжиниринга мы можем понять, как работает программа, какие данные использует, куда и что отправляет, а также какие в ней есть слабые места и как она реагирует на аварийные ситуации. Это всё поможет нам сделать свой продукт лучше и переиграть конкурентов.

Дисклеймер: здесь стоит оговориться, что почти все разработчики запрещают расшифровывать код своих программ в лицензионном соглашении. А значит, применять ревёрс-инжиниринг стоит либо на свой страх и риск, либо предварительно согласовав с компаниями-поставщиками.

Так выглядит код программы, прошедший через ревёрс-инжиниринг
Скриншот: Skillbox Media

Давайте приведём ещё пару примеров областей, в которых полезна обратная разработка.

🔵 Анализ вирусов и поиск уязвимостей. Специалисты по кибербезопасности уже давно применяют методы ревёрс-инжиниринга, чтобы анализировать вредоносное ПО. Например, они могут специально скачивать вирусы, заражать ими свои компьютеры и выяснять, как те устроены, чтобы потом разработать средства защиты.

🔵 Разработка модов для игр. В геймдеве обратная разработка позволяет создавать модификации для игр и изменять игровой процесс: добавлять новые функции и контент. Например, таким образом создавались моды для игр The Elder Scrolls V: Skyrim и Grand Theft Auto 5.

🔵 Изучение старых технологий. Бывает, что оригинальная документация для приложений утеряна или что программа написана для старых компьютеров, которые больше не производятся. Поэтому разработчикам приходится с нуля воссоздавать код приложений.

Способы и этапы обратного проектирования: как взломать программу

Хорошо, ревёрс-инжиниринг — это наука о том, как машинный код превратить в понятный для человека язык. С этим разобрались. Но как именно происходит обратная разработка? Есть три способа.

1️⃣ Перевести бинарный файл в код на языке высокого уровня. Для этого существуют специальные программы — дизассемблеры. Они понимают, как устроен машинный код, и без проблем могут перевести его на удобный для нас язык программирования — например, C++.

Единственный минус работы дизассемблера в том, что в готовом коде часто нет названий переменных и комментариев, поэтому после процедуры разработчику нужно будет довольно долго разбираться, за что отвечают отдельные блоки кода.

2️⃣ Перевести бинарный файл в код на языке ассемблера. Ассемблер — язык чуть более высокого уровня, чем машинный код, но гораздо более низкого, чем привычные нам JavaScript и Python. Любой процессор умеет работать с ассемблером, поэтому для компьютера этот способ расшифровки бинарного файла — самый простой.

Чтобы прочитать код, написанный на ассемблере, нужно разбираться в том, как устроен процессор, какие команды он использует и как вообще работает. Поэтому без подготовки проанализировать программу будет сложно.

3️⃣ Изучить, какие данные программа пересылает по Сети или внутри компьютера. Обычно программы обмениваются данными по интернету или внутри операционной системы. Поэтому, чтобы понять, как устроена программа, ревёрс-инженеры используют специальные сетевые анализаторы.

Например, существует сетевой анализатор, встроенный прямо в Google Chrome. Чтобы его открыть, нужно зайти в инструменты разработчика (клавиша F12) и перейти на вкладку «Network».

Это файлы, которые скачивает браузер при открытии Skillbox Media. Все они — картинки и иконки
Скриншот: Skillbox Media

Теперь, когда мы знаем основные способы обратной разработки, давайте перейдём к самому процессу — этапам ревёрс-инжиниринга. Всего их четыре.

  • Провести предварительное исследование. Сначала нужно внимательно изучить программу: понажимать все кнопки, попользоваться всеми функциями. Это поможет составить цельную картину того, как работает приложение.
  • Начать разборку, или демонтаж. Теперь мы должны заглянуть внутрь программы и посмотреть, как она устроена. Для этого как раз применяем один из способов обратной разработки, а затем изучаем полученный код.
  • Провести анализ. Когда мы разобрались, какие в программе есть алгоритмы и структуры данных, пора собирать всё воедино. Мы изучаем все части и пытаемся понять, как они работают вместе. Например, смотрим, в какой последовательности выполняются методы в коде и как приложение взаимодействует с внешней средой.
  • Создать документацию. После того как мы со всем разобрались, пора документировать функциональность. Нужно записать, что делают функции, какие переменные они принимают и куда отправляют данные. А потом всё это тщательно задокументировать, чтобы не возникало вопросов о том, что делают отдельные части кода.

Ещё раз напомним, что процесс может занять много времени. А чтобы понять, как работает программа, нужно иметь опыт программирования — иначе будет сложно. Хотя попробовать всё равно стоит.

Как освоить ревёрс-инжиниринг: первые шаги

Допустим, вы решили попробовать себя на нелёгкой стезе ревёрс-инжиниринга. Куда идти, что нажимать?

❗️ Хотим напомнить, что пиратство в России незаконно. За него суд может назначить штраф до 200 тысяч рублей, до двух лет исправительных работ или лишить свободы на срок до двух лет. А за распространение, использование и создание вредоносного ПО — до семи лет. Поэтому не занимайтесь взломом — занимайтесь кибербезопасностью.

Лучше всего изучить обратную разработку на своих проектах или решать задачи на специальных сайтах — например, на Crackmes. Так вы сможете вполне легально прокачать свои навыки.

Программ для ревёрс-инжиниринга достаточно. Некоторые из них могут быть вам знакомы — например, Cheat Engine. Вообще, это программа для обратной разработки, но она также позволяет накрутить игровой валюты где-нибудь в Sims или GTA.

Интерфейс Cheat Engine
Скриншот: Skillbox Media

Вот ещё список программ:

Давайте в качестве примера покажем, как выглядит обратная разработка в программе IDA Pro. Напишем код «Hello, World» на C++, скомпилируем его и попробуем расшифровать с помощью приложения.

Так выглядит код программы в среде разработки Visual Studio Code
Скриншот: Skillbox Media

Открываем программу IDA Pro и видим первый экран. Здесь нажимаем кнопку «New», чтобы начать процесс дизассемблирования:

Видите — ничего сложного пока нет. Просто нажимаем кнопку «New»
Скриншот: Skillbox Media

Дальше нам нужно загрузить файл в программу. На выбор есть два варианта — формат DLL или бинарный файл. Нам нужен первый:

Остальные настройки оставьте по умолчанию. Они нам пока не пригодятся
Скриншот: Skillbox Media

Готово — вот как выглядит наш дизассемблированный файл. Можно поизучать его и понять, из каких элементов он вообще состоит.

Так выглядит файл, который прошёл обратную компиляцию, или дизассемблирование
Скриншот: Skillbox Media

Сначала мы попадаем на вкладку «IDA View-A». Это место, где находится код языка ассемблера нашей переведённой программы. Если приглядеться, то можно увидеть строчку lea rdx, _Val ; "Hello, World". Она показывает, что мы что-то делаем со строкой «Hello, World» — а точнее, пытаемся вывести её в консоль. Но это очевидно для нас, потому что программа простая. Если бы тут был, скажем, код операционной системы Windows, то мы бы думали очень долго.

Давайте посмотрим, что находится в других вкладках 👇

Скриншот: Skillbox Media

Это вкладка «Hex View 1». Тут дизассемблированный код представлен в виде шестнадцатеричных — то есть понятных для компьютера — символов. Если понимать язык нулей и единиц, отсюда можно достать полезную информацию — например, найти повторяющиеся команды или какие-нибудь интересные данные.

Кстати, обратите внимание на функции слева. Они тоже могут дать много полезной информации:

Скриншот: Skillbox Media

Например, по этим функциям можно понять, какие системные вызовы делает программа. Правда, имена этих вызовов не вполне очевидны, поэтому часто приходится гуглить, зачем они нужны.

Переходим на следующую вкладку — «Structures».

Скриншот: Skillbox Media

Здесь можно подробнее исследовать, как устроены структуры данных в программе. Например, тут показано, какие классы вызываются, какие типы переменных они используют и какие исключения обрабатывают. Сложно, зато познавательно.

👉 Подведём итоги: с помощью всех этих данных инженеры по обратному проектированию изучают, как работает программа. Они запускают дебагеры и тыкают везде, где можно потыкать, чтобы собрать максимум информации об архитектуре. Работа непростая — но невероятно полезная. А ещё за это платят неплохие деньги — какие именно зарплатные вилки у разработчиков, владеющих языком ассемблера, мы рассказывали в отдельной статье.

Больше интересного про код — в нашем телеграм-канале.  Подписывайтесь!


Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Научитесь: Профессия Python-разработчик Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована