日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

通过SEH 非inline hook

發布時間:2025/3/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通过SEH 非inline hook 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SEH(Struct Exception Handler,結構化異常) VEH(Vector Exception Handler,向量異常處理)
SEH是OS提供給線程來感知和處理異常的一種回調機制。
在Intel Win32平臺上,由于FS寄存器問題指向當前的TIB(線程信息塊),因此FS:[0]處能找到最新的一個EXCEPTION_REGISTRATION_RECORD結構。
typedef struct _EXCEPTION_REGISTRATION_RECORD {
??? struct _EXCEPTION_REGISTRATION_RECORD *Next;
??? PEXCEPTION_ROUTINE Handler;
} EXCEPTION_REGISTRATION_RECORD;
EXCEPTION_ROUTINE (
??? _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,
??? _In_ PVOID EstablisherFrame,
??? _Inout_ struct _CONTEXT *ContextRecord,
??? _In_ PVOID DispatcherContext
??? );

typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE;
typedef struct _EXCEPTION_RECORD {
??? DWORD??? ExceptionCode;
??? DWORD ExceptionFlags;
??? struct _EXCEPTION_RECORD *ExceptionRecord;
??? PVOID ExceptionAddress;
??? DWORD NumberParameters;
??? ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
??? } EXCEPTION_RECORD;
???
XP之后,在基于線程的SEH基礎增加了基于進程的VEH
比較:
1.SEH基于線程,VEH基于進程
2.優先級:調試器 > VEH > SEH?即KiUserExceptionDispatcher()函數先檢查進程是否處理調試,然后VEH,最后SEH.
3.SEH單鏈表,VEH雙鏈表,VEH節點可掛在頭上或尾上。
注冊VEH的回調API:
PVOID WINAPI AddVectoredExceptionHandler(
? __in? ULONG FirstHandler,
? __in? PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

IA-32處理器定義了8個調試寄存器(DR0-DR7) DR0-DR3用于指點內存地址或I/O地址 DR4-DR5保留,DR6事件發生報告詳細信息,DR7定義中斷條件。
硬件斷點HOOK是結合DR0-DR3調試寄存器和Winows SEH或VEH機制所引入的HOOK機制,因不涉及修改代碼,不易檢驗檢測到。

?

//test.exe #include <stdio.h> #include <Windows.h> #include <process.h>DWORD Counter = 0;unsigned __stdcall SecondThreadFunc( void* pArguments ) {while ( Counter < 2 ){MessageBox(NULL,"the fact infor","test SEH hook",MB_OK);Sleep(1000);Counter++;}_endthreadex( 0 );return 0; } void main() {HANDLE hThread;unsigned threadID;hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );::LoadLibraryA("WaiGua.dll");WaitForSingleObject(hThread,INFINITE);MessageBox(NULL,"the fact infor","test SEH hook",MB_OK); }


?

//hook dll #include <Windows.h> #include <TlHelp32.h> #include <stdio.h> #include <limits.h>typedef HANDLE (WINAPI *OPENTHREAD) (DWORD dwFlag, BOOL bUnknow, DWORD dwThreadId); OPENTHREAD g_lpfnOpenThread = NULL; DWORD func_addr = 0x00401000; DWORD func_addr_offset = func_addr + 0x2;void PrintParameters(PCONTEXT debug_context) {printf("EAX: %X EBX: %X ECX: %X EDX: %X\n",debug_context->Eax, debug_context->Ebx, debug_context->Ecx, debug_context->Edx);printf("ESP: %X EBP: %X\n",debug_context->Esp, debug_context->Ebp);printf("ESI: %X EDI: %X\n",debug_context->Esi, debug_context->Edi);printf("Parameters\n""HWND: %X\n""text: %s\n""caption: %s\n",(HWND)(*(DWORD*)(debug_context->Esp + 0x4)),(char*)(*(DWORD*)(debug_context->Esp + 0x8)),(char*)(*(DWORD*)(debug_context->Esp + 0xC)));}void ChangeText(PCONTEXT debug_context) {char* text = (char*)(*(DWORD*)(debug_context->Esp + 0x8));int length = strlen(text);DWORD oldprotect = 0;VirtualProtect(text,length,PAGE_EXECUTE_READWRITE,&oldprotect);_snprintf(text, length, "hooked that");VirtualProtect(text,length,oldprotect,&oldprotect); }void __declspec(naked) ReturnOriginalFunc(void) {__asm {mov edi,edi//push ebp way 222jmp [func_addr_offset]} }LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) {if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr) {//if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr+2) { way 222PCONTEXT debug_context = ExceptionInfo->ContextRecord;printf("Breakpoint hit!\n");PrintParameters(debug_context);ChangeText(debug_context);debug_context->Eip = (DWORD)&ReturnOriginalFunc;return EXCEPTION_CONTINUE_EXECUTION;}}return EXCEPTION_CONTINUE_SEARCH; }void SEHHook(void) {HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);if(hTool32 != INVALID_HANDLE_VALUE) {THREADENTRY32 thread_entry32;thread_entry32.dwSize = sizeof(THREADENTRY32);FILETIME exit_time, kernel_time, user_time;FILETIME creation_time;FILETIME prev_creation_time;prev_creation_time.dwLowDateTime = 0xFFFFFFFF;prev_creation_time.dwHighDateTime = INT_MAX;HANDLE hMainThread = NULL;if(Thread32First(hTool32, &thread_entry32)) {do { //取最早啟動的線程作為hook對象if(thread_entry32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(thread_entry32.th32OwnerProcessID)&& thread_entry32.th32OwnerProcessID == GetCurrentProcessId()/*&& thread_entry32.th32ThreadID != GetCurrentThreadId()*/){HANDLE hThread = g_lpfnOpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,FALSE, thread_entry32.th32ThreadID);GetThreadTimes(hThread, &creation_time, &exit_time, &kernel_time, &user_time);if(CompareFileTime(&creation_time, &prev_creation_time) == -1) {//creation_time 小于 prev_creation_time時候為-1memcpy(&prev_creation_time, &creation_time, sizeof(FILETIME));if(hMainThread != NULL)CloseHandle(hMainThread);hMainThread = hThread;}elseCloseHandle(hThread);}thread_entry32.dwSize = sizeof(THREADENTRY32);} while(Thread32Next(hTool32, &thread_entry32));(void)SetUnhandledExceptionFilter(ExceptionFilter);CONTEXT thread_context = {CONTEXT_DEBUG_REGISTERS};thread_context.Dr0 = func_addr;//thread_context.Dr0 = func_addr+2; way 222thread_context.Dr7 = (1 << 0);SetThreadContext(hMainThread, &thread_context);CloseHandle(hMainThread);}CloseHandle(hTool32);} }int APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved) {if(reason == DLL_PROCESS_ATTACH) {DisableThreadLibraryCalls(hModule);if(AllocConsole()) {freopen("CONOUT$", "w", stdout);SetConsoleTitle("Console");SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);printf("DLL loaded.\n");}HMODULE hDll = ::LoadLibrary("kernel32.dll");g_lpfnOpenThread = (OPENTHREAD)::GetProcAddress(hDll, "OpenThread"); func_addr = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");func_addr_offset = func_addr+2;//func_addr_offset = func_addr+3; way 222printf("MessageBoxA Addr: 0x%x\n",func_addr);SEHHook();}return TRUE; }//31: MessageBox(NULL,"the fact infor","test SEH hook",MB_OK); //008D0365 8B F4 mov esi,esp //008D0367 6A 00 push 0 //008D0369 68 88 0C 92 00 push 920C88h //008D036E 68 A4 0C 92 00 push 920CA4h //008D0373 6A 00 push 0 //008D0375 FF 15 14 84 93 00 call dword ptr ds:[938414h] //008D037B 3B F4 cmp esi,esp //008D037D E8 2B A9 FF FF call __RTC_CheckEsp (08CACADh) // //_MessageBoxA@16: //7526FD1E 8B FF mov edi,edi //func_addr is eque to 7526FD1E //7526FD20 55 push ebp //7526FD21 8B EC mov ebp,esp //7526FD23 6A 00 push 0 //7526FD25 FF 75 14 push dword ptr [ebp+14h] //7526FD28 FF 75 10 push dword ptr [ebp+10h] //7526FD2B FF 75 0C push dword ptr [ebp+0Ch] //7526FD2E FF 75 08 push dword ptr [ebp+8] //7526FD31 E8 A0 FF FF FF call _MessageBoxExA@20 (7526FCD6h)


總結

以上是生活随笔為你收集整理的通过SEH 非inline hook的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。