| greki_hoy |
16.04.2010 13:33 |
Цитата:
Сообщение от sn0w
Собственно очередная техника перехвата любых функций. только в начало пишется не джамп - а привелегированная инструкция, система генерирует исключение - а обработчик то уже тоже перехвачен. поэтому управление получает наш заранее подготовленный перехватчик. недоработок много - в частности не доделал снятие этого хука - но в этом ничего сложного нет. можете и сами.
особые спасиба кезу, который как всегда помог советом и делом =)
вообщем, кодоманы, это для вас ;)
сорсы с билдом тут - webfile.ru/3886408
пасс 123123
а это кусок движка:
Код:
//////////////////////////////////////////////////////////////////////////
// (c) Exception hook engine by sn0w. big thx to kez for good advices ;)
// (c) cih.[ms] community, 2009
//////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include "alldefs.h"
//////////////////////////////////////////////////////////////////////////
// анхук не поддерживается, пока. впадлу бля)
//////////////////////////////////////////////////////////////////////////
LIST_ENTRY exception_list_head;
//////////////////////////////////////////////////////////////////////////
#define InitializeListHead(ListHead) (\
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
#define InsertHeadList(ListHead,Entry) {\
PLIST_ENTRY _EX_Flink;\
PLIST_ENTRY _EX_ListHead;\
_EX_ListHead = (ListHead);\
_EX_Flink = _EX_ListHead->Flink;\
(Entry)->Flink = _EX_Flink;\
(Entry)->Blink = _EX_ListHead;\
_EX_Flink->Blink = (Entry);\
_EX_ListHead->Flink = (Entry);\
}
//////////////////////////////////////////////////////////////////////////
PHOOK_ENTRY find_hook_entry(LPVOID real_address)
{
PLIST_ENTRY current_list;
PHOOK_ENTRY pcurr_hook;
current_list = exception_list_head.Flink;
while(current_list != &exception_list_head){
pcurr_hook = CONTAINING_RECORD(current_list, HOOK_ENTRY, list_entry);
if ((DWORD)pcurr_hook->real_address == (DWORD)real_address)
return pcurr_hook;
current_list = current_list->Flink;
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
VOID (WINAPI * Real_KiUserExceptionDispatcher)(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextFrame);
VOID WINAPI My_KiUserExceptionDispatcher(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextFrame)
{
if(ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION){
PHOOK_ENTRY hhk;
hhk = find_hook_entry(ExceptionRecord->ExceptionAddress);
if(hhk){
ContextFrame->Eip = (DWORD)hhk->handler;
NtContinue(ContextFrame, FALSE);
}
}
Real_KiUserExceptionDispatcher(ExceptionRecord,ContextFrame);
}
//////////////////////////////////////////////////////////////////////////
__declspec(naked) VOID WINAPI Stub_KiUserExceptionDispatcher(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextFrame)
{
__asm{
sub esp, 4
jmp My_KiUserExceptionDispatcher
}
}
//////////////////////////////////////////////////////////////////////////
inline void generate_pushret_code(LPVOID at_address, LPVOID to_address)
{
*(LPBYTE)at_address = 0x68;
*(DWORD*)((LPBYTE)at_address + 1) = (DWORD)to_address;
*((LPBYTE)at_address + 5) = 0xC3;
}
//////////////////////////////////////////////////////////////////////////
PHOOK_ENTRY ExceptionHookFunction(LPVOID function, LPVOID handler)
{
BYTE privileged_opcodes[] = {0xFA, 0xFB, 0xEE, 0xEF, 0xEC, 0x6C, 0x6F};
LPVOID trampoline;
DWORD first_inst_len, protection;
PHOOK_ENTRY phhk;
get_instruction_length(function, &first_inst_len);
trampoline = valloc(first_inst_len + 6);
memcpy(trampoline, function, first_inst_len);
generate_pushret_code((LPVOID)((LPBYTE)trampoline + first_inst_len), (LPVOID)((LPBYTE)function + first_inst_len));
phhk = (PHOOK_ENTRY)valloc(sizeof(HOOK_ENTRY));
phhk->handler = handler;
phhk->real_address = function;
phhk->trampoline = trampoline;
InsertHeadList(&exception_list_head, &phhk->list_entry);
VirtualProtect(function, first_inst_len, PAGE_EXECUTE_READWRITE, &protection);
*(LPBYTE)function = privileged_opcodes[brandom(0, sizeof(privileged_opcodes) - 1)];
VirtualProtect(function, first_inst_len, protection, &protection);
return phhk;
}
//////////////////////////////////////////////////////////////////////////
void InitializeExceptionHook()
{
InitializeListHead(&exception_list_head);
SpliceHookFunction((DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"), "KiUserExceptionDispatcher"),
Stub_KiUserExceptionDispatcher, (DWORD*)&Real_KiUserExceptionDispatcher);
}
//////////////////////////////////////////////////////////////////////////
|
2sn0w - fix InsertHeadList
Код:
#if 0
#define InsertHeadList(ListHead,Entry) {\
PLIST_ENTRY _EX_Flink;\
PLIST_ENTRY _EX_ListHead;\
_EX_ListHead = (ListHead);\
_EX_Flink = _EX_ListHead->Flink;\
(Entry)->Flink = _EX_Flink;\
(Entry)->Blink = _EX_ListHead;\
_EX_Flink->Blink = (Entry);\
_EX_ListHead->Flink = (Entry);\
}
#endif
#define InsertHeadList(ListHead,Entry) do { \
LIST_ENTRY *E_Entry = (Entry); \
LIST_ENTRY *E_ListHead = (ListHead); \
E_Entry->Flink = E_ListHead->Flink; \
E_Entry->Blink = E_ListHead; \
E_ListHead->Flink->Blink = E_Entry; \
E_ListHead->Flink = E_Entry; \
} while (0)
побочный эффект в макросе 4 раза вычисляется второй аргумент плюс без do {} while (0) нельзя вставить
что то в список в условии if else или придется не ставить точку с запятой после InsertHeadList
|