|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Ноя 28, 2003 03:17:45 Добрый день, господа. Интересует каким образом можно глобально перехватить вызовы функций. Т.е. имеется ввиду к примеру - перехватывать вызов MessageBoxA во всех процессах. При этом естественно знать какой это процесс и т.д. Причем перехватывать безопасно - т.е. чтоб при возможности можно было продолжить выполнение функции. Собственно у меня единственный вариант, который пришел в голову - это инжектировать код, и патчить импорты у каждого модуля. Но здесь возникает резонный вопрос - как загрузиться _ДО_ всех юзерских либ? т.е. сразу после kernel32 (Даже в случае, если либы грузятся из импортов). Собственно вот.Если у кого есть что сказат по этой теме - буду весьма признателен. |
|
|
Дата: Ноя 28, 2003 09:27:10 Я листал процессы с помощью Process32First/Process32Next и в каждом процессе первые 6 байт функции заменял на push offset hook ret а из хука менял их обратно и вызывал настоящую функцию Вот кусок моего user mode сниффера. Здесь хукается send и весь исходящий траффик пишется в c:\send_log _1974133046__sniffer.asm |
|
|
Дата: Ноя 28, 2003 17:39:54 Есть другая методика, но будет работать только в случае функций, проходящих через шлюз sysenter/int 2E. Надо патчить SDT. |
|
|
Дата: Ноя 28, 2003 23:30:43 Володя: Функции из winapi, к ядру отношения мало имеющие. А что по поводу патча функции _ДО_ загрузки библиотек и старта программы? |
|
|
Дата: Ноя 28, 2003 23:37:16 rst ИМХО единственный способ это сделать - пропатчить сами дллки. Еще можно хукнуть CreateProcess, но это будет не _ДО_ а _СРАЗУ_ПОСЛЕ_ :) Можешь подробнее описать задачу? |
|
|
Дата: Ноя 29, 2003 00:11:16 Посмотри у Рихтера. Там целая глава этому посвящена "DLL Injection and API Hooking". Все основные методы расписаны. Всё для третьего кольца. И в конце главы как раз есть пример хуканья MessageBox. А грузиться до не имеет смысла, в этом случае, т.к. хучить то ещё нечего :-) В общем, почитай. Там всё грамотно написано. |
|
|
Дата: Ноя 29, 2003 00:18:55 А существует ли метод где не надо каждый прцесс отдельно хукать? |
|
|
Дата: Ноя 29, 2003 00:42:28 comrade в win9x можно все хукнуть 1 раз. Там все библиотеки общие для всех процессов. Еще можно длл пропатчить. Вот пара ссылок: http://www.wasm.ru/article.php?article=1021007 http://z0mbie.host.sk/api_hook.txt |
|
|
Дата: Ноя 29, 2003 03:12:26 FFFF - я читал рихтера. Там описана методика хука самого по себе (путем патчинга IAT - я это умею и делаю.. собственно это единственный момент, который не вызывает вопросов - я это уже делал). Меня больше интересует следующий момент - глобальный хук. Т.е. преследую следующие 2 вещи: 1) чтоб ни один процесс не мог вызвать определенные функции без моей сатисфакции 2) чтоб ни коим образом нельзя было вызвать функции без моей сатисфакции (LoadLibrary && GetProcAddress и Imorts) Т.е. нужно: а) следить создание процессов и сразу же делать перехват GetProcAddress после загрузки процесса. б) в каждом процессе так же делать патчинг IAT во всех модулях. Да, кстати есть метод, не описанный у Рихтера - через отладку. Можно ведь бряку поставить туда. Но это ИМХО так же некрасиво, как и подменять код самих DLL. Собственно остается два вопроса на повеске дня: 1) отслеживать создание процессов. 2) получать доступ сразу же после CreateProcess.. |
|
|
Дата: Ноя 29, 2003 03:52:26 2 all Прочитал Рихтера и ничего не понял. Почему он рекомендует патчить IAT вместо того чтобы патчить первые 6 байт функции? Цитата из книги: На замену кода в начале функции уходит какое-то время, а в этот момент перехватываемая функция может понадобиться другому потоку. Результаты могут быть просто катастрофическими! Какая разница сколько байт менять 6 или 4 ??? И еще если патчить IAT то придется писать писать функцию для ее поиска и ставить хук на GetProcAdress. Может я чего-то не понимаю? |
|
|
Дата: Ноя 29, 2003 04:13:44 rst Тут один вариант (если хочешь чтобы хук был глобальным) и volodya прав в том плане, что надо писать перехватчик на уровне ядра системы, поскольку для каждого процесса в Win используется своя память, т.е. один процесс не может залезть в память другого процесса (хотя это не совсем так, но для текущего объяснения пойдет), а вот ядро для всех процессов одинаково. Хочешь пример реализациии такого хука - это отладчик SoftIce. |
|
|
Дата: Ноя 29, 2003 06:04:13 PROFi : 1) не все функции уходят в ядро. 2) ReadProcessMemory\WriteProcessMemory\CreateRemoteThread - так что я имею доступ ко всему, что надо -) hello_world: - а ты уверен. что сможешь восстановить алгоритм работы функции после замены этих 6-х байт? Дело в том, что это весьма "кривой" и "грязный" метод патчинга (имхо) Уж лучше int 3 туда поставить , или drx регистры юзать. 2 all: а что скажете по поводу перехвата userspace функций, используя драйвер? (Я не особо знаком с написанием драйверов. Посему у самого идеи на этот счет не появятся). Я думаю что с помощью драйверов можно реализовать перехват выполнения кода после запуска процесса ( до каких-либо initialization routines ) Ещё были мысли по поводу замены либы ( т.е. создание т.н. прокси-либы ), но это не вариант по той причине, что я не могу гарантировать такое же количество экспортов, как в оригинале. Да и мне кажется это есть _СЛИШКОМ_ радикальное решение. Хотя Symantec использует подобное, но там proxy com-библиотека. Там все проще намного. |
|
|
Дата: Ноя 29, 2003 10:15:50 · Поправил: zen333 если менять первые 6 байт функций то их надо менять постоянно при каждой подгрузке длл а еще нужно чтоб функция была восстановленна для продолжения выполнения... мне нужно было перехватить что посылает ТХе БАТ... в таблицах импорта он несодержит сенд вообще писал через хук длл ку которая постоянно меняет 6 байт а потом обратно , когда принимаешь почту с 10 ящиков то БАТ вместе с Эксплорером вылетают с Эксцепшином потому как постоянно меняются байтики в начале функции туда сюда... выход нашел такой например для всех НТ систем: исходник дллки ;goto make .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib include \masm32\include\masm32.inc includelib \masm32\lib\masm32.lib filsav proto STDCALL :dword,:dword includef proto STDCALL inclfile:dword,result:dword myfunc PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD getwindir proto STDCALL :dword .data? oldseh db 10 dup (?) buflen dd ? SizeWrite dd ? SizeWritten dd ? hHook dd ? hWnd dd ? ws2lib dd ? hFileWrite dd ? buffer db 255 dup (?) tmpstr db 255 dup (?) txtbuf db 255 dup (?) windir db 255 dup (?) adress dd ? adress1 dd ? dwOldProtect dd ? .data offmy equ offset myfunc me equ 13,10,0 _1310end db 96,13,10,'end',13,10,'.',me _1310begin db 13,10,13,10,'begin 600 _1310 db me flag db 0 senen db 13,10,'.',13,10,0 szLib db 'ws2_32',0 szProc db 'send',0 oldapi db 6 dup (0) newseh db 068h dd offmy db 0c3h hhook1 dd 0 hhook dd 0 hInstance dd 0 cnt dd 0 nil dd 0 .code DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD push hInst pop hInstance assume fs: nothing mov eax,fs:[0] mov [eax+4],offset ErrorHandler mov eax,1 ret DllEntry Endp DebugProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD cmp cnt,0 jnz @F invoke GetModuleHandle, ADDR szLib cmp eax,NULL jz @F mov ws2lib,eax invoke GetProcAddress, eax, ADDR szProc mov adress,eax invoke VirtualProtect,eax, 10, PAGE_EXECUTE_READWRITE, ADDR dwOldProtect call conv @@: invoke CallNextHookEx,hhook1,nCode,wParam,lParam ret DebugProc endp InstallHook proc invoke SetWindowsHookEx,WH_CBT,addr DebugProc,hInstance,NULL mov hhook1,eax ret InstallHook endp UninstallHook proc invoke UnhookWindowsHookEx,hhook1 pusha mov edi,adress mov esi,offset oldseh movsw movsd popa ret UninstallHook endp ;--------------------------------------------------------------------- -------- conv: inc cnt pusha mov esi,adress mov edi,offset oldseh movsw movsd mov esi,offset newseh mov edi,adress movsw movsd popa retn ;------------------ _send: push ebp ;вот здесь очень важно mov ebp,esp ;так как нам нельзя постоянно крутить байтики мы восстанавливаем значения всех регистров как должно быть и отдаем управление оригинальной функции точнее ее продолжению после 6 байт... sub esp,10h mov eax,adress add eax,6 mov adress1,eax jmp [adress1] ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@myfunc PROC mysock:DWORD,myvar:DWORD,mycount:DWORD,myflag:DWORD local dlina:dword local buf:dword local res:dword local mesto:dword push myflag push mycount push myvar push mysock call _send @@: ret myfunc endp ;---------=-=-=-=-=--=--------------------------------------- ErrorHandler proc C lpExcept:DWORD, lpFrame:DWORD, lpContext:DWORD, lpDispatch:DWORD invoke ExitProcess,0 xor eax, eax ; continue execution ret ErrorHandler endp End DllEntry :make echo LIBRARY ahook>mhook.def echo EXPORTS >>mhook.def echo InstallHook>>mhook.def echo UninstallHook>>mhook.def \masm32\bin\ml /c /coff /Cp %0 \masm32\bin\Link /SECTION:.bss,S /DLL /DEF:mhook.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib bhook.obj del *.obj del *.exp del *.lib |
|
|
Дата: Ноя 29, 2003 11:28:27 [ rst: FFFF - я читал рихтера. ] Извини, своих не признал. [ rst: Собственно остается два вопроса на повеске дня: 1) отслеживать создание процессов. 2) получать доступ сразу же после CreateProcess. ] Из драйвера это просто. Есть документированные PsSetCreateProcessNotifyRoutine, PsSetCreateThreadNotifyRoutine, PsSetLoadImageNotifyRoutine. "PsSetCreateProcessNotifyRoutine adds a driver-supplied callback routine to, or removes it from, a list of routines to be called whenever a process is created or deleted. After a driver-supplied routine is registered, it is called with Create set to TRUE just after the initial thread is created within the newly created process designated by the input ProcessId handle. A driver's process-notify routine is also called with Create set to FALSE, usually when the last thread within a process has terminated and the process address space is about to be deleted." |
|
|
Дата: Ноя 29, 2003 13:41:55 rst а ты уверен. что сможешь восстановить алгоритм работы функции после замены этих 6-х байт? а в чем может быть проблема? zen333 мне нужно было перехватить что посылает ТХе БАТ... в таблицах импорта он несодержит сенд вообще он делает GetModuleHandle/GetProcAdress mov eax,adress add eax,6 mov adress1,eax jmp [adress1] а зачем add eax,6 ? |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.112 |