ANTICHAT — форум по информационной безопасности, OSINT и технологиям
ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию.
Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club,
и теперь снова доступен на новом адресе —
forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
 |
|

10.07.2008, 16:24
|
|
Познающий
Регистрация: 30.11.2006
Сообщений: 49
Провел на форуме: 36434
Репутация:
28
|
|
Тут только перехватывать ZwExitProcess и ZwExitThread.
таких функций не сущесмтвует
|
|
|

10.07.2008, 17:23
|
|
Постоянный
Регистрация: 29.04.2007
Сообщений: 496
Провел на форуме: 2715445
Репутация:
588
|
|
вот такие функции есть:
ntdll.ZwTerminateProcess
ntdll.ZwTerminateThread
|
|
|

10.07.2008, 17:43
|
|
Познающий
Регистрация: 04.07.2008
Сообщений: 56
Провел на форуме: 390892
Репутация:
60
|
|
таких функций не сущесмтвует
сорри, ошибся, имел ввиду:
ntdll.ZwTerminateProcess
ntdll.ZwTerminateThread
- есть вот какая тема - добавить свою запись в двусвязный список LDR_MODULE (или как его там...), указав адрес обработчика, которому и будут приходить сообщения DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH и прочие...
Вообщем ты себе все круто усложняешь. Лучше все же вернись к перехвату функций, можно подменой адреса в таблице ипорта (как советовал Jes), если не хочешь возиться со сплайзингом.
Если хуки тебя не в какую не устраивают, то можно вместо добавления новой структуры в двусвязный список загруженных библиотек (довольно палевно, т.к. такие программы как 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
Последний раз редактировалось SlyBit; 10.07.2008 в 17:48..
|
|
|

10.07.2008, 18:13
|
|
Познающий
Регистрация: 30.11.2006
Сообщений: 49
Провел на форуме: 36434
Репутация:
28
|
|
Что толку от перехвата таблицы импорта, если не знаешь какой именнго модуль завершит последний поток? вообще прога может завершить своё выполнение по рету и ExitProcess будет вызван из kernel32 - тут только сплайсинг. а вариант с изменением адреса входа действительно реальный, хотя, возможно, и не самый лучший. ведь адрес точки входа будет лежать за границами модуля, что может вызвать подозрения...
|
|
|

10.07.2008, 18:26
|
|
Познающий
Регистрация: 04.07.2008
Сообщений: 56
Провел на форуме: 390892
Репутация:
60
|
|
да, я про таблицу экспорта kernel32 и ntdll конечно...какая нафиг импорта  мне кажется вариант со сплайзингом такой же палевный как и подмена адреса точки входа либы.
вообще прога может завершить своё выполнение по рету и ExitProcess будет вызван из kernel32
Подменяй тогда адрес возврата.
Последний раз редактировалось SlyBit; 10.07.2008 в 18:30..
|
|
|

10.07.2008, 18:50
|
|
Banned
Регистрация: 13.09.2006
Сообщений: 523
Провел на форуме: 2869410
Репутация:
925
|
|
KiSystemFastRet+ZwTerminateProcess.
|
|
|

10.07.2008, 20:16
|
|
Познающий
Регистрация: 30.11.2006
Сообщений: 49
Провел на форуме: 36434
Репутация:
28
|
|
Сообщение от SlyBit
да, я про таблицу экспорта kernel32 и ntdll конечно...какая нафиг импорта  мне кажется вариант со сплайзингом такой же палевный как и подмена адреса точки входа либы.
Подменяй тогда адрес возврата.
про адрес возврата я уже сказал - не катит на случай многопоточности
|
|
|

10.07.2008, 20:19
|
|
Познающий
Регистрация: 04.07.2008
Сообщений: 56
Провел на форуме: 390892
Репутация:
60
|
|
А вот и пример подмены точки входа библиотеки подоспел (описание несколькими постами выше):
Код:
#include <windows.h>
#include "ntdll.h"
#pragma comment(linker, "/ENTRY:Main")
typedef DWORD (WINAPI *PTRUEENTRY)(HMODULE Module, DWORD Reason, LPVOID Reserved);
PVOID dwTrueAddr;
DWORD WINAPI CatchExit(HMODULE Module, DWORD Reason, LPVOID Reserved)
{
if(Reason == DLL_PROCESS_DETACH) {
// Событие перед завершение приложения
}
return ((PTRUEENTRY)dwTrueAddr)(Module, Reason, Reserved);
}
VOID WINAPI HookDllEntry(PWCHAR pDllName, PVOID pDummyEntry)
{
PPEB pPeb;
PPEB_LDR_DATA pPebLdrData;
PLDR_DATA_TABLE_ENTRY pLdrDataTableEntry;
DWORD dwBlink;
__asm {
mov eax, fs:[0x30]
mov pPeb, eax
}
pPebLdrData = (PPEB_LDR_DATA)pPeb->Ldr;
// Запоминаем адрес последнего элемента в двусвязном списке
dwBlink = *(PDWORD)pPebLdrData->InMemoryOrderModuleList.Blink;
// Получаем указатель на первую структуру в двусвязном списке
pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pPebLdrData->InLoadOrderModuleList.Flink;
// Обходим все структуры и как находим библиотеку с именем pDllName, изменяем её точку входа
do {
pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pLdrDataTableEntry->InLoadOrderModuleList.Flink;
if(!lstrcmpW(pLdrDataTableEntry->BaseDllName.Buffer, pDllName)) {
dwTrueAddr = pLdrDataTableEntry->EntryPoint;
pLdrDataTableEntry->EntryPoint = pDummyEntry;
}
} while(dwBlink != *(PDWORD)pLdrDataTableEntry->InMemoryOrderModuleList.Flink);
}
VOID WINAPI Main()
{
HookDllEntry(L"ntdll.dll", CatchExit);
ExitProcess(0);
}
Последний раз редактировалось SlyBit; 10.07.2008 в 20:22..
|
|
|

10.07.2008, 20:29
|
|
Познающий
Регистрация: 30.11.2006
Сообщений: 49
Провел на форуме: 36434
Репутация:
28
|
|
SlyBit, пасиб, конечно. но это вобщем-то понятно. у меня ситуация несколько другая - вот я и думаю что сделать лучше: перехват PEB или сплайсинг ExitThread или ExitProcess. Вообще-то мой код и так хучит кое-какие функции. В частности имеет доступ к оконным сообщениям. так что идеальный вариант - отслеживать сообщения (есали такие есть) о закрытии всех окон или что-то типа этого...
|
|
|

10.07.2008, 21:18
|
|
Познающий
Регистрация: 04.07.2008
Сообщений: 56
Провел на форуме: 390892
Репутация:
60
|
|
gevara
Я думаю, что оконные сообщения отпадают по как минимум 2м причинам: не отслеживается самостоятельный вызов ExitProcess программой, не всегда они "правильно" обрабатываются программой. Пример Outpost, при посылке его главному окну сообщения WM_CLOSE (щелчек на крестик в правом верхнем углу), оно просто сворачивается, вместо того чтобы закрыться. На сообщения WM_DESTROY и WM_QUIT вообще нет никакой реакции. Калькулятор же спокойно закрывается получив WM_CLOSE.
Выбор между модификацией PEB и сплайзингом ExitProcess и ExitThread. В первом случае все просто. Во втором нужно считать количество потоков, приложение закроется как только закроют его последний поток. Для этого нужно будет перехватывать CreateThread и икрементировать счетчик кол-ва потоков и декрементировать при выхове ExitThread, либо подсчитывать количество потоков перед вызовом ExitThread.
|
|
|
|
 |
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|