Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
metasm — Это основной репозиторий для metasm — свободного ассемблера / дизассемблера / компилятора, написанного на ruby. | Kitploit
Инструменты/GitHubGitHub/jjyg/metasm
Анализ КодаОбратная инженерияШелл-кодОтладчикиАнализ Бинарных Файлов
GitHubjjyg/metasm

metasm

Это основной репозиторий для metasm — свободного ассемблера / дизассемблера / компилятора, написанного на ruby.

Репозиторий
47582177 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Сайт

Metasm, набор средств для работы с ассемблером на Ruby

  • примеры скриптов в samples/ -- читайте комментарии в начале файлов
  • все файлы распространяются на условиях LGPL

Автор: Yoann Guillot

Базовый обзор:

Metasm позволяет вам взаимодействовать с форматами исполняемых файлов (ExeFormat): PE, ELF, Mach-O, Shellcode и т.д. Существует три подхода к ExeFormat:

  • компиляция с нуля
  • декомпиляция существующего формата
  • манипуляция структурой файла

Готовые к использованию скрипты можно найти в подкаталоге samples/, смотрите комментарии в начале скриптов. Можете также попробовать аргумент --help, если чувствуете себя удачливым.

За дополнительной информацией обращайтесь в подкаталог doc/. Текстовые файлы можно скомпилировать в html с помощью скрипта misc/txt2html.rb.

Здесь представлен краткий обзор внутреннего устройства Metasm.

Ассемблирование:

При компиляции вы начинаете с исходного текста (ruby String, в основном состоящего из последовательности инструкций/данных/директив выравнивания), который разбирается.

Строка передаётся экземпляру Preprocessor (который обрабатывает #if, #ifdef, #include, #define, /* */ и т.д. и должен быть на 100% совместим с gcc -E), который для ассемблерных исходников инкапсулируется в AsmPreprocessor (для обработки макроопределений asm, 'equ' и ассемблерных комментариев ';'). Интерфейсом для этого служат ExeFormat#parse(text[, filename, lineno]) или ExeFormat.assemble (который вызывает .new, #parse и #assemble).

(Asm)Preprocessor возвращает токены в ExeFormat, который разбирает их как Data, Padding, Labels или директивы парсера. Директивы парсера всегда начинаются с точки. Они могут быть универсальными (.pad, .offset...) или специфичными для ExeFormat (.section, .import, .entrypoint...). Они обрабатываются методом #parse_parser_instruction(). Если ExeFormat не распознаёт слово, оно передаётся его экземпляру CPU, который отвечает за разбор инструкций (или выбрасывает исключение). Все эти токены хранятся в одном или нескольких массивах в атрибуте @source объекта ExeFormat (@source у Shellcode — это Array, а для PE/ELF это хэш [имя секции] => [Array разобранных данных]). Каждое непосредственное значение может быть произвольным Expression (см. далее).

Затем вы можете собрать исходник в бинарные секции с помощью ExeFormat#assemble.

Когда бинарные секции готовы, весь исполняемый файл можно записать на диск с помощью ExeFormat#encode_file(filename[, format]).

PE и ELF включают функцию автоимпорта, которая позволяет автоматически создавать данные, связанные с импортом, для известных специфичных для ОС функций (например, неразрешённые вызовы 'strcpy' приведут к генерации данных, благодаря которым бинарный файл будет слинкован с библиотекой libc во время выполнения).

Скрипты samples/{exe,pe,elf}encode.rb могут принимать asm-файл в качестве аргумента и компилировать его в работающий исполняемый файл.

Классы CPU отвечают за разбор и кодирование отдельных инструкций. Текущий парсер Ia32 использует синтаксис Intel (например, mov eax, 42). Универсальный парсер распознаёт метки как строку в начале строки, за которой идёт двоеточие (например, 'some_label:'). Можно использовать локальные метки в стиле GCC (например, '1:', на которые ссылаются как '1b' (назад) или '1f' (вперёд); их можно переопределять сколько угодно раз). Данные задаются в нотации в стиле 'db' (например, 'dd 42h', 'db "blabla", 0') См. samples/asmsyntax.rb

EncodedData:

В Metasm все бинарные данные хранятся в виде EncodedData. EncodedData имеет 3 основных атрибута:

  • #data, который содержит необработанные бинарные данные (обычно ruby String, но см. VirtualString)
  • #export, который представляет собой хэш, связывающий имя экспорта (имя метки) со смещением внутри #data
  • #reloc, который представляет собой хэш, ключи которого — смещения внутри #data, а значения — объекты Relocation. Объект Relocation имеет порядок байтов (:little/:big), тип (:u32 для беззнакового 32-битного значения) и цель (предполагаемое значение, которое здесь хранится). Цель — произвольное арифметическое/логическое Expression.

EncodedData также имеет #virtsize (например, для секций .bss) и #ptr (внутреннее смещение, используемое при декодировании).

Вы можете выполнить fixup EncodedData с помощью хэша имя переменной => значение (значение должно быть Expression или числовым значением). При этом цель каждого объекта Relocation связывается с помощью биндинга, и если результат вычислим (в Expression не используется ни одна внешняя переменная), результат кодируется с использованием информации о размере/знаке/порядке байтов объекта Relocation. Если происходит переполнение (например, попытка сохранить 128 в 8-битном знаковом Relocation), выбрасывается исключение EncodeError. Используйте тип :a32, чтобы разрешить молчаливое усечение при переполнении. Если цель Relocation не является числовой, при использовании EncodedData#fixup она остаётся неизменной, а при использовании #fixup! она заменяется на связанную цель.

Дизассемблирование:

Этот код находится в исходном файле metasm/decode.rb, в котором определён класс Disassembler.

Дисассемблеру нужны декодированный ExeFormat (чтобы можно было определить, какие данные находятся по какому виртуальному адресу) и точка входа (виртуальный адрес или имя экспорта). Затем он может начать дизассемблировать инструкции. Когда он встречает опкод, помеченный как :setip, он запрашивает у CPU адрес перехода (Expression, которое может включать значения регистров, например для jmp eax), и выполняет обратную трассировку инструкций, пока не найдёт числовое значение.

В процессе декодирования Disassembler поддерживает хэш #decoded, связывающий адреса (выражения/целые числа, нормализованные с помощью #normalize()) с объектами DecodedInstructions.

В результате дизассемблирования создаётся граф InstructionBlock. Каждый блок содержит список DecodedInstruction и указатели на следующий/предыдущий блок (по адресу).

Дисассемблер также отслеживает обращения инструкций к данным и сохраняет для них перекрёстные ссылки (Xrefs). Параметры обратной трассировки можно настраивать, а максимальную учитываемую глубину можно отдельно изменять для трассировок :r/:w (перекрёстных ссылок инструкций на память) с помощью #backtrace_maxblocks_data. При обратной трассировке Expression каждый пройденный блок помечается, чтобы обнаруживались циклы и чтобы при обнаружении нового пути кода к существующему блоку трассировку можно было возобновить по этому новому пути.

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

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

Когда обнаруживается подфункция, создаётся специальный объект DecodedFunction, содержащий сводку эффектов функции (как DecodedInstruction «на стероидах»). Это позволяет трассировщику «перешагивать» через подфункции, что значительно повышает скорость. DecodedFunctions могут быть основаны на обратных вызовах, что обеспечивает очень динамичное поведение. Вызовы внешних функций создают отдельные объекты DecodedFunctions, которые содержат некоторую информацию об API (например, информацию о коррекции стека, базовые обращения к параметрам...). Эта информация может быть получена из предварительно разобранного C-заголовка. Если прототип C-функции недоступен, используется специальная запись 'default', предполагающая, что функция имеет стандартный ABI.

Скачать инструмент