![]() |
Цитата:
|
вот такие функции есть:
ntdll.ZwTerminateProcess ntdll.ZwTerminateThread |
Цитата:
ntdll.ZwTerminateProcess ntdll.ZwTerminateThread Цитата:
Если хуки тебя не в какую не устраивают, то можно вместо добавления новой структуры в двусвязный список загруженных библиотек (довольно палевно, т.к. такие программы как Process Explorer увидят странную библиотеку), изменить базу существующей библиотеку на свой обработчик. При вызове твоего обработчика проверяй 2-ой параметр Reason на равенство коду DLL_PROCESS_DETACH, пиши там свои логи и затем вызывай оригинальную точку входа библиотеки с такими же параметрами. Подменяй точку входа у невыгружаемых библиотеках, таких как user32.dll, kernel32.dll, ntdll.dll. Теперь постараюсь объяснить как выйти на этот список и что нужно менять. Для начала нужно получить адрес структуры PEB процесса. Указатель лежит по адресу fs:[30h], либо можно взять его из структуры PROCESS_BASIC_INFORMATION по смещению +4 байта. Указатель на саму струкуру PROCESS_BASIC_INFORMATION получаешь вызвав функцию NtQueryInformationProcess со вторым параметром равным 0 (ProcessBasicInformation). Указатель на PEB есть. По смещению 0xC в PEB находится указатель на структуру PPEB_LDR_DATA. В этой структуре находятся 3 указателя на точки входа двусвязных списков, содержащих информацию о библиотеках на стадии загрузки, уже загруженных в память и на стадии инициализации. Нас интересует второй указатель. Теперь нам нужно обойти список LDR_DATA_TABLE_ENTRY и сравнить имя BaseDllName с "ntdll.dll" например. Как находим, заменяем EntryPoint на наш обработчик. Это все в теории, если что-то не так - поправьте. NTDLL.h |
Что толку от перехвата таблицы импорта, если не знаешь какой именнго модуль завершит последний поток? вообще прога может завершить своё выполнение по рету и ExitProcess будет вызван из kernel32 - тут только сплайсинг. а вариант с изменением адреса входа действительно реальный, хотя, возможно, и не самый лучший. ведь адрес точки входа будет лежать за границами модуля, что может вызвать подозрения...
|
да, я про таблицу экспорта kernel32 и ntdll конечно...какая нафиг импорта ;) мне кажется вариант со сплайзингом такой же палевный как и подмена адреса точки входа либы.
Цитата:
|
KiSystemFastRet+ZwTerminateProcess.
|
Цитата:
|
А вот и пример подмены точки входа библиотеки подоспел (описание несколькими постами выше):
Код:
#include <windows.h> |
SlyBit, пасиб, конечно. но это вобщем-то понятно. у меня ситуация несколько другая - вот я и думаю что сделать лучше: перехват PEB или сплайсинг ExitThread или ExitProcess. Вообще-то мой код и так хучит кое-какие функции. В частности имеет доступ к оконным сообщениям. так что идеальный вариант - отслеживать сообщения (есали такие есть) о закрытии всех окон или что-то типа этого...
|
gevara
Я думаю, что оконные сообщения отпадают по как минимум 2м причинам: не отслеживается самостоятельный вызов ExitProcess программой, не всегда они "правильно" обрабатываются программой. Пример Outpost, при посылке его главному окну сообщения WM_CLOSE (щелчек на крестик в правом верхнем углу), оно просто сворачивается, вместо того чтобы закрыться. На сообщения WM_DESTROY и WM_QUIT вообще нет никакой реакции. Калькулятор же спокойно закрывается получив WM_CLOSE. Выбор между модификацией PEB и сплайзингом ExitProcess и ExitThread. В первом случае все просто. Во втором нужно считать количество потоков, приложение закроется как только закроют его последний поток. Для этого нужно будет перехватывать CreateThread и икрементировать счетчик кол-ва потоков и декрементировать при выхове ExitThread, либо подсчитывать количество потоков перед вызовом ExitThread. |
| Время: 02:30 |