郁金香外挂技术-郁金香灬老师

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

郁金香终身VIP管理员QQ150330575项目合作(有实力的+)视频教程+每月更新+QQ群
飞郁视频分享(每周更新)
查看: 1671|回复: 0

SEH 异常相关

[复制链接]
发表于 2017-6-1 22:39:10 | 显示全部楼层 |阅读模式

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机制,因不涉及修改代码,不易检验检测到。


[cpp] view plain copy


  • //测试EXE  
  • #include <stdio.h>  
  • #include <Windows.h>  
  • #include <vector>  
  •   
  • typedef LONG  (WINAPI *PVECTOREDEXCEPTIONHANDLER)(PEXCEPTION_POINTERS ExceptionInfo);  
  •   
  • typedef PVOID (WINAPI *ADDVECTOREEXCEPTIONHANDLER)(  
  •     ULONG FirstHandler,  
  •     PVECTOREDEXCEPTIONHANDLER VectoredHandler  
  • );  
  •   
  • typedef struct _VECTORED_EXCEPTION_NODE {  
  • LIST_ENTRY ListEntry;  
  • PVECTORED_EXCEPTION_HANDLER pfnHandler; // 该指针出于安全目的已经被加密  
  • } VECTORED_EXCEPTION_NODE, *PVECTORED_EXCEPTION_NODE;  
  •   
  • LONG CALLBACK VectoredHandlerinit1(struct _EXCEPTION_POINTERS *ExceptionInfo)  
  • {  
  •     return EXCEPTION_CONTINUE_SEARCH;  
  • }  
  • LONG CALLBACK VectoredHandlerinit2(struct _EXCEPTION_POINTERS *ExceptionInfo)  
  • {  
  •     return EXCEPTION_CONTINUE_SEARCH;  
  • }  
  • LONG CALLBACK VectoredHandlerinit3(struct _EXCEPTION_POINTERS *ExceptionInfo)  
  • {  
  •     return EXCEPTION_CONTINUE_SEARCH;  
  • }  
  •   
  •   
  • LONG CALLBACK VectoredHandler(__in  PEXCEPTION_POINTERS ExceptionInfo)  
  • {  
  •     ExceptionInfo;  
  •     return EXCEPTION_CONTINUE_EXECUTION;  
  • }  
  •   
  • int CheckVEHHook(std::vector<VOID>& vecVEH, bool bcache, bool bdelete = false)  
  • {  
  •     PVOID pExceptionHandler = NULL;  
  •     PVECTORED_EXCEPTION_NODE pCurrent = NULL;  
  •     PVECTORED_EXCEPTION_NODE pNext = NULL, pDel = NULL;  
  •     pCurrent = (PVECTORED_EXCEPTION_NODE)AddVectoredExceptionHandler(0,VectoredHandler);  
  •     if( pCurrent == NULL )  
  •     {  
  •         printf("AddVectoredExceptionHandler111 failed.\n");  
  •         return 0;  
  •     }  
  •     pNext = (PVECTORED_EXCEPTION_NODE)pCurrent->ListEntry.Blink;  
  •     //pNext = (PVECTORED_EXCEPTION_NODE)pNext->ListEntry.Flink;  
  •     printf("fake addr:0x%.8x pfnHandler:0x%.8x VEH function.\n",  
  •         pCurrent, DecodePointer(pCurrent->pfnHandler));  
  •     for( ; pNext != pCurrent; )  
  •     {  
  •         pExceptionHandler = DecodePointer(pNext->pfnHandler);  
  •         if( pExceptionHandler )  
  •         {  
  •             if( bcache )  
  •             {  
  •                 vecVEH.push_back(pNext);  
  •             }  
  •             printf("found addr:0x%.8x pfnHandler:0x%.8x VEH function.\n",pNext,pExceptionHandler);  
  •             pNext = (PVECTORED_EXCEPTION_NODE)pNext->ListEntry.Blink;  
  •             if( bdelete )  
  •             {  
  •                 std::vector<VOID>::iterator findit = find(vecVEH.begin(),vecVEH.end(),pNext);  
  •                 if( findit == vecVEH.end() )  
  •                 {  
  •                     pDel = pNext;  
  •                     pNext = (PVECTORED_EXCEPTION_NODE)pNext->ListEntry.Blink;  
  •                     printf("#### addr:0x%.8x pfnHandler:0x%.8x VEH function is illegal.\n",pDel,pExceptionHandler);  
  •                     if( RemoveVectoredExceptionHandler(pDel) )  
  •                     {  
  •                         printf("####the 0x%.8x is deleted.\n",pDel);  
  •                     }  
  •                     else  
  •                     {  
  •                         printf("####delete failed.\n");  
  •                     }  
  •                     break;  
  •                 }  
  •             }  
  •         }  
  •     }  
  •     if( RemoveVectoredExceptionHandler(pCurrent) )  
  •     {  
  •         printf("the fake node 0x%.8x is deleted.\n",pCurrent);  
  •     }  
  •     else  
  •     {  
  •         printf("delete failed.\n");  
  •     }  
  •     return 0;  
  • }  
  • DWORD func_addr = 0, func_addr_offset = 0;  
  • void __declspec(naked) ReturnOriginalFunc(void) {   
  •     __asm {   
  •         mov edi,edi   
  •         //push ebp      way 222   
  •         jmp [func_addr_offset]   
  •     }   
  • }   
  •   
  • LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) {   
  •     if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {   
  •         func_addr = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");  
  •         func_addr_offset = func_addr + 0x2;  
  •         printf("***catch some exception, don't know who hook that.\n");  
  •         if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr) {   
  •         //if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr+2) {    way 222   
  •             PCONTEXT debug_context = ExceptionInfo->ContextRecord;   
  •             printf("only blind cat meet mouse !\n");   
  •    
  •             debug_context->Eip = (DWORD)&ReturnOriginalFunc;   
  •             return EXCEPTION_CONTINUE_EXECUTION;   
  •         }   
  •     }   
  •    return EXCEPTION_CONTINUE_SEARCH;   
  • }   
  •   
  •   
  • void main()  
  • {  
  •     SetUnhandledExceptionFilter(ExceptionFilter);  
  •     //事先加3个进去  
  •     AddVectoredExceptionHandler(1,VectoredHandlerinit1);  
  •     AddVectoredExceptionHandler(0,VectoredHandlerinit2);  
  •     AddVectoredExceptionHandler(1,VectoredHandlerinit3);  
  •   
  •     MessageBox(NULL,"the fact infor111","test SEH hook",MB_OK);  
  •   
  •     std::vector<VOID> vecVEH;  
  •     printf("-----------------before LoadLibraryA.----------------\n");  
  •     CheckVEHHook(vecVEH,true,false);  
  •   
  •     :oadLibraryA("WaiGua.dll");  
  •     printf("-----------------after LoadLibraryA.----------------\n");  
  •     CheckVEHHook(vecVEH,false,false);  
  •     MessageBox(NULL,"the fact infor222","test SEH hook",MB_OK);  
  •   
  •     printf("-----------------delete LoadLibraryA added veh.-----\n");  
  •     CheckVEHHook(vecVEH,false,true);  
  •   
  •     MessageBox(NULL,"the fact infor333","test SEH hook",MB_OK);  
  •     //如果用下面的,是字面值需要VirtualProtect,并且和第2个MessageBox指向同一地址,则弹出内容还是被改变的。  
  •     //MessageBox(NULL,"the fact infor222","test SEH hook",MB_OK);  
  •     getchar();  
  • }  


[cpp] view plain copy


  • //VEH hook dll.  
  • // VEHHook.cpp : Defines the entry point for the DLL application.  
  • //  
  • #include <Windows.h>  
  • #include <TlHelp32.h>  
  • #include <stdio.h>  
  • #include <limits.h>  
  • #include <Winbase.h>  
  •   
  • typedef HANDLE (WINAPI *OPENTHREAD) (DWORD dwFlag, BOOL bUnknow, DWORD dwThreadId);   
  • OPENTHREAD g_lpfnOpenThread = NULL;   
  •   
  • typedef LONG  (WINAPI *PVECTOREDEXCEPTIONHANDLER)(PEXCEPTION_POINTERS ExceptionInfo);  
  •   
  • typedef PVOID (WINAPI *ADDVECTOREEXCEPTIONHANDLER)(  
  •     ULONG FirstHandler,  
  •     PVECTOREDEXCEPTIONHANDLER VectoredHandler  
  • );  
  • ADDVECTOREEXCEPTIONHANDLER g_AddVectorExceptionHandler = 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("arameters\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, "Be Hooked!");  
  •     VirtualProtect(text,length,oldprotect,&oldprotect);  
  • }  
  •   
  • void __declspec(naked) ReturnOriginalFunc(void) {  
  •     __asm {  
  •         mov edi,edi  
  •         jmp [func_addr_offset]  
  •     }  
  • }  
  •   
  • LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) {  
  •     if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {  
  •         if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr) {  
  •             PCONTEXT 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 VEHHook(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时候为-1  
  •                             memcpy(&prev_creation_time, &creation_time, sizeof(FILETIME));  
  •                             if(hMainThread != NULL)  
  •                                 CloseHandle(hMainThread);  
  •                             hMainThread = hThread;  
  •                     }  
  •                     else  
  •                            CloseHandle(hThread);  
  •   
  •   
  •                 }  
  •                 thread_entry32.dwSize = sizeof(THREADENTRY32);  
  •             } while(Thread32Next(hTool32, &thread_entry32));  
  •   
  •             //(void)SetUnhandledExceptionFilter(ExceptionFilter);  
  •             g_AddVectorExceptionHandler(1, ExceptionFilter);  
  •             CONTEXT thread_context = {CONTEXT_DEBUG_REGISTERS};  
  •             thread_context.Dr0 = func_addr;  
  •             thread_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 = :oadLibrary("kernel32.dll");  
  •         g_lpfnOpenThread =  (OPENTHREAD)::GetProcAddress(hDll, "OpenThread");   
  •         func_addr = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");  
  •         func_addr_offset = func_addr+2;  
  •         printf("MessageBoxA Addr: 0x%x\n",func_addr);  
  •         g_AddVectorExceptionHandler = (ADDVECTOREEXCEPTIONHANDLER)GetProcAddress(GetModuleHandle("kernel32.dll"), "AddVectoredExceptionHandler");  
  •         VEHHook();  
  •     }  
  •     return TRUE;  
  • }  


郁金香外挂教程,学习中...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

限时限量优惠

QQ|小黑屋|手机版|郁金香外挂技术-郁金香灬老师 ( 苏ICP备10059359号 )

GMT+8, 2019-9-16 10:05 , Processed in 0.053219 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表