Перейти к содержанию
Публикация AiManual

Локальные LLM для реверс-инжиниринга: что реально может Qwen 3.8 27B, а где нужен человек

Разбираем, что локальные LLM вроде Qwen 3.8 27B реально умеют в реверс-инжиниринге: объяснение ассемблера, именование псевдокода, скрипты для Ghidra и IDA. Плюс

Коротко

Что будет в материале

  1. 01

    Короткий ответ: что реально может локальная LLM в реверсе

  2. 02

    Какие задачи реверс-инжиниринга вообще можно закрыть LLM

  3. 03

    Существуют ли дообученные модели для реверс-инжиниринга

  4. 04

    Ограничения локальных LLM, о которых нужно знать до старта

Короткий ответ: что реально может локальная LLM в реверсе

Тема пришла из r/LocalLLaMA: пользователь /u/Danny_Davitoe спросил, способна ли локальная модель вроде Qwen 3.8 27B реверсить игры и программы, и если нет, существует ли дообученная модель под эту задачу (публикация с вопросами). Готового ответа в этой публикации нет: там два вопроса и комментарии. Поэтому дальше разбор по существу задачи, без опоры на неподтверждённые обещания.

Важная оговорка: конкретные характеристики модели под названием «Qwen 3.8 27B» в доступных источниках не подтверждены. Это название встречается только в вопросе пользователя, официальной карточки модели с таким именем в проверенных материалах нет. Поэтому все рассуждения ниже — про класс локальных LLM сопоставимого размера, а не про подтверждённые параметры конкретной версии. Точные размер, контекст и дату релиза смотрите в официальной документации Qwen или в карточке модели на Hugging Face.

Короткий вердикт: локальная LLM годится как ассистент в реверсе и не годится как исполнитель. Модель не декомпилирует бинарник, не запускает программу, не ставит breakpoint и не проверяет гипотезы запуском кода. Она объясняет незнакомый ассемблер, подписывает псевдокод осмысленными именами, пишет скрипты для Ghidra и IDA, помогает сформулировать гипотезу о структуре данных.

Рабочая схема простая: инструменты дают факты (дизассемблер, декомпилятор, трассировка, дамп памяти), модель превращает их в читаемый текст и предположения, инженер сверяет предположения с фактами. Всё, что модель выдала и вы не проверили по листингу, остаётся гипотезой, а не знанием.

ЗадачаЛокальная LLMЧто происходит на практике
Декомпиляция бинарникаНетПсевдокод строят Ghidra, IDA Pro или Binary Ninja по алгоритмам, модель к этому шагу не подключена
Объяснение фрагмента ассемблераДа, с оговоркамиИнструкции и типовые конструкции распознаются, контекст на длинных листингах теряется
Имена, комментарии, структура псевдокодаДаСамая сильная сторона: модель подписывает переменные и функции по смыслу
Скрипты для Ghidra и IDAДаГенерация Python-кода для перебора функций, поиска строк, экспорта данных
Запуск, отладка, проверка гипотезНетНужны x64dbg, GDB, WinDbg или Frida и человек за ними
Гарантия корректностиНетЛюбой вывод проверяется вручную по дизассемблеру

Какие задачи реверс-инжиниринга вообще можно закрыть LLM

Модель работает с текстом. Всё, что сводится к тексту и возвращается текстом, она берёт на себя; всё, что требует доступа к процессу или к бинарнику целиком, остаётся инструментам. На практике полезны пять сценариев.

  1. Объяснение незнакомого ассемблера. x86/x64, ARM, MIPS: модель переводит инструкции на человеческий язык, узнаёт пролог и эпилог функции, типовой switch через jump table, ручной разворот цикла.
  2. Восстановление логики по псевдокоду. Ghidra или IDA отдают читаемый, но безликий код с именами вида FUN_00401a20. Модель предлагает имена, комментарии и отмечает, где идёт разбор заголовка, где проверка длины, где копирование буфера. На выходе получается черновик, который вы сверяете с листингом.
  3. Генерация скриптов для Python API Ghidra и IDA. Перебрать все функции, найти вызовы конкретной, выгрузить список строк в JSON, отметить функции без перекрёстных ссылок. Здесь экономится время на рутине, а ошибки в API вылезают при первом запуске.
  4. Сигнатуры и байтовые паттерны. Модель помогает собрать шаблон поиска по маске и объясняет, почему паттерн из шести байт даёт ложные срабатывания.
  5. Разбор строк, ресурсов и конфигов. Локализации, XML, JSON, Lua-скрипты внутри игр. Десятки небольших текстовых файлов модель разбирает быстрее человека.

Чего в этом списке нет и не будет: автоматического поиска скрытой логики по всему exe. У модели нет ни процесса, ни полного бинарника в контексте, только тот фрагмент, который вы ей скопировали.

Декомпиляция с помощью нейросетей: где LLM помогает, а где мешает

Нейросеть не декомпилирует. Декомпиляция — это преобразование машинного кода в псевдокод по алгоритмам, этим занимаются Ghidra, IDA Pro и Binary Ninja. Языковая модель подключается после и переписывает результат в читаемый вид.

Польза реальна, если держать её в границах: предложить имя функции, объяснить странную конструкцию, восстановить типы. Вред тоже предсказуем: модель додумывает вызовы, которых в листинге нет, путает знаковые и беззнаковые сравнения, приписывает функции работу с файлом по одному похожему имени переменной.

Проверка всегда одна: утверждение модели сверяем с дизассемблером. Если в листинге нет вызова, значит вызова нет, как бы уверенно модель ни рассказывала.

Анализ ассемблера нейросетью: что получается, а что нет

На коротких фрагментах результат приличный: модель уверенно читает mov, lea, call, cmp с последующим условным переходом и описывает проверку условия. Сложности начинаются с оптимизаций компилятора.

Инлайнинг растворяет вызовы в теле вызывающей функции, векторизация превращает цикл в набор SSE или AVX-инструкций, разворачивание цикла множит похожие блоки. Для модели такой код выглядит набором операций без очевидной логики, и она начинает додумывать. Признак проблемы простой: ответ связный, но противоречит соседним инструкциям в листинге.

Второе ограничение — объём. Чем длиннее листинг, тем меньше шансов, что модель удержит связи между началом и концом функции.

Ghidra и LLM: как связать инструмент и модель

Ghidra даёт два способа связать её с моделью: скрипты на Python через встроенный интерфейс и headless-режим для пакетной обработки. Скрипт берёт псевдокод текущей функции, отправляет его на локальный HTTP-эндпоинт модели и возвращает ответ в виде комментариев или имён прямо в листинге.

Готовые плагины под эту схему встречаются в открытом доступе, но подтверждённых ссылок на конкретные репозитории в проверенных источниках нет, а совместимость зависит от версии Ghidra и движка. Если берёте сторонний плагин, проверяйте репозиторий проекта под своё окружение. Принцип у всех один: вытащить текст, отправить в модель, записать результат обратно. Никакой магии, которую модель выполняет с бинарником сама, в этой схеме нет.

Существуют ли дообученные модели для реверс-инжиниринга

Широко известной публичной модели, дообученной именно под реверс-инжиниринг, в проверенных источниках не обнаружено. Вопрос о такой модели прозвучал в том же обсуждении и остался без подтверждённого ответа (исходная публикация). Это не доказательство того, что таких моделей не существует: отсутствие подтверждения в доступных материалах и отсутствие модели — разные вещи.

Что есть на рынке: модели общего назначения с сильной подготовкой по коду, например семейства Qwen-Coder, DeepSeek-Coder и CodeLlama. Они читают ассемблер и декомпилированный псевдокод лучше универсальных чат-моделей, но узкой специализацией под реверс это не назвать.

Почему узкоспециализированных моделей для реверса почти нет

  • Датасеты. Для дообучения нужны пары «ассемблер — логика» или «бинарник — исходник» в промышленных объёмах. Открытых наборов такого рода мало, они разрознены и покрывают узкий класс программ.
  • Интерактивность. Реверс — это цикл: запустить, посмотреть, изменить входные данные, поставить breakpoint, снова запустить. Модель в этот цикл не встроена, она не может ни запустить процесс, ни заглянуть в память.
  • Вариативность. Один и тот же код после разных компиляторов и флагов оптимизации выглядит по-разному, а поверх идут упаковщики и обфускаторы. Выучить общие закономерности сложнее, чем кажется.
  • Право. Раздавать чужие бинарники в датасете нельзя, а без данных дообучение упирается в потолок качества.

Какие модели ближе всего к задачам реверса

Практический выбор выглядит так: кодовая модель с длинным контекстом и нормальной поддержкой локального запуска. Длинный контекст важнее пиковой сообразительности, потому что вам нужно подавать функцию целиком вместе с картой уже разобранных участков.

Второй параметр — размер. Модель на 27B параметров на домашней видеокарте — это компромисс между качеством рассуждений и скоростью ответа. Более крупные модели реже ошибаются в рассуждениях и держат больше контекста, но требуют заметно больше VRAM и времени на ответ, и переход на них оправдан не всегда (разбор опыта владельца RTX 5090 с Qwen 3.8 27B и Flash Next).

Ограничения локальных LLM, о которых нужно знать до старта

Контекстное окно и большие бинарники

Даже модели с контекстом в десятки тысяч токенов не вмещают бинарник целиком. Точное значение смотрите в карточке конкретной модели. Порядок величин такой: 128 000 токенов — это ориентировочно сотни килобайт текста, а дизассемблированный листинг средней программы легко превышает этот объём в разы. Точное соотношение токенов и символов зависит от токенизатора и от того, насколько «плотный» код: в исходниках и листингах один токен обычно покрывает несколько символов, но конкретную цифру для своей модели лучше проверять на реальном фрагменте.

Отсюда рабочий приём: держать модель на уровне одной-двух функций и вести отдельную карту проекта, где записаны имена, назначения функций и найденные структуры. Карту вы подаёте в контекст вместе с новым фрагментом, чтобы модель не теряла связь с уже разобранной частью.

Галлюцинации и почему им нельзя доверять в реверсе

Допустим, в функции есть косвенный вызов через таблицу, а модель уверенно пишет, что это system(). В обычном чате такая ошибка стоит одной перегенерации, в реверсе она стоит часов, ушедших на ложный след.

Правило: любой вызов, тип или имя, которых нет в листинге, отбрасываются без обсуждения. Второе правило: если ответ модели противоречит сам себе, это не повод уточнять вопрос, а сигнал вернуться к дизассемблеру и перечитать фрагмент.

Отсутствие исполняемой среды и отладчика

Модель не запускает программу. Она не поставит breakpoint, не посмотрит стек и регистры, не изменит память, не перехватит вызов. Это делает человек в x64dbg, GDB, WinDbg или Frida. Динамический анализ остаётся вне LLM, и часто именно он даёт ответ, которого статический разбор не даёт.

Следствие простое: модель не проверяет свои гипотезы. Проверка — это всегда ваш шаг.

Практические подходы: как использовать LLM в реверсе уже сейчас

Базовый процесс устроен одинаково, меняются инструменты. Если железа мало, начинать стоит с моделей поменьше и квантизации поагрессивнее: какие локальные LLM реально работают на слабом железе в задачах реверса.

  1. Разобрать цель в Ghidra или IDA: получить список функций, строк и перекрёстных ссылок.
  2. Выбрать фрагмент: одну функцию целиком, а не обрывок на десять инструкций.
  3. Отправить фрагмент локальной модели с конкретным промптом: «объясни, что делает эта функция, предложи имена переменных, отметь места, где ты не уверен».
  4. Получить гипотезу и проверить её по дизассемблеру или в отладчике.
  5. Вернуть модели результат проверки и уточнить вопрос. Цикл повторяется, пока функция не станет понятной.

Отдельная надстройка — RAG: в базу кладут документацию по API, описания форматов файлов и заметки по уже разобранным функциям, и модель получает релевантный контекст вместо догадок. Это полезно, когда в проекте десятки функций и нужно держать единые имена.

Через MCP-серверы модели можно дать доступ к файлам и инструментам, но в реверсе это повышает риск: модель с правом записи способна испортить листинг или выполнить лишнее действие. На старте достаточно ручного копирования текста или одного узкого скрипта.

Локальный запуск: Ollama, LM Studio, llama.cpp

Ollama даёт самый короткий путь: команда запуска, локальный HTTP-эндпоинт, готовые обёртки под Python. LM Studio удобен для ручной работы: загрузка GGUF-модели, чат, встроенный сервер с OpenAI-совместимым API. llama.cpp нужен, когда важна гибкость: ручной выбор квантизации, числа слоёв на GPU, длины контекста и пакетный режим без интерфейса.

Пример конфигурации Qwen 3.8 27B в LM Studio и другие сценарии локального запуска разбирали отдельно, вместе с требованиями к железу и проблемами совместимости.

Связка Ghidra + LLM через скрипты

Практическая реализация занимает один скрипт. Он берёт псевдокод текущей функции, отправляет POST-запрос на адрес локального движка (у Ollama по умолчанию порт 11434), получает текст и пишет его в комментарий к функции или в отдельный JSON-файл.

Что заложить в скрипт сразу: ограничение на длину отправляемого текста, таймаут, логирование ответов и запись результата в отдельный файл, а не прямо в базу проекта. Так проще сравнивать версии разбора и откатывать неудачные попытки.

Формулировки, которые экономят время: «перечисли, в каких местах ты не уверен», «предложи три варианта имени», «покажи, какая инструкция подтверждает твой вывод».

Железо и VRAM: хватит ли домашнего ПК для реверса с LLM

Требования к железу определяют размер модели и длина контекста. Грубая арифметика по весам: при квантизации около 4-5 бит на вес модель на 27B параметров занимает порядка 15-20 ГБ, при 8 битах — ближе к 27-30 ГБ. Это оценка по битам, а не измерение конкретного движка: фактические размеры файлов квантизаций зависят от версии GGUF, реализации и того, какие слои вы оставляете в полной точности. Точные цифры смотрите в таблицах размеров квантизаций llama.cpp и в карточке конкретной модели.

К весам добавляется KV-кэш, который растёт вместе с длиной контекста. Для реверса это критично: вы подаёте длинные листинги, значит кэш занимает заметную часть VRAM. На карте с 24 ГБ (например, RTX 3090 или 4090) модель на 27B в Q4 с умеренным контекстом помещается целиком. На 16 ГБ придётся либо брать модель меньше, либо выгружать часть слоёв на CPU и терять скорость.

Скорость ответа здесь важнее, чем в чате: разбор идёт циклами, и ожидание по 30-60 секунд на каждую функцию съедает весь выигрыш от модели. Как подбирать железо и движок под конкретную модель и сколько VRAM требуют разные квантизации и когда локальный запуск окупается мы считали в отдельных материалах.

Юридические и этические риски

Реверс для совместимости, безопасности и исследований во многих юрисдикциях допустим, но лицензионное соглашение программы может прямо запрещать декомпиляцию и модификацию. Авторское право на код при этом никуда не исчезает.

Локальная LLM юридическую рамку не меняет. Меняется другое: при локальном запуске фрагменты кода не уходят на чужой сервер. Если отправлять листинги в облачную модель, вы передаёте третьей стороне части чужой программы, и это отдельный риск.

Отдельно про игры: обход защиты, распространение модифицированных сборок и доступ к платным функциям почти всегда нарушают лицензию и могут нарушать закон. Разбор собственной копии для обучения и совместимости и взлом чужого продукта для распространения — это разные вещи. Это не юридическая консультация, конкретный случай стоит обсуждать с юристом.

Итог: стоит ли пробовать локальную LLM для реверса

Пробовать стоит, если вы уже умеете читать дизассемблер и готовы проверять каждый вывод модели. Локальная LLM сопоставимого с 27B размера ускоряет рутину: объяснение незнакомых инструкций, имена и комментарии, скрипты для Ghidra, черновые гипотезы. Заменой реверс-инженеру она не будет.

Не стоит, если ждёте автоматического реверса: загрузить exe и получить восстановленную логику не получится. Широко известных дообученных моделей под эту задачу в проверенных источниках не видно, а ограничения по контексту, галлюцинациям и отсутствию отладчика снимаются только человеком.

Стартовая конфигурация для эксперимента: кодовая модель на 24 ГБ VRAM в квантизации Q4, локальный движок с HTTP-эндпоинтом, Ghidra со скриптом отправки псевдокода и отдельный файл карты проекта. Первые выводы видно на одной-двух функциях, дальше решайте по фактической экономии времени.

Подписаться на канал