------ By adrenaline, special for LIMB.cc ------
Всем привет!
Сегодня я расскажу вам о том, что такое реверс-инжиниринг, какой он бывает, что для этого нужно и начнем свой путь в этом деле с реверса простого кода!
Содержание:
Что же такое, этот ваш "реверс"?
Реверс-инжиниринг - процесс анализа и получения кода из готовой программы, аля мы смотрим как она устроена внутри и какие функции за что отвечают. Но! Реверс это не только про код, программы, кейгены и прочую радость, это про сам процесс анализа и попытку понять, как вещь работает внутри. Реверсы могут разобраться как работает Cisco коммуникатор, как работает движок бмв и сделать свой, но лучше, могут разобраться как работают те самы рации с криптографией сигнала. Думаю вы поняли что они есть почти во всех сферах нашей жизни. Если вы в детстве что-нибудь разбирали, то вас тоже можно назвать в некой степени реверсером. Реверс нужен всем и везде, поэтому даже на белом рынке работы годного специалиста заберут с руками и ногами, дав ему оффер с неплохой з/п, особенно на фоне импортозамещения, когда все железо и софт перестало работать в один миг.
Как работает код?
Теперь мы подходим к самому душному, но очень важному пункту. Представим у нас есть код на Python. Как же он работает? Сначала мы пишем сам код в текстовом файлике primer.py, затем мы прописываем "python primer.py". В это время компилятор берет твой код и превращает в байт-код. Почему? Потому что интерпретатор (та программа, которая как раз и отвечает за исполнение кода) не понимает print('') и прочие функции, она лишь понимает байт-код. После превращения твоего кода в байт-код он попадает в сердце аля интерпретатор, а он в свою очередь превращает байт-код в машинный код, те самые нули и единицы, которые понимает процессор. Если проще, то вот схема:
Текст кода -> Компилятор -> Интерпретатор -> Процессор
(Если хотите больше углубиться в тему, то посмотрите видос от Merion Academy, сам по их видосам учился)
Окей, а что мы будем реверсить? Нули и единицы? Неа, мы будем реверсить вывод, который вышел из компилятора. И тут у вас может возникнуть логичный вопрос: "можем ли мы просто прогнать код через декомпилятор и получить готовый сурс?" - Нет, точнее можем, но мы получим кашу. Компилятор - штука хитрая и умная. Он не будет тащить переменные, которые в коде не используются, он почистить и оптимизирует его, а также выкинет привычные и понятные нам переменные и функции на адреса памяти и регистров. Прогоняя код через декомпилятор мы получаем то, что видит сердце, исполнитель кода. Так сказать, углубляемся по полной :) Цель реверса - сделать/поменять что-то, чтобы это что-то делало что-то по другому, не так, как задумывал разработчик, ну или просто понять что там под капотом.
Какие инструменты для этого нужны?
Если вы хоть чутка сувались в эту тему, то скорее всего слышали про какую IDA или Ghidra - самые популярные декомпиляторы. IDA Pro - Излюбленный инструмент всех реверсеров, но она платная (есть бесплатная версия, ну и кряки, куда же без них), Ghidra - инструмент АНБ США, те самые ребята, у которых сноуден документы слил про Prism и прочее, из минусов оба этих инструмента выглядят очень страшно и для новичка это будет испытанием, понять куда жать, чтобы просто найти функцию, поэтому для этой статья и зеленых ребят я советую и буду использовать Binary Ninja, беслатной версии с головой хватит для x86, x86_64 кода. Предлагаю взглянуть на нее.
1 - Symbols. Там лежат абсолютно все функции из кода, пользуюсь для быстрой навигации и поиска нужной функции
2 - Types. Показывает что и какие библиотеки тянет программа
3 - Memory map. Показывает начало и конец памяти программы, для нашей сегодняшней задачи этот раздел не сильно важен.
4 - Debugger. Позволяет отслеживать ход программы по коду и расставлять red flag, т.е места, где программа должна остановиться. Позволяет проверить верность найденной вами функции, чтобы вы не пропатчили (изменили) функцию активации и лицензии, а при запуске программы у вас начинается свистопляска из ошибок и кривой работы проги. Советую пользоваться этой функцией всегда, статический анализ (без реального запуска) не всегда дает верные результаты, особенно если это делает человек :)
5 - Graph. Позволяет увидеть с какими другими функциями и участками кода взаимодействует функция, по графу легко понять как работает if else в программе.
6 - Cross references. Почти как граф, только показывает откуда руки растут, точнее какая функция стоит над вами выбранной. (например покажет вам функцию проверку кода активации над функцией выдачей ошибки)
7 - Variables. Показывает переменные в вашей функции
8 - Поиск. Просто жмите Ctrl + F и ищите что вам надо.
Всем привет!
Сегодня я расскажу вам о том, что такое реверс-инжиниринг, какой он бывает, что для этого нужно и начнем свой путь в этом деле с реверса простого кода!
Не удалось прогрузить медиа
Содержание:
- Что такое реверс и кто эти люди
- Как работает код и наши цели
- Какие инструменты использовать и небольшой обзор
- Заставляем наш код всегда говорить "YES"
- Вывод
Что же такое, этот ваш "реверс"?
Реверс-инжиниринг - процесс анализа и получения кода из готовой программы, аля мы смотрим как она устроена внутри и какие функции за что отвечают. Но! Реверс это не только про код, программы, кейгены и прочую радость, это про сам процесс анализа и попытку понять, как вещь работает внутри. Реверсы могут разобраться как работает Cisco коммуникатор, как работает движок бмв и сделать свой, но лучше, могут разобраться как работают те самы рации с криптографией сигнала. Думаю вы поняли что они есть почти во всех сферах нашей жизни. Если вы в детстве что-нибудь разбирали, то вас тоже можно назвать в некой степени реверсером. Реверс нужен всем и везде, поэтому даже на белом рынке работы годного специалиста заберут с руками и ногами, дав ему оффер с неплохой з/п, особенно на фоне импортозамещения, когда все железо и софт перестало работать в один миг.
Как работает код?
Теперь мы подходим к самому душному, но очень важному пункту. Представим у нас есть код на Python. Как же он работает? Сначала мы пишем сам код в текстовом файлике primer.py, затем мы прописываем "python primer.py". В это время компилятор берет твой код и превращает в байт-код. Почему? Потому что интерпретатор (та программа, которая как раз и отвечает за исполнение кода) не понимает print('') и прочие функции, она лишь понимает байт-код. После превращения твоего кода в байт-код он попадает в сердце аля интерпретатор, а он в свою очередь превращает байт-код в машинный код, те самые нули и единицы, которые понимает процессор. Если проще, то вот схема:
Текст кода -> Компилятор -> Интерпретатор -> Процессор
(Если хотите больше углубиться в тему, то посмотрите видос от Merion Academy, сам по их видосам учился)
Окей, а что мы будем реверсить? Нули и единицы? Неа, мы будем реверсить вывод, который вышел из компилятора. И тут у вас может возникнуть логичный вопрос: "можем ли мы просто прогнать код через декомпилятор и получить готовый сурс?" - Нет, точнее можем, но мы получим кашу. Компилятор - штука хитрая и умная. Он не будет тащить переменные, которые в коде не используются, он почистить и оптимизирует его, а также выкинет привычные и понятные нам переменные и функции на адреса памяти и регистров. Прогоняя код через декомпилятор мы получаем то, что видит сердце, исполнитель кода. Так сказать, углубляемся по полной :) Цель реверса - сделать/поменять что-то, чтобы это что-то делало что-то по другому, не так, как задумывал разработчик, ну или просто понять что там под капотом.
Какие инструменты для этого нужны?
Если вы хоть чутка сувались в эту тему, то скорее всего слышали про какую IDA или Ghidra - самые популярные декомпиляторы. IDA Pro - Излюбленный инструмент всех реверсеров, но она платная (есть бесплатная версия, ну и кряки, куда же без них), Ghidra - инструмент АНБ США, те самые ребята, у которых сноуден документы слил про Prism и прочее, из минусов оба этих инструмента выглядят очень страшно и для новичка это будет испытанием, понять куда жать, чтобы просто найти функцию, поэтому для этой статья и зеленых ребят я советую и буду использовать Binary Ninja, беслатной версии с головой хватит для x86, x86_64 кода. Предлагаю взглянуть на нее.
Не удалось прогрузить медиа
1 - Symbols. Там лежат абсолютно все функции из кода, пользуюсь для быстрой навигации и поиска нужной функции
2 - Types. Показывает что и какие библиотеки тянет программа
3 - Memory map. Показывает начало и конец памяти программы, для нашей сегодняшней задачи этот раздел не сильно важен.
4 - Debugger. Позволяет отслеживать ход программы по коду и расставлять red flag, т.е места, где программа должна остановиться. Позволяет проверить верность найденной вами функции, чтобы вы не пропатчили (изменили) функцию активации и лицензии, а при запуске программы у вас начинается свистопляска из ошибок и кривой работы проги. Советую пользоваться этой функцией всегда, статический анализ (без реального запуска) не всегда дает верные результаты, особенно если это делает человек :)
5 - Graph. Позволяет увидеть с какими другими функциями и участками кода взаимодействует функция, по графу легко понять как работает if else в программе.
6 - Cross references. Почти как граф, только показывает откуда руки растут, точнее какая функция стоит над вами выбранной. (например покажет вам функцию проверку кода активации над функцией выдачей ошибки)
7 - Variables. Показывает переменные в вашей функции
8 - Поиск. Просто жмите Ctrl + F и ищите что вам надо.
Заставляем наш код говорить всегда "YES"
Помните как вы скачивали кряк, а там нужно было всего-лишь ввести любую белеберду в поле ключа активации и все прекрасно работало? Так вот, это патчинг условия, тот самый always TRUE. Сейчас вы сможете сами сделать такое. Возьмем для примера самый простой C++ код с условием if else. Задача нашей проги - Попросить пользователя ввести число 571, если ввод верный, то нам скажут YES, если нет, то NO. Вот этот код:
C++:
#include <iostream>
int main() {
int number;
std::cout << "Введи число 576: ";
std::cin >> number;
if (number == 576) {
std::cout << "YES" << std::endl;
} else {
std::cout << "NO" << std::endl;
}
return 0;
}
Копируем, сохраняем в primer.cpp и идем в терминал. Прописываем следущее:
g++ - компилятор C++ кода
duty.cpp - название нашего сырка (кода)
-o - задаем название файла выхода, т.е duty.
Проверяем что работает как надо:
Приступаем к реверсу!
Берем наш исполняемый файл duty и закидываем его в окно binary ninja
Здесь мы видим наш псевдокод (попытка декомпилятора привести машинную кашу в читаемый вид):
Видите 0x240 в if (var_10 != 0x240)?
0x240 - наше 576 в шестнадцатеричной системе счисления
А само условие с != говорит что если ввели число, которое не равно 576, то нужно вывести NO, иначе YES. Смена логики происходит в основном из-за работы процессорных функций и самого декомпилятора, который пытается создать нормальный код. Пррсто как интересный факт, на нашу работу это не влияет.
Теперь сделаем так, чтобы наша программа принимала любое число как верное, а т.е сделать тот самый патчинг. У нас существует несколько путей. Мы можем заменить инструкцию с если не равно - JNE на если равно - JE, но тогда программа будет отвергать 576, а другие числа принимать. Согласитесь, как-то колхозно и не подходит под ввод любой белеберды, как я говорил в начале? Поэтому мы сделаем патч branch, не простой, а never. Наш код будет пропускать развилку и просто прыгать дальше по коду, выполняя ниже стоящие функции. После патча мы всегда будем получать YES. Есть еще always branch, он заставляет прогу выполнять всегда действие, которое верно условию. В нашем случае always branch выводил бы NO. Выделяем строчку с if (var_10 != 0x240) простым кликом, жмем ПКМ, Patch -> Never branch. Вот так это должно выглядить:
Теперь жмём Ctrl + S и идем проверять! Результат вы увидите такой:
Поздравляю! Теперь вы начинающий реверсер!
Code:
g++ duty.cpp -o duty
g++ - компилятор C++ кода
duty.cpp - название нашего сырка (кода)
-o - задаем название файла выхода, т.е duty.
Проверяем что работает как надо:
Не удалось прогрузить медиа
Приступаем к реверсу!
Берем наш исполняемый файл duty и закидываем его в окно binary ninja
Не удалось прогрузить медиа
Здесь мы видим наш псевдокод (попытка декомпилятора привести машинную кашу в читаемый вид):
Не удалось прогрузить медиа
Видите 0x240 в if (var_10 != 0x240)?
0x240 - наше 576 в шестнадцатеричной системе счисления
А само условие с != говорит что если ввели число, которое не равно 576, то нужно вывести NO, иначе YES. Смена логики происходит в основном из-за работы процессорных функций и самого декомпилятора, который пытается создать нормальный код. Пррсто как интересный факт, на нашу работу это не влияет.
Теперь сделаем так, чтобы наша программа принимала любое число как верное, а т.е сделать тот самый патчинг. У нас существует несколько путей. Мы можем заменить инструкцию с если не равно - JNE на если равно - JE, но тогда программа будет отвергать 576, а другие числа принимать. Согласитесь, как-то колхозно и не подходит под ввод любой белеберды, как я говорил в начале? Поэтому мы сделаем патч branch, не простой, а never. Наш код будет пропускать развилку и просто прыгать дальше по коду, выполняя ниже стоящие функции. После патча мы всегда будем получать YES. Есть еще always branch, он заставляет прогу выполнять всегда действие, которое верно условию. В нашем случае always branch выводил бы NO. Выделяем строчку с if (var_10 != 0x240) простым кликом, жмем ПКМ, Patch -> Never branch. Вот так это должно выглядить:
Не удалось прогрузить медиа
Теперь жмём Ctrl + S и идем проверять! Результат вы увидите такой:
Не удалось прогрузить медиа
Поздравляю! Теперь вы начинающий реверсер!
Вывод
Сегодня мы узнали что такое реверс-инжиниринг, что можно реверсить, как вообще компьютер понимает код, узнали какими инструментами это делается и реверснули свою первую программу на C++.
Если тема сыщет интерес у вас, то я покажу как реверсить более сложные программы с ключами-активации
Если тема сыщет интерес у вас, то я покажу как реверсить более сложные программы с ключами-активации
Всем удачи и успехов в дальнейшем обучении!)
------ By adrenaline, special for LIMB.cc ------
------ By adrenaline, special for LIMB.cc ------
------ By adrenaline, special for LIMB.cc ------
------ By adrenaline, special for LIMB.cc ------
------ By adrenaline, special for LIMB.cc ------
👍48
🔥3
😮9
🤔14
😢12
💯8
LIMB