справочник по плагинам API
Общий интерфейс обратного вызова для пользовательских нативных плагинов.
DE Decompiler использует общий ABI плагинов VB Decompiler. Имена экспортируемых функций сохраняют префикс VBDecompilerPlugin. Общие идентификаторы компиляторов и исторические имена команд VB/FRX относятся к API и не определяют поддерживаемые продуктом входные форматы. Для каждой операции проверяйте данные, доступные в текущем проекте DE Decompiler.
Данная документация описывает интерфейс плагина, общий для VB Decompiler и DE Decompiler. Система плагинов позволяет анализировать, изменять или расширять декомпилированный код и внутренние структуры приложения с помощью общей библиотеки (DLL).
1. Обзор архитектуры
Система плагинов работает на основе модели обратных вызовов:
- Хост-декомпилятор загружает ваш DLL-плагин.
- Он вызывает ваши экспортируемые функции для получения имени плагина и информации об авторе.
- Вызывается VBDecompilerPluginLoad, передавая указатель на его внутренний Движок обратных вызовов (Callback Engine).
- Ваш плагин взаимодействует с хостом, вызывая функции этого Движка с использованием конкретных идентификаторов действий (vlType ).
2. Экспортируемые функции
Ваша DLL должна экспортировать следующие stdcall функции:
VBDecompilerPluginName
Вызывается хостом для получения отображаемого имени вашего плагина.
void __stdcall VBDecompilerPluginName(
HWND VBDecompilerHWND, // Дескриптор главного окна
HWND RichTextBoxHWND, // Дескриптор окна редактора кода
char* Buffer, // Целевой буфер (100 байт, ANSI)
int Reserved // Зарезервировано
);
Пример использования: Скопируйте стандартную ASCII-строку (максимум 100 символов) с именем вашего плагина в Buffer.
VBDecompilerPluginAuthor
Вызывается для получения контактной информации автора.
void __stdcall VBDecompilerPluginAuthor(
HWND VBDecompilerHWND,
HWND RichTextBoxHWND,
char* Buffer, // Целевой буфер (ANSI)
int Reserved
);
Пример использования: Скопируйте строку вида "Author Name, email@domain.com" в Buffer.
VBDecompilerPluginLoad
Основная точка входа, где выполняется логика вашего плагина.
void __stdcall VBDecompilerPluginLoad(
HWND VBDecompilerHWND,
HWND RichTextBoxHWND,
char* Buffer, // Зарезервировано/Буфер
void* PluginEngine // <--- Указатель на функцию обратного вызова
);
Пример использования: Сохраните PluginEngine указатель. Вы будете использовать его для вызова команд GetValue / SetValue (см. раздел «Движок обратного вызова» ниже).
3. Движок обратного вызова
Взаимодействие с хостом осуществляется через единственный указатель функции обратного вызова, предоставляемый в PluginEngine.
Сигнатура функции:
typedef wchar_t* (__stdcall *TVBDPluginEngine)(
int vlType, // Идентификатор команды (действие)
int vlNumber, // Первичный индекс (идентификатор формы/модуля)
int vlFnNumber, // Вторичный индекс (идентификатор функции)
char* vlNewValue // Значение для установки (строка ANSI) или NULL для команд получения
);
Примечание: Движок принимает строки ANSI (char*) для входных данных, но возвращает строки Unicode (wchar_t*) для результатов.
4. Справочник по командам (vlType)
Следующие константы используются в качестве vlType аргумента для выполнения конкретных действий.
Глобальные команды проекта
Операции, связанные с файлом проекта или глобальными настройками. vlNumber и vlFnNumber обычно соответствуют 0.
| ID | Константа | Описание |
|---|---|---|
| 1 | GetVBProject | Получить полный текст декомпилированного файла проекта. |
| 2 | SetVBProject | Заменить содержимое файла проекта. |
| 3 | GetFileName | Получить полный путь к анализируемому файлу. |
| 4 | IsNativeCompilation | Возвращает "1", если целевой файл скомпилирован в нативный код, и "0" для P-Code. |
| 5 | ClearAllBuffers | Очищает внутренние структуры декомпилятора. Используйте этот метод, если ваш плагин реализует полную пользовательскую декомпиляцию для нового языка. |
| 6 | GetCompiler | Возвращает тип компилятора: 1=VB, 2=.NET, 3=Delphi, 4=Неизвестно. |
| 7 | IsPacked | Возвращает "1", если файл упакован/сжат, и "0" в противном случае. |
| 56 | GetVBDecompilerPath | Возвращает путь к исполняемому файлу DE Decompiler. |
| 100 | UpdateAll | Применяет изменения и обновляет графический интерфейс (GUI). Обязательно после установки значений, чтобы пользователь увидел изменения. |
| 64 | GetProductName | Необязательная загруженная идентичность хоста, независимая от анализируемого компилятора; см. SDK 26.6 ниже. |
Элементы управления интерфейсом
Управление элементами интерфейса DE Decompiler.
| ID | Константа | Описание |
|---|---|---|
| 8 | SetStackCheckBoxValue | Установить «Парсить парам. из стека» (Parse stack parameters) состояние флажка. "1" = отмечен, "0" = не отмечен. |
| 9 | SetAnalyzerCheckBoxValue | Установить «Анализ и оптимизация кода» (Procedure analyzer and optimizer) состояние флажка. "1" = отмечен, "0" = не отмечен. |
| 50 | GetActiveText | Получить текст, отображаемый в активном окне кода. |
| 51 | SetActiveText | Установить текст в активном окне кода. |
| 52 | GetActiveDisasmText | Получить сырой текст дизассемблирования окна дизассемблера. |
| 53 | SetActiveDisasmText | Установить сырой текст дизассемблирования в окно дизассемблера. |
| 54 | SetActiveTextLine | Прокрутить или перейти к указанному номеру строки (передаётся как строка в vlNewValue). |
| 55 | GetActiveModuleCoordinats | Получить идентификаторы активного представления. Перед использованием проверьте возвращаемое значение. |
| 58 | SetStatusBarText | Отобразить пользовательское сообщение в строке состояния приложения. |
Формы
Операции с восстановленными формами. vlNumber: индекс формы (на основе 0).
| ID | Константа | Описание |
|---|---|---|
| 10 | GetVBFormName | Получить имя формы. |
| 11 | SetVBFormName | Переименовать форму. |
| 12 | GetVBForm | Получить декомпилированные свойства формы. |
| 13 | SetVBForm | Установить свойства формы. |
| 14 | GetVBFormCount | Возвращает общее количество форм в проекте. |
Модули
Операции со стандартными модулями (.bas) или модулями классов (.cls). vlNumber: Индекс модуля (на основе 0).
| ID | Константа | Описание |
|---|---|---|
| 30 | GetModuleName | Получить имя модуля. |
| 31 | SetModuleName | Переименовать модуль. |
| 32 | GetModule | Получить заголовок с декомпилированными объявлениями модуля. |
| 33 | SetModule | Установить заголовок с декомпилированными объявлениями модуля. |
| 34 | GetModuleStringReferences | Получить список ссылок на строки, используемые в данном модуле. |
| 35 | SetModuleStringReferences | Установить ссылки на строки. |
| 36 | GetModuleCount | Возвращает общее количество модулей. |
Процедуры / Функции
Операции с конкретными функциями внутри модуля.
vlNumber: Индекс модуля.
vlFnNumber: Индекс функции (на основе 0) в пределах данного модуля.
vlNumber: Индекс модуля.
vlFnNumber: Индекс функции (на основе 0) в пределах данного модуля.
| ID | Константа | Описание |
|---|---|---|
| 20 | GetSubMain | Получить код точки входа (Sub Main). (Аргументы индекса игнорируются). |
| 21 | SetSubMain | Установить код точки входа. |
| 40 | GetModuleFunctionName | Получить имя конкретной функции. |
| 41 | SetModuleFunctionName | Переименовать функцию. |
| 42 | GetModuleFunctionAddress | Получить виртуальный адрес (VA) функции в памяти. |
| 43 | SetModuleFunctionAddress | Установить адрес функции. |
| 44 | GetModuleFunction | Получить декомпилированный код функции. |
| 45 | SetModuleFunction | Установить код функции. |
| 46 | GetModuleFunctionStrRef | Получить строковые ссылки, специфичные для данной функции. |
| 47 | SetModuleFunctionStrRef | Установить строковые ссылки для данной функции. |
| 48 | GetModuleFunctionCount | Возвращает количество функций в указанном модуле. |
| 57 | GetModuleFunctionCode | Получить код функции в режиме «Быстрая декомпиляция» (если данная функция в данный момент не обрабатывается). |
| 70 | GetModuleFunctionDisasm | Получить дизассемблирование (ASM) функции. |
| 71 | SetModuleFunctionDisasm | Установить дизассемблирование функции. |
Ресурсы (FRX)
Доступ к ресурсам в бинарном формате (иконки/изображения). vlNumber: Индекс иконки.
| ID | Константа | Описание |
|---|---|---|
| 60 | GetFrxIconCount | Количество зарегистрированных оригинальных изображений (индексы с нуля), включая нативные растровые листы ImageList. |
| 61 | GetFrxIconOffset | Устаревший скорректированный офсет: фактический офсет изображения минус 8. Перед чтением прибавьте 8. |
| 62 | GetFrxIconSize | Устаревший скорректированный размер: фактическое количество байт изображения плюс 8. Перед чтением вычтите 8. |
| 63 | GetFrxImageListInfo | Необязательные метаданные IL1 для зарегистрированного нативного цветного растрового изображения DFM ImageList; см. ниже SDK 26.6. |
5. Нативные изображения и необязательные команды SDK 26.6
Эта общая ревизия SDK реализована через VB Decompiler 26.6 и DE Decompiler 26.6. Команды 63 и 64 являются необязательными, только для чтения геттерами. Подпись обратного вызова, экспортируемые символы и существующие номера команд не изменены. Вызывайте обратный вызов в основном потоке хост-приложения.
Зарегистрированные изображения: команды 60–62
Индексы изображений отсчитываются с нуля.
GetFrxIconCount возвращает количество зарегистрированных оригинальных изображений, а не количество логических иконок внутри ImageLists. Читайте их исходные байты из исполняемого файла или DLL, возвращаемой GetFileName (команда 3).Для изображения с фактическим офсетом в файле
P и фактивным количеством байт N, команда 61 возвращает P - 8 , а команда 62 возвращает N + 8. Прибавьте 8 к возвращённому офсету и вычтите 8 из возвращённого размера:Offset := GetInteger(GetFrxIconOffset, ImageIndex); Size := GetInteger(GetFrxIconSize, ImageIndex); FileStream.Position := Offset + 8; ImageStream.CopyFrom(FileStream, Size - 8);
Проверьте индекс, скорректированный диапазон и сигнатуру полезной нагрузки перед чтением. Эти унаследованные корректировки не подразумевают наличия физического заголовка FRX в исполняемом файле Delphi. Полученная полезная нагрузка начинается с её сигнатуры BMP, PNG, JPEG, GIF, ICO или CUR; префиксы свойства DFM и заголовки контейнера ImageList исключены.
DE Decompiler регистрирует изображения во время декодирования двоичных значений формы DFM. Независимо закодированные изображения коллекции имеют отдельные записи. Оригинальное цветное растровое изображение и необязательная маска нативного ImageList остаются обычными записями растровых изображений, поэтому существующие плагины могут продолжать отображать или экспортировать полные листы.
63 — GetFrxImageListInfo
Передайте существующий индекс изображения в
vlNumber; передайте ноль для vlFnNumber и нулевой указатель ввода. Для распознанного нативного цветного растрового изображения DFM ImageList текущий ответ:IL1;<Count>;<Width>;<Height>;<Flags>;<MaskOffset>;<MaskSize>
| Поле | Значение |
|---|---|
Count | Количество логических изображений, исключая резервную ёмкость. |
Width, Height | Размеры ячейки в пикселях. |
Flags | Исходные флаги ImageList. Бит 0 указывает на наличие маски; формат цвета $20 указывает ILC_COLOR32. |
MaskOffset | Фактическое смещение файла сигнатуры растрового изображения маски. Не добавляйте 8. |
MaskSize | Фактное количество байт маски. Не вычитайте 8. |
Числовые поля представлены в десятичном формате и разделены точками с запятой. Оба поля маски равны нулю, если маска отсутствует. Цветные данные по-прежнему используют команды 61–62 и их унаследованную корректировку. Команда 63 возвращает только метаданные: она не изменяет индексы, не растеризует ячейки и не дублирует данные изображений в хосте.
Текущая
IL1 реализация распознаёт нативную версию потока $0101 с растровыми листами BMP. Обычное изображение, неподдерживаемый поток или более старшая версия хоста могут вернуть пустую строку; недействительные индексы возвращают Error. Рассматривайте пустые ответы, ошибки, некорректные данные и ответы с неизвестной версией как неподдерживаемые и сохраняйте обработку целого изображения везде, где доступна исходная запись изображения.Для индекса ячейки
K, используйте логические координаты верхнего левого угла:Columns := ColorBitmap.Width div CellWidth; X := (K mod Columns) * CellWidth; Y := (K div Columns) * CellHeight;
Требовать
0 <= K < Count. Проверить геометрию и диапазоны файлов, а также учесть DIB-сканлайны с нижним началом. Применить соответствующую однобитовую маску или предварительно умноженный альфа-канал. В более старых 32-битовых списках может встречаться полностью нулевой альфа-канал; в этом случае маска остаётся резервным вариантом.Предоставленный
shared/PluginSDK.pas и shared/modFrxImageList.pas реализует геттеры, парсер и читатель ImageList, используемые обновлённым просмотрщиком. В приведённом ниже фрагменте предполагается, что FileStream открыт для анализируемого файла:InfoText := GetString(GetFrxImageListInfo, ImageIndex);
if ParseFrxImageListInfo(InfoText, Info) then begin
ColorOffset := GetInteger(GetFrxIconOffset, ImageIndex) + 8;
ColorSize := GetInteger(GetFrxIconSize, ImageIndex) - 8;
Images := TFrxImageList.Create(FileStream, ColorOffset, ColorSize, Info);
try
Icon := Images.Icon(0);
try
Icon.SaveToFile('Image_0.ico');
finally
Icon.Free;
end;
finally
Images.Free;
end;
end;
Читатель проверяет диапазоны и геометрию и использует общие элементы управления Windows для декодирования нативного списка. Перебрать каждый распознанный список один раз. Подавить его отдельную запись маски, сравнив фактическое смещение маски с каждым скорректированным смещением изображения плюс 8. Экспортируемые ячейки ICO-файлов являются производными изображениями со списка масок/альфа-канала; автономные изображения сохраняют свои исходные полезную нагрузку.
64 — GetProductName
Передайте нули для обоих индексов и нулевой указатель ввода. Результатом будет
VB Decompiler или DE Decompiler, полученный из идентификатора загруженного хоста независимо от компилятора анализируемого файла.Скопируйте каждую возвращаемую UTF-16-строку немедленно: указатель принадлежит хосту и остаётся действительным только до следующего обратного вызова. Предоставленный
DecompilerProductName помощник проверяет ответ и переходит к VB Decompiler на более старых хостах. Сохраните исторические экспорты SDK, пути реестра и ключи локализации без изменений.Совместимость и загрузки
- Существующие плагины продолжают использовать команды 60–62 без изменений.
- Обновлённый просмотрщик сохраняет поведение целого изображения на более старых хостах.
- Распознанные нативные DFM-списки используют команду 63 для индивидуальных предварительных просмотров ячеек и экспорта ICO; независимо закодированные изображения коллекций остаются обычными записями.
- VB5/6 и графика .NET сохраняют свои существующие пути извлечения.
- Эти новые геттеры не изменяют исходный файл, восстановленный код, формы или текущий выбор.
Скачать общий SDK, включая ссылку на необязательную команду и вспомогательные средства Delphi. Ознакомьтесь с предоставленными дополнениями SDK 26.6. См. FRX Image Viewer для описания сценария работы пользователя.