Blog. Just Blog

Мульти-плагин для PEiD, DiE, Bit Detector, SCANiT, ExeScan, FastScanner и PE Tools

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Практически все современные анализаторы исполняемых файлов поддерживают внешние модули (плагины), значительно расширяющие их функционал. Это могут быть утилиты для извлечения ресурсов, узкоспециализированные анализаторы протекторов, распаковщики, редакторы исполняемых файлов и множество других модулей. Все хорошо и здорово, если бы не одно "но". Анализаторы чаще всего не совместимы по своим функциям взаимодействия с плагинами. Для решения этой проблемы некоторые авторы начали делать мульти-плагины, которые могут работать с несколькими типами анализаторов. Если мне не изменяет память, то первым таким плагином стал модуль определения точной версии ASProtect под названием VerA от известного реверсера PE_Kill. Он одинаково хорошо работал в PEiD и DiE. Я решил пойти дальше и сделать мульти-плагин, который поддерживает шесть различных анализаторов, а именно PEiD, DiE, Bit Detector, SCANiT, ExeScan и FastScanner, а также подходит для программы PE Tools. Остальные анализаторы исполняемых файлов и подавляющее большинство утилит для реверса, поддерживающие внешние модули, "заточены" на формат плагинов от PEiD, поэтому я их в этом списке даже не упоминаю.

Начнем с формата плагинов для PEiD. Тут используются две функции - LoadDll и DoMyJob. Первая используется для получения имени плагина, вторая - непосредственно для работы плагина с загруженным файлом. С LoadDll ничего сложного:
  1. ;-----------------------------------------------------------
  2. ; PEiD - запрос имени плагина
  3. ;-----------------------------------------------------------
  4. proc LoadDll
  5.         ; Вернуть в регистре EAX указатель на строку названия
  6.         mov     eax,plugName
  7.         ret
  8. endp
Забегая вперед скажу, что подобная функция используется еще в двух анализаторах, так что при написании реального плагина их можно без проблем объединить. В статье для удобства понимания эти функции разделены.
  1. ;-----------------------------------------------------------
  2. ; PEiD - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; hwnd - хэндл главного окна PEiD
  6. ; filename - указатель на полный путь загруженного файла
  7. ; lpreserved и lpparam зарезервированы и не используются
  8. ;-----------------------------------------------------------
  9. proc DoMyJob hwnd:DWORD,filename:DWORD,lpreserved:DWORD,lpparam:DWORD
  10.  
  11.         ; Окно с именем загруженного файла
  12.         invoke  MessageBox,[hwnd],[filename],plugName,MB_OK
  13.  
  14.         pop     ebp
  15.         mov     eax,TRUE
  16.         retn
  17. endp 
DoMyJob передает в плагин хэндл окна запущенного PEiD и указатель на строку загруженного файла. Плагин должен использовать этот хэндл окна в качестве родительского для создания своих диалоговых окон, а, зная полный путь до загруженного файла, выполнять с ним необходимые действия. В нашем случае просто откроется окно с именем загруженного файла. Примеры создания плагинов для PEiD на других языках вы можете посмотреть в SDK.

Plugin SDK для PEiDPlugin SDK для PEiD

PEiD.Plugin.SDK.zip (5,852 bytes)

Анализатор DiE предоставляет гораздо больше возможностей для плагинописателей, Однако минимальный набор обязательных функций не намного отличается от предыдущего. Это DiePlugName - получение имени плагина и DiePlugProc - выполнение действий с загруженным файлом.
  1. ;-----------------------------------------------------------
  2. ; DiE - запрос имени плагина
  3. ;-----------------------------------------------------------
  4. proc DiePlugName
  5.         ; Вернуть в регистре EAX указатель на строку названия
  6.         mov     eax,plugName
  7.         ret
  8. endp
  1. ;-----------------------------------------------------------
  2. ; DiE - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; hwnd - хэндл главного окна DiE
  6. ; filename - указатель на полный путь загруженного файла
  7. ; die_name - указатель на полный путь DiE
  8. ;-----------------------------------------------------------
  9. proc DiePlugProc hwnd:DWORD, filename:DWORD, die_name:DWORD
  10.         ; Окно с именем загруженного файла
  11.         invoke  MessageBox,[hwnd],[filename],plugName,MB_OK
  12.         ret
  13. endp
В SDK описаны еще несколько функций, при помощи которых вы можете выполнять предварительную проверку загруженного файла и устанавливать в информационные окна главного окна DiE свой текст. Например, это может быть информация о результатах анализа файла.

Plugin SDK для DiEPlugin SDK для DiE

DiE.Plugin.SDK.zip (8,419 bytes)

Арабский анализатор FastScanner прекрасно поддерживает плагины от PEiD, однако при этом использует и свой собственный формат плагинов. В программе "родные" плагины отмечаются галочкой. Официального PDK для этого анализатора нет, но все становится понятно, если посмотреть на его плагины в дизассемблере. Функция PluginStart возвращает название плагина, а функция Action выполняет действия с загруженным файлом.
  1. ;-----------------------------------------------------------
  2. ; FastScanner - запрос имени плагина
  3. ;-----------------------------------------------------------
  4. proc PluginStart
  5.         ; Вернуть в регистре EAX указатель на строку названия
  6.         mov     eax,plugName
  7.         ret
  8. endp
  1. ;-----------------------------------------------------------
  2. ; FastScanner - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; hwnd - хэндл главного окна FastScanner
  6. ; filename - указатель на полный путь загруженного файла
  7. ;-----------------------------------------------------------
  8. proc Action hwnd:dword,filename:dword
  9.         ; Окно с именем загруженного файла
  10.         invoke  MessageBox,[hwnd],[filename],plugName,MB_OK
  11.         ret
  12. endp
SCANiT - это натурально война и немцы в одном флаконе. Мало того, что я не нашел никаких нормальных описаний формата плагинов для этого анализатора, так еще и поведение основной программы с плагинами тоже вызывает грусть. Пришлось разбираться в отладчике и дизассемблере с единственным имеющимся плагином, написанным на Дельфи. GetPluginName возвращает имя плагина, а через StartPlugin в плагин по идее должны передаваться хэндл окна и имя загруженного файла. Но это только по идее. Фактически хэндл окна передается в регистре EAX, при запуске плагина главное окно SCANiT вообще скрывается, а имя файла передается в регистре EDX. Может быть на языках высокого уровня это выглядит как-то получше, но на Ассемблере получается именно так.
  1. ;-----------------------------------------------------------
  2. ; SCANiT - запрос имени плагина
  3. ;-----------------------------------------------------------
  4. proc GetPluginName
  5.         ; Вернуть в регистре EAX указатель на строку названия
  6.         mov     eax,plugName
  7.         ret
  8. endp
  1. ;-----------------------------------------------------------
  2. ; SCANiT - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; hwnd - хэндл главного окна SCANiT
  6. ; filename - указатель на полный путь загруженного файла
  7. ;-----------------------------------------------------------
  8. ; ВАЖНО!! Реальный указатель на путь файла приходит в
  9. ; регистре EDX, а хэндл окна в регистре EAX
  10. ;-----------------------------------------------------------
  11. proc StartPlugin hwnd:dword,filename:dword
  12.         ; EAX -> hwnd
  13.         ; EDX -> filename
  14.  
  15.         ; Окно с именем загруженного файла
  16.         invoke  MessageBox,eax,edx,plugName,MB_OK
  17.         ret
  18. endp
К счастью, при такой глюкавости SCANiT не получил распространения и хранится у меня только для коллекции. Сейчас, насколько я знаю, этот проект вообще закрыт.

Plugin SDK для SCANiTPlugin SDK для SCANiT

SCANiT.Plugin.SDK.zip (1,107 bytes)

Анализатор ExeScan по формату плагинов очень похож на PEiD, разница только в названиях экспортируемых функций и в порядке следования параметров. Его автору - PuNkDuDe - можно было бы запросто использовать формат PEiD, но он предпочел пойти своим путем. Ничего страшного, поддержка этого анализатора добавляется двумя функциями. LibName возвращает название плагина, а DoFeature выполняет нужные действия с загруженным файлом.
  1. ;-----------------------------------------------------------
  2. ; ExeScan - запрос имени плагина
  3. ;-----------------------------------------------------------
  4. proc LibName
  5.         ; Вернуть в регистре EAX указатель на строку названия
  6.         mov     eax,plugName
  7.         ret
  8. endp
  1. ;-----------------------------------------------------------
  2. ; ExeScan - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; filename - указатель на полный путь загруженного файла
  6. ; hwnd - хэндл главного окна ExeScan
  7. ;-----------------------------------------------------------
  8. proc DoFeature filename:dword, hwnd:dword
  9.         ; Окно с именем загруженного файла
  10.         invoke  MessageBox,[hwnd],[filename],plugName,MB_OK
  11.         ret
  12. endp
В SDK, прилагаемом в комплекте к анализатору, есть примеры пагинов и на других языках программирования, так что можете посмотреть сами.

Plugin SDK для ExeScanPlugin SDK для ExeScan

ExeScan.Plugin.SDK.zip (6,102 bytes)

Остался последний анализатор - Bit Detector. Его автор также отказался от использования де-факто стандартных форматов плагинов PEiD. Так, в функции PluginName, получающей информацию о плагине, обязательным значением является не только название плагина, но и имя его автора.
  1. ;-----------------------------------------------------------
  2. ; Bit Detector - запрос имени плагина и автора
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; PluginInfo - указатель на структуру (2 DWORD), в которую
  6. ; надо записать указатели на имя автора плагина и название
  7. ;-----------------------------------------------------------
  8. proc PluginName PluginInfo:DWORD
  9.         ; Указатель на структуру
  10.         mov     eax,[PluginInfo]
  11.         ; Первый DWORD - указатель на имя автора
  12.         mov     dword [eax],plugAuthor
  13.         ; Второй DWORD - указатель на название плагина
  14.         mov     dword [eax+4],plugName
  15.         mov     eax,TRUE
  16.         ret
  17. endp
В качестве параметра в PluginName передается указатель на структуру из двух указателей DWORD, которую плагин должен заполнить. В первый указатель записывается адрес строки имени автора, во второй указатель записывается адрес строки с названием плагина. С основной функцией взаимодействия RunPlugin никаких проблем нет, тут все понятно.
  1. ;-----------------------------------------------------------
  2. ; Bit Detector - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; hwnd - хэндл главного окна Bit Detector
  6. ; filename - указатель на полный путь загруженного файла
  7. ;-----------------------------------------------------------
  8. proc RunPlugin hwnd:dword,filename:dword
  9.         ; Окно с именем загруженного файла
  10.         invoke  MessageBox,[hwnd],[filename],plugName,MB_OK
  11.         ret
  12. endp 
Plugin SDK для Bit DetectorPlugin SDK для Bit Detector

Bit.Detector.Plugin.SDK.zip (21,056 bytes)

А теперь попробуем совместить несовместимое, добавим в наш мульти-плагин поддержку программы PE Tools. Эта программа не предназначена для анализа файлов, поэтому в ней не предусмотрены штатные функции по передаче информации о выбранном файле в плагины. По сути плагины для PE Tools - это самостоятельные программы, которые запускаются в контексте приложения PE Tools и больше никак с ним не взаимодействуют. Используются всего две функции - GetPTPluginName для получения названия плагина и StartPTPlugin для его запуска. Первая функция мало чем отличается от описанных выше.
  1. ;-----------------------------------------------------------
  2. ; PE Tools - запрос имени плагина
  3. ;-----------------------------------------------------------
  4. proc GetPTPluginName
  5.         ; Вернуть в регистре EAX указатель на строку названия
  6.         mov     eax,plugName
  7.         ret
  8. endp
А вот на вторую посмотрим повнимательнее. Как написано в SDK, ей передается единственный параметр - хэндл главного окна PE Tools. В этом окне есть стандартный список SysListView32, в первой колонке которого указан полный путь к файлам запущенных процессов. Значит, зная хэндл главного окна, мы можем найти хэндл этого списка, получить имя файла, на котором стоит курсор, и затем выполнить с ним нужные нам действия. Для этого нам потребуется вспомогательная функция, перебирающая дочерние окна.
  1. ;-----------------------------------------------------------
  2. ; PE Tools - выполнение действий с загруженным файлом
  3. ;-----------------------------------------------------------
  4. ; Параметры:
  5. ; hwnd - хэндл главного окна PE Tools
  6. ;-----------------------------------------------------------
  7. proc StartPTPlugin hwnd:dword
  8.         ; Найти окно со списком процессов
  9.         invoke  EnumChildWindows,[hwnd],EnumChildProc,0
  10.  
  11.         ; Окно с именем выбранного файла
  12.         invoke  MessageBox,[hwnd],buff,plugName,MB_OK
  13.         ret
  14. endp
В сегменте данных добавится несколько переменных и структура для работы со списками.
  1. szPTClass       db 'SysListView32',0
  2. szIdleProc      db '[System Idle Process]',0
  3. buff            rb MAX_PATH  ; Путь к файлу
  4. lvi             LV_ITEM      ; Структура для работы со списком
  1. ;-----------------------------------------------------------
  2. ; PE Tools - перебор дочернего списка
  3. ;-----------------------------------------------------------
  4. proc    EnumChildProc  hwnd: DWORD, lParam:DWORD
  5.         ; Найти список процессов
  6.         invoke  GetClassName,[hwnd],buff,MAX_PATH
  7.         invoke  lstrcmp,buff,szPTClass
  8.  
  9.         ; Очистить строку
  10.         mov     byte [buff],0
  11.  
  12.         or      eax,eax
  13.         jnz     @f
  14.  
  15.         ; Получить выбранную строку списка
  16.         invoke  SendMessage,[hwnd],LVM_GETSELECTEDCOUNT,0,0
  17.         or      eax,eax
  18.         jz      @f
  19.         invoke  SendMessage,[hwnd],LVM_GETSELECTIONMARK,0,0
  20.         cmp     eax,-1
  21.         je      @f
  22.  
  23.         ; Получить текст из ячейки списка
  24.         mov     [lvi.iItem],eax
  25.         mov     [lvi.mask],LVIF_TEXT
  26.         mov     [lvi.iSubItem],0
  27.         mov     [lvi.pszText],buff
  28.         mov     [lvi.cchTextMax],MAX_PATH
  29.         invoke  SendMessage,[hwnd],LVM_GETITEM,0,lvi
  30.  
  31.         ; Пропустить системные процессы
  32.         invoke  lstrcmp,buff,szIdleProc
  33.         or      eax,eax
  34.         jz      @f
  35.  
  36.         ; Строка пустая
  37.         cmp     byte [buff],0
  38.         je      @f
  39.  
  40.         mov     eax,FALSE
  41.         ret
  42. @@:
  43.         ; Очистить строку
  44.         mov     byte [buff],0
  45.  
  46.         mov     eax,TRUE
  47.         ret
  48. endp
Вспомогательная функция перебирает все дочерние окна PE Tools, находит среди них окно, имеющее класс SysListView32, получает строку, на которой стоит курсор и извлекает из нее путь к файлу. Если это системный процесс, который в программе обозначается как [System Idle Process], то его надо пропустить.

Plugin SDK для PE ToolsPlugin SDK для PE Tools

PE.Tools.Plugins.SDK.zip (6,816 bytes)

Осталось объединить все полученные знания в одном плагине. В приложении готовый исходник и скомпилированный демонстрационный мульти-плагин для PEiD, DiE, Bit Detector, SCANiT, ExeScan, FastScanner и PE Tools. А реальный рабочий мульти-плагин для анализаторов исполняемых файлов вы можете посмотреть в моей утилите File Location Calculator.

Пример мульти-плагина с исходным текстом (FASM)Пример мульти-плагина с исходным текстом (FASM)

Multi.Plugin.Demo.zip (3,278 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 7042 | Комментариев: 8

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Hek (24.09.2013 в 12:48):
ManHunter, ну хз, может кому пригодятся)
ManHunter (24.09.2013 в 12:45):
И нахрена тут эта полезная информация?
Hek (24.09.2013 в 12:43):
Нашел исходники PE Tools 1.5.800.2006 rc7
sourceforge.net/projects/pe-tools/

Правда последняя версия стоит 3$ на shareit, и 5$ на sellboxhq.
ManHunter (07.05.2013 в 12:53):
Добавил поддержку FastScanner и PE Tools, архив и статья обновлены.
ManHunter (19.04.2013 в 17:55):
Добавил поддержку анализатора ExeScan, подкорректировал информацию по SCANiT, архив и статья обновлены.
IMPosTOR (18.01.2013 в 22:03):
Good job!
tnx
ManHunter (11.01.2013 в 10:36):
Это точка входа для dll, она должна быть всегда. Эта процедура вызывается в момент загрузки библиотеки.
brute (11.01.2013 в 10:24):
здесь несложно.. Процедуру DllEntry обязательно использовать или просто "так положено"?

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0052 сек.) / Память: 4.5 Mb
Наверх