Различия
Показаны различия между двумя версиями страницы.
| Следующая версия | Предыдущая версия | ||
| reverseenengineering:стек [2025/06/23 23:55] – создано Lex | reverseenengineering:стек [2025/07/16 22:28] (текущий) – [Введение] Lex | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | ====== Стек ====== | + | ====== |
| + | |||
| + | ===== Введение ===== | ||
| + | |||
| + | |||
| + | Одним из важнейших аспектов обратной разработки **Reverse Engineering** является понимание **архитектуры процессора** и, в частности, | ||
| + | |||
| + | ===== Архитектура x86/x64 и стек ===== | ||
| + | |||
| + | ==== Что такое стек? ==== | ||
| + | Стек | ||
| + | * Аргументы функций | ||
| + | * Локальные переменные | ||
| + | * Возвращаемые адреса после вызова функций | ||
| + | |||
| + | ==== Регистр ESP/RSP ==== | ||
| + | В архитектуре x86: | ||
| + | * `ESP` — регистр Stack Pointer, указывает на вершину стека | ||
| + | |||
| + | В архитектуре x64: | ||
| + | * `RSP` — 64-битный стековый указатель | ||
| + | |||
| + | ==== Работа стека в ассемблере ==== | ||
| + | |||
| + | Пример простейшего вызова функции: | ||
| + | |||
| + | < | ||
| + | push ebp ; сохраняем предыдущий кадр стека | ||
| + | mov ebp, esp ; создаём новый фрейм стека | ||
| + | sub esp, 0x20 ; резервируем 32 байта под локальные переменные | ||
| + | |||
| + | ... | ||
| + | |||
| + | mov esp, ebp ; восстанавливаем стек | ||
| + | pop ebp ; восстанавливаем старый ebp | ||
| + | ret ; возвращаем управление вызывающему коду | ||
| + | </ | ||
| + | |||
| + | ==== Пример вызова функции ==== | ||
| + | |||
| + | < | ||
| + | ; вызывающий код | ||
| + | push 0x2 ; аргумент 2 | ||
| + | push 0x1 ; аргумент 1 | ||
| + | call add_numbers | ||
| + | |||
| + | ... | ||
| + | |||
| + | add_numbers: | ||
| + | push ebp | ||
| + | mov ebp, esp | ||
| + | mov eax, [ebp+8] | ||
| + | add eax, [ebp+12] | ||
| + | pop ebp | ||
| + | ret | ||
| + | </ | ||
| + | |||
| + | **Разбор: | ||
| + | * `[ebp+8]` — это первый аргумент (находится выше сохраненного EBP и адреса возврата) | ||
| + | * `[ebp+12]` — второй аргумент | ||
| + | * `ret` — извлекает адрес возврата из стека | ||
| + | |||
| + | ==== Визуализация стека ==== | ||
| + | Когда функция вызывается, | ||
| + | |||
| + | < | ||
| + | [ebp+12] — второй аргумент | ||
| + | [ebp+8] | ||
| + | [ebp+4] | ||
| + | [ebp] — сохранённый ebp вызывающей функции | ||
| + | [ebp-4] | ||
| + | [ebp-8] | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | ==== Команды работы со стеком ==== | ||
| + | ^ Команда ^ Описание ^ | ||
| + | | `push reg` | Помещает значение регистра в стек, `ESP -= 4` | | ||
| + | | `pop reg` | Извлекает значение из вершины стека в регистр, | ||
| + | | `call addr` | Помещает адрес следующей инструкции (`EIP`) в стек, затем прыгает по адресу | | ||
| + | | `ret` | Извлекает адрес возврата из вершины стека и прыгает на него | | ||
| + | |||
| + | ===== Использование в Reverse Engineering ===== | ||
| + | |||
| + | ==== Отладка с помощью x64dbg, IDA, Ghidra ==== | ||
| + | Инструменты позволяют анализировать вызовы функций, | ||
| + | * Отображение `call stack` и `stack view` | ||
| + | * Анализ локальных переменных | ||
| + | * Распознавание аргументов функции | ||
| + | |||
| + | ==== Распространённые приёмы защиты ==== | ||
| + | * **Stack obfuscation** — запутывание структуры вызовов | ||
| + | * **SEH Overwrite** — атака через обработчик исключений | ||
| + | * **Return Oriented Programming (ROP)** — использование `ret` для обхода DEP | ||
| + | |||
| + | ==== Reverse Engineering в практике: | ||
| + | * Анализируем стек для отслеживания аргументов | ||
| + | * Ищем возвращаемые значения | ||
| + | * Отслеживаем, | ||
| + | |||
| + | ===== Советы по анализу стека ===== | ||
| + | * Используйте **stack comments** в IDA для маркировки значений | ||
| + | * При анализе `ret` всегда проверяйте, | ||
| + | * Определяйте calling convention: `cdecl`, `stdcall`, `fastcall`, `thiscall` | ||
| + | * Следите за соответствием push/pop пар | ||
| + | |||
| + | ===== Заключение ===== | ||
| + | Понимание работы стека — фундаментальный навык для любого инженера, | ||
| + | |||
| + | ===== Полезные ссылки | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||