В этой статье мы разберём самую базу реверс-инжиниринга на примере простого crackme — программы, созданной для практики «хацкинга». Ничего серьёзного.
Введение
Как бы этого не хотелось, но желательно хоть немного понимать ассемблер для чтения базовых инструкций
-
Базовые инструкции
mov rax, rbx
— копирует значение из регистра rbx в rax.add al, 0x5
— добавляет 5 к регистру rax.cmp rax, rbx
— сравнивает значения в rax и rbx.jmp <адрес>
— переходит к указанному адресу в коде. Системные вызовы (syscalls): Способ взаимодействия программы с операционной системой. Например, syscall с номером 1 в Linux — это запись в стандартный вывод (stdout).
Немного примеров:
mov rax, 10
Записываем число 10 в регистр rax
. Теперь rax = 10
.
add rax, 5
Прибавляем 5 к rax
. Теперь rax = 15
.
mov rbx, rax
Копируем значение из rax
в rbx
. Теперь rbx = 15
.
cmp rbx, 12
Сравниваем rbx
с 12
Если значения равны — переходим на функцию equal
.
je equal
Если не равно — просто переходим в end.
jmp end
Вот функции equal и end
equal:
inc rbx ; rbx = 13
end:
push rbx ; кладём rbx в стек
pop rcx ; забираем из стека в rcx → rcx = 13
ret ; возврат из функции
Также рассмотрим syscall
section .text
global _start
_start:
mov rax, 1 ; номер системного вызова: sys_write
mov rdi, 1 ; 1 = stdout
mov rsi, msg ; адрес строки
mov rdx, 1 ; длина — 1 байт
syscall ; вызов ядра
; Выход из программы
mov rax, 60 ; sys_exit
mov rdi, 0 ; код возврата 0
syscall
section .data
msg:
db 'A' ; один байт с символом 'A'
И это выведет «A» при выполнении
Тут описана ОЧЕНЬ малая часть того, что умеет ассемблер, но этого, наверное, для начала хватит.
Практика: Разбор простого crackme
Для практики мы возьмём простую программу с сайта Crackmes.one, где бинарников для «взлома» очень много, хорошее место для практики «хацкинга»
Заходим на Crackmes.one, сортируем по сложности 1 (Для начала) и я выберу платформу (Unix/Linux).
Скачиваем любой crackme, который только пожелаете. Для примера возьмем этот
Распаковываем архив (пароль crackmes.one), получаем исполняемый файл (в нашем случае «hello»).
Запустим для начала программу:

Программа запрашивает имя и пароль, после чего пишет Wrong Credentials. Рассмотрим «внутренности» этого бинарника.
Я буду использовать программу Binary Ninja, но подойдут и другие, такие как Ghidra или IDA.
Откроем файл hello в Binary Ninja.
В центре видим декомпилированный псевдокод (High‑Level IL), который нам, людям, помогает легче читать код программы. Рассмотрим основные моменты:
-
Начало _start: Программа начинается с функции _start. Она вызывает системный вызов (syscall) с номером 1, что выводит строку «Please enter your name:» в консоль через stdout.
Чтение ввода: Программа использует sys_read (syscall 0) для чтения введённого имени. Введённые данные сохраняются в переменную ret_code начиная с 4-го байта, максимальная длина — 32 байта. Регистр rax содержит количество прочитанных байт. Если rax < 0, программа завершается с ошибкой.
Вывод приветствия: Программа создаёт строку Welcome {Имя пользователя}. Для этого используются два поля: welcome и welcome:6 (начиная с 6-го байта строки welcome).
Запрос пароля: Аналогично имени, программа запрашивает пароль и перезаписывает в ret_code.
Программа содержит цикл, который проверяет пароль:

Регистр r15_2 используется как индекс, начиная с длина_пароля — 1 и уменьшаясь на каждом шаге.
Программа берёт символ из строки welcome, начиная с 5-го байта, смещённого на r15_2.
-
Условие проверки: каждый символ пароля должен удовлетворять формуле:
password[i] == welcome[5 + i] + 5
где i — позиция символа с конца строки.
При успешной проверке программа выводит строку Great H4×0r Skillz!!!!!, что означает прохождение crackme.
Зная, как работает программа, мы введем имя ABC. Тогда:
Строка welcome формируется как Welcome ABC.
Позиция 5 в welcome указывает на начало имени (A).
Пароль вычисляется по «формуле»: password[i] = welcome[5 + i] + 5.
Для ABC откроем английский алфавит и пропустим для каждой буквы ещё на 4 позиции вперёд
Итоговый пароль: FGH.
Вводим ABC как имя и FGH как пароль — программа выводит Great H4×0r Skillz!

Теперь попробуем «взломать» программу, изменив её поведение с помощью дебаггера Binary Ninja:
В Binary Ninja переключаемся на вид дизассемблера (Disassembly вместо High‑Level IL).
-
Находим инструкцию, отвечающую за прибавление 5 к символу:
004010ca add al, 0x5
-
Устанавливаем точку остановки (breakpoint) на этой инструкции (F2 / ПКМ — Breakpoint).
Запускаем дебаггер в левой панели Binary Ninja.
Вводим снизу в консоли одинаковые имя и пароль (например, ABC и ABC).
Нажимаем F9 (Resume) для продолжения выполнения до точки останова.
Когда выполнение останавливается на add al, 0×5, щёлкаем ПКМ — Patch — Edit Current Line и изменяем 0×5 на 0×0. Теперь программа прибавляет 0 к символам пароля.
-
Продолжаем выполнение (F9). Программа принимает пароль ABC и выводит Great H4×0r Skillz!!!!!.
Поздравляю, теперь вы полноценный «хацкер» ну почти.
В этой статье я попытался кратко разобрать «взлом» очень легкой crackme и самых основ реверс-инжиниринга, советую найти любую другую crackme на Crackmes.one той же сложности и попытаться решить её. На легкой сложности задачи не сильно отличаются друг от друга
Если я в статье где‑либо ошибся, прошу поправить в комментариях. Эта статья моя проба пера на Хабре.
Emelian
Для «полусредних» можно предложить разобраться с декомпиляцией бинарного кода в ассемблерный и, обратно, компиляцией ассемблерного кода в бинарный ( https://erfaren.narod.ru ).