Большая часть работы, которую мы будем выполнять при обратной разработке, будет выполняться с использованием языка ассемблера. Этот простой, но порой трудоёмкий язык может раскрыть огромное количество информации об исходном коде. Если мы не можем увидеть или восстановить исходный код вредоносной программы или другого программного обеспечения, мы можем использовать такие инструменты, как дизассемблеры и отладчики, для восстановления базового ассемблера программного обеспечения. И, конечно же, это позволит нам понять, что именно пыталось сделать программное обеспечение.
В этом руководстве я просто перечислю самые базовые и фундаментальные инструкции ассемблера. Полагаю, большинство из вас будет использовать его просто как справочный материал по мере изучения, поэтому обязательно добавьте эту страницу в закладки, чтобы иметь возможность легко к ней вернуться.
Куски
Давайте начнём с самых основных понятий. Надеюсь, этот обзор вам подошёл, но если нет, вам необходимо разобраться в этих базовых понятиях, прежде чем продолжить обучение.
Бит — это наименьший фрагмент данных. Он может быть 0, 1, а также «Вкл» или «Выкл».
Байт – байт состоит из 8 бит. Диапазон его десятичных эквивалентных значений – от 0 до 255.
Слово – слово состоит из двух байтов или 16 бит.
Double Word – двойное слово состоит из двух слов или 32 бит.
Килобайт – килобайт равен 1024 (32 * 32) байтам.
Мегабайт – мегабайт равен 1 048 578 байт (1024 x 1024).
Регистры
Регистры — это области памяти компьютера, где хранятся данные. При работе с ассемблером мы обычно используем эти регистры для перемещения и обработки информации, поэтому вам следует с ними познакомиться.
Эти регистры таковы:
EAX – расширенный регистр-аккумулятор
EBX – Расширенный базовый регистр
ECX – Расширенный регистр счетчика
EDX – Расширенный регистр данных
ESI – Расширенный индекс источников
EDI – Расширенный индекс назначения
EBP – расширенный базовый указатель
ESP – расширенный указатель стека
EIP – расширенный указатель инструкций
Флаги
Флаги — это один бит, указывающий состояние регистра. Регистр флагов в современных 32-разрядных процессорах имеет длину 32 бита. Всего флагов 32. В нашем исследовании нам понадобятся только три из них: (1) флаг Z, флаг O и флаг C.
Флаг может быть только УСТАНОВЛЕН или НЕ УСТАНОВЛЕН.
Z-Флаг
Z-флаг (флаг нуля) — самый полезный флаг для взлома. Он используется примерно в 90% случаев. Он может быть установлен или сброшен несколькими опкодами, если последняя выполненная инструкция имеет результат 0.
O-флаг
Флаг O (флаг переполнения) используется примерно в 4% всех попыток взлома. Он устанавливается, когда последняя операция изменяет старший бит регистра, в котором хранится результат операции.
C-флаг
Флаг C (флаг переноса) используется примерно в 1% всех попыток взлома. Он устанавливается, если вы добавляете значение к регистру так, что оно становится больше FFFFFFFF, или вычитаете значение так, что значение регистра становится меньше нуля.
Куча
Стек — это часть памяти, где можно хранить различные данные для последующего использования. Например, стопка книг на столе, где последняя сверху (последняя входящая или LI) — это первая уходящая (LIFO).
Команда PUSH сохраняет содержимое регистра в стеке. Команда POP извлекает из стека последнее сохранённое содержимое регистра и помещает его в указанный регистр.
Инструкции
В языке ассемблера имеется небольшое количество основных команд. К ним относятся:
ADD – инструкция ADD добавляет значение к регистру или адресу памяти.
Синтаксис:
ДОБАВИТЬ пункт назначения, источник
И – инструкция И использует логическое И для двух значений
Синтаксис:
И пункт назначения, источник
CALL – инструкция CALL помещает относительный виртуальный адрес (RVA) следующей инструкции в стек и вызывает подпрограмму или подпроцедуру.
Синтаксис:
НАЗЫВАЙТЕ что-то
CDQ – Преобразование DWORD в QWORD ( Конвертация D в Q )
Синтаксис:
CDQ
CMP – Сравнить
Инструкция CMP сравнивает два значения и может установить флаги C/O/Z, если результат сравнения подходит
Синтаксис:
CMP пункт назначения, источник
DEC – Уменьшение
команда декремента используется для уменьшения значения
уменьшает значение (значение= значение -1)
Синтаксис:
DEC что-то
ДИВ – Разделение
Команда DIV используется для деления EAX на делитель. Делимое всегда равно EAX, результат сохраняется в EAX, а модуль — в EDX.
Синтаксис:
DIV делитель
IDIV – Целочисленное деление. Знаковое деление, может устанавливать флаги C/O/Z.
Синтаксис:
делитель IDIV
IMUL – целочисленное умножение
Синтаксис:
Значение IMUL
IMUL d
est, value, value
IMUL dest, значение
INC – инкремент, противоположный инструкции DEC (значение = значение +1)
Синтаксис:
регистр ИНК
INT – команда INT генерирует вызов обработчика прерываний
ПРЫЖКИ – существует множество прыжков, но наиболее распространенными и важными являются:
JE – прыжок, если равно
JG – прыжок, если больше
JGE – переход, если больше или равно
JL – прыжок, если меньше
JLE – переход, если меньше или равно
JMP – прыгать всегда
JNE – переход, если не равно
JNZ – прыжок, если не ноль
JZ – прыжок, если ноль
LEA – Эффективный адрес загрузки
Синтаксис:
LEA пункт назначения, источник
MOV – перемещение копирует значение из источника в место назначения.
Синтаксис:
MOV-адрес, источник
MUL – умножение то же самое, что и IMUL, но умножает без знака
Синтаксис:
Значение MUL
NOP – никакая операция не делает ничего
Синтаксис:
НОП
ИЛИ – логическое включающее ИЛИ
Синтаксис:
ИЛИ пункт назначения, источник
POP – инструкция POP загружает значение указателя байта/слова/двойного слова (ESP) и помещает его в место назначения.
Синтаксис:
POP-направление
PUSH – инструкция PUSH сохраняет значение в стеке и уменьшает его на размер операнда, который был помещен в стек, так что ESP указывает на значение, которое было помещено в стек.
Синтаксис:
Операнд PUSH
REP – повторить следующую строковую инструкцию. Обычно используется: REPE (повторить, если равно), REPZ (повторить, если ноль), REPNE (повторить, если не равно) и REPNZ (повторить, если не ноль).
Синтаксис :
REP-инс
Где ins — строковая операция
РЕТ – возврат
Синтаксис:
RET-цифра
SUB – вычитание. Это противоположность команде ADD. Вычитает значение источника из значения назначения и сохраняет результат в назначении.
Синтаксис:
SUB назначение, источник
ТЕСТ – выполняет логическое И, но не сохраняет значение
Синтаксис:
TEST операнд1, операнд2
XOR – инструкция XOR соединяет два значения с помощью логического исключающего ИЛИ
Синтаксис:
XOR назначение, источник
Логические операции
В таблице ниже приведены логические операции, отображающие результаты AND, OR, NOT и XOR, когда источником или назначением является 1 или 0.
В этом руководстве я просто перечислю самые базовые и фундаментальные инструкции ассемблера. Полагаю, большинство из вас будет использовать его просто как справочный материал по мере изучения, поэтому обязательно добавьте эту страницу в закладки, чтобы иметь возможность легко к ней вернуться.
Куски
Давайте начнём с самых основных понятий. Надеюсь, этот обзор вам подошёл, но если нет, вам необходимо разобраться в этих базовых понятиях, прежде чем продолжить обучение.
Бит — это наименьший фрагмент данных. Он может быть 0, 1, а также «Вкл» или «Выкл».
Байт – байт состоит из 8 бит. Диапазон его десятичных эквивалентных значений – от 0 до 255.
Слово – слово состоит из двух байтов или 16 бит.
Double Word – двойное слово состоит из двух слов или 32 бит.
Килобайт – килобайт равен 1024 (32 * 32) байтам.
Мегабайт – мегабайт равен 1 048 578 байт (1024 x 1024).
Регистры
Регистры — это области памяти компьютера, где хранятся данные. При работе с ассемблером мы обычно используем эти регистры для перемещения и обработки информации, поэтому вам следует с ними познакомиться.
Эти регистры таковы:
EAX – расширенный регистр-аккумулятор
EBX – Расширенный базовый регистр
ECX – Расширенный регистр счетчика
EDX – Расширенный регистр данных
ESI – Расширенный индекс источников
EDI – Расширенный индекс назначения
EBP – расширенный базовый указатель
ESP – расширенный указатель стека
EIP – расширенный указатель инструкций
Флаги
Флаги — это один бит, указывающий состояние регистра. Регистр флагов в современных 32-разрядных процессорах имеет длину 32 бита. Всего флагов 32. В нашем исследовании нам понадобятся только три из них: (1) флаг Z, флаг O и флаг C.
Флаг может быть только УСТАНОВЛЕН или НЕ УСТАНОВЛЕН.
Z-Флаг
Z-флаг (флаг нуля) — самый полезный флаг для взлома. Он используется примерно в 90% случаев. Он может быть установлен или сброшен несколькими опкодами, если последняя выполненная инструкция имеет результат 0.
O-флаг
Флаг O (флаг переполнения) используется примерно в 4% всех попыток взлома. Он устанавливается, когда последняя операция изменяет старший бит регистра, в котором хранится результат операции.
C-флаг
Флаг C (флаг переноса) используется примерно в 1% всех попыток взлома. Он устанавливается, если вы добавляете значение к регистру так, что оно становится больше FFFFFFFF, или вычитаете значение так, что значение регистра становится меньше нуля.
Куча
Стек — это часть памяти, где можно хранить различные данные для последующего использования. Например, стопка книг на столе, где последняя сверху (последняя входящая или LI) — это первая уходящая (LIFO).
Команда PUSH сохраняет содержимое регистра в стеке. Команда POP извлекает из стека последнее сохранённое содержимое регистра и помещает его в указанный регистр.
Инструкции
В языке ассемблера имеется небольшое количество основных команд. К ним относятся:
ADD – инструкция ADD добавляет значение к регистру или адресу памяти.
Синтаксис:
ДОБАВИТЬ пункт назначения, источник
И – инструкция И использует логическое И для двух значений
Синтаксис:
И пункт назначения, источник
CALL – инструкция CALL помещает относительный виртуальный адрес (RVA) следующей инструкции в стек и вызывает подпрограмму или подпроцедуру.
Синтаксис:
НАЗЫВАЙТЕ что-то
CDQ – Преобразование DWORD в QWORD ( Конвертация D в Q )
Синтаксис:
CDQ
CMP – Сравнить
Инструкция CMP сравнивает два значения и может установить флаги C/O/Z, если результат сравнения подходит
Синтаксис:
CMP пункт назначения, источник
DEC – Уменьшение
команда декремента используется для уменьшения значения
уменьшает значение (значение= значение -1)
Синтаксис:
DEC что-то
ДИВ – Разделение
Команда DIV используется для деления EAX на делитель. Делимое всегда равно EAX, результат сохраняется в EAX, а модуль — в EDX.
Синтаксис:
DIV делитель
IDIV – Целочисленное деление. Знаковое деление, может устанавливать флаги C/O/Z.
Синтаксис:
делитель IDIV
IMUL – целочисленное умножение
Синтаксис:
Значение IMUL
IMUL d
est, value, value
IMUL dest, значение
INC – инкремент, противоположный инструкции DEC (значение = значение +1)
Синтаксис:
регистр ИНК
INT – команда INT генерирует вызов обработчика прерываний
ПРЫЖКИ – существует множество прыжков, но наиболее распространенными и важными являются:
JE – прыжок, если равно
JG – прыжок, если больше
JGE – переход, если больше или равно
JL – прыжок, если меньше
JLE – переход, если меньше или равно
JMP – прыгать всегда
JNE – переход, если не равно
JNZ – прыжок, если не ноль
JZ – прыжок, если ноль
LEA – Эффективный адрес загрузки
Синтаксис:
LEA пункт назначения, источник
MOV – перемещение копирует значение из источника в место назначения.
Синтаксис:
MOV-адрес, источник
MUL – умножение то же самое, что и IMUL, но умножает без знака
Синтаксис:
Значение MUL
NOP – никакая операция не делает ничего
Синтаксис:
НОП
ИЛИ – логическое включающее ИЛИ
Синтаксис:
ИЛИ пункт назначения, источник
POP – инструкция POP загружает значение указателя байта/слова/двойного слова (ESP) и помещает его в место назначения.
Синтаксис:
POP-направление
PUSH – инструкция PUSH сохраняет значение в стеке и уменьшает его на размер операнда, который был помещен в стек, так что ESP указывает на значение, которое было помещено в стек.
Синтаксис:
Операнд PUSH
REP – повторить следующую строковую инструкцию. Обычно используется: REPE (повторить, если равно), REPZ (повторить, если ноль), REPNE (повторить, если не равно) и REPNZ (повторить, если не ноль).
Синтаксис :
REP-инс
Где ins — строковая операция
РЕТ – возврат
Синтаксис:
RET-цифра
SUB – вычитание. Это противоположность команде ADD. Вычитает значение источника из значения назначения и сохраняет результат в назначении.
Синтаксис:
SUB назначение, источник
ТЕСТ – выполняет логическое И, но не сохраняет значение
Синтаксис:
TEST операнд1, операнд2
XOR – инструкция XOR соединяет два значения с помощью логического исключающего ИЛИ
Синтаксис:
XOR назначение, источник
Логические операции
В таблице ниже приведены логические операции, отображающие результаты AND, OR, NOT и XOR, когда источником или назначением является 1 или 0.