Написание плагинов для API шпиона kerberos — Архив WASM.RU

Все статьи

Написание плагинов для API шпиона kerberos — Архив WASM.RU

Сам себя непохвалишь-никто непохвалит

В данной статье я хочу показать, как пишутся плагины для API-шпиона kerberos 1.01

Самого шпиона можно взять на  WWW.WASM.RU (раздел Утилиты)

Без поддержки плагинов - создание нового API-шпиона имело бы мало смысла, т.к. можно было бы использовать любой другой. С другой стороны свои плагины дают возможность безграничного контроля над функциями используемыми приложением и самим приложением тоже.

Общие аспекты:

1. Одновременно может работать только один плагин

2. Файл плагина всегда называется ke_plug.dll

3. Плагин считается установленным, если лежит в директории с ke_core.dll

Шпион написан исключительно на ассемблере (masm32), как на самом лучшем языке программирования, и плагин тоже пишется на нем. В каждом плагине должна присутствовать функция инициализации plug_setup. Она возвращает в eax значение 0, если рапорт шпиона необходим, иначе рапорт создан не будет. Это нужно если вы собираетесь использовать kerberos как загрузчик программ.

Также в каждом плагине должна быть функция plugin - это основной код плагина.Функции plugin и plugin_setup должны являться экспортируемыми, иначе работать не будет.(Самое лучшее воспользоваться готовым примером из папки ke_plug)

Давайте, наконец, рассмотрим шаблон, который подойдет для всех плагинов.

ke_plug.asm
............................
............................
;Возвращаем значение рапорт нужен\ненужен
plug_setup proc
mov eax, REPORT_OFF
ret
plug_setup endp
; Вызывается каждый раз, при перехвате любой функции, которая есть в базе
plugin proc
pop ret_address ;Снимаем со стека адрес возврата
pop func_adr ;Адрес начала перехваченной функции
pop func_par ;Количество параметров функции
pop func_nam ;Указатель на имя функции
pop func_return_address ;Адрес возврата в вызывающую программу
pop func_idx ;Индекс функции в базе
pushfd
pushad
mov eax, func_adr
;Ваш код должен быть здесь
.if eax == FUNC_0
;Выполняем действия, которые хотим
;.............................................
;Восстанавливаем регистры и вызываем функцию
;Можно не вызывать, но надо будет сбалансировать стек от параметров функции
popad
popfd
call func_adr
;Если у нас другая функция, для которой установлен плагин 
.elseif eax == FUNC_1
.......................
;Никакая функция не подошла- просто вызываем перехваченную функцию 
.else
popad
popfd
call func_adr
.endif
;Возвращаемся туда, откуда пришли
push ret_address
ret
plugin endp

Ничего сложного. Надеюсь, что непонятные стороны прояснятся в разборе конкретного примера.

Рассмотрю, как можно сделать граббер музыки с записью музыки в wav файл. (Я тестировал его на демке UberNuss. Если будете пробовать на ней незабудьте вытащить из нее Win32 exe. В общем она 4кб, и сделана как com - файл, который распаковывается и запускает сам PE файл)

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

waveOutOpen, waveOutWrite

Первым делом модифицируем файл ke_spy.txt, чтобы в нем были эти самые функции, иначе получится вот что - нет перехвата этих функций, и нет вызова нашего кода из плагина. Если нужны только две функции, то нет необходимости перехватывать остальные - так надежнее. Сам ke_spy.txt для нашего плагина будет выглядеть так:

[winmm.dll]
waveOutOpen, 6
waveOutWrite, 3

Дальше сам плагин. Приведу только ключевую часть, полностью смотрите в исходниках.

Главное, что делает плагин:

  1. Открывает файл для вывода туда данных

  2. Пишет первую часть заголовка (по шаблону)

  3. Записывает вторую часть заголовка (берется из параметров функции waveOutOpen

  4. Дописывает заголовок wav файла

  5. Выводит буфер, переданный в функцию waveOutWriteв выходной файл.

  6. После окончания закрывает выходной файл

Если интересно, описания функции есть в MSDN, сам формат wav- файла есть в сети.

Остается заметить, что в нем незаполнены два поля (DWORD)- по смещению 04h и 024h должны быть равны Размер Файла -8 и Размер Файла - 44 соответственно, хотя можно послушать и так. (Пробовал в WinAmp5.0)

;Имя выходного файла и заголовок wav - файла
ofile db "m.wav",0
wavhead_0 db "RIFF"
db 0,0,0,0
db "WAVE"
db "fmt "
dd 10h
wavhead_1 db "data"
db 0,0,0,0
install_plugin proc
invoke LoadLibrary,offset sz_winmm
mov hwinmm, eax
invoke GetProcAddress, eax, offset sz_waveOutOpen
mov waveOutOpen_addr, eax
invoke GetProcAddress, hwinmm,offset sz_waveOutWrite
mov waveOutWrite_addr, eax
invokeCreateFile,offset ofile,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
mov hwavfile, eax
ret
install_plugin endp

plugin proc
pop ret_address
pop func_adr
pop func_par
pop func_nam
pop func_return_address
pop func_idx
pushfd
pushad
mov eax, func_adr
;Если адрес перехваченной функции совпал, то действуем
.if eax == waveOutOpen_addr 
;Пишем в файл заголовок wav - файла
invoke WriteFile,hwavfile,offset wavhead_0,20,ADDR bwri,NULL
;Пишем в файл структуру, переданную функции waveOutOpen(должна быть в заголовке)
mov eax, [esp+2Ch] ;LPWAVEFORMATEX
invoke WriteFile,hwavfile, eax,10h,ADDR bwri,NULL
;Дописываем в файл заголовок
invoke WriteFile,hwavfile, offset wavhead_1,8,ADDR bwri,NULL popad
popfd
call func_adr
;Если мы перехватили waveOutWrite, то выводим её звукой буфер в наш файл, а уже потом играем.
.elseif eax == waveOutWrite_addr
mov eax, [esp+28h] ;LPWAVEHDR
mov ecx, [eax] ;lpData
mov edx, [eax+4] ;dwBuffer
invoke WriteFile,hwavfile, ecx, edx,ADDR bwri,NULL
popad
popfd
call func_adr; Вызвали waveOutWrite
.else
popad
popfd
call func_adr; Ни одна не совпала- прсто вызываем её
.endif
push ret_address; Возвращаемся
ret
plugin endp

Напоследок хочу сказать, что при помощи плагинов можно сделать кое-что более интересное, например цеплять шпиона к создающимся процессам. (Нужен перехват CreateProcess и написать для нее обработчик, который внедрит ke_core.dll при помощи CreateRemoteThread)

2002-2013 (c) wasm.ru