Debug and Exceptions

Commissioning and abnormal

Termination of treatmentSEH

Terminator: guaranteed during execution of the program, we will execute the code block _finally

  • __ try to ensure that regardless of the manner in which exited, eventually executed __finally
    • Can not handle the exception, usually only used to perform cleanup
    • __ try: Saved usually requires the code detecting
      __ finally: a code is stored will perform
      __ leave: the block to exit __try
int main()
{
    __try 
    {
        printf("__try { ... }\n");

        // 推荐使用 __leave 退出代码块,使用跳转语句会产生多余的函数调用
        // __leave 对应实际是一条 jmp 语句,执行更加的迅速
        __leave;

        // 使用跳转指令退出 __try 块,例如 continue break goto return
        goto label_exit;
    }
    __finally
    {
        // 通常用于执行某一些特定的清理工作,比如关闭句柄或释放内存
        printf("__finally { ... }\n");

        // 使用 AbnormalTermination 判断是否是正常退出的
        if (AbnormalTermination())
            printf("异常退出代码块");
        else
            printf("正常退出代码块");
    }

label_exit:

    return 0;
}

Exception HandlingSEH

  • SEHTwo implementations process can not exist simultaneously, but can be nested
  • SEHThe handler is stored in the stack, so different thread has its own handler

Exception handler SEH: it can be used to capture the generated exception, and it executes the corresponding handler

__try: Is to be protected (potential exception) code

__except: Storing the filter expression and exception handling block

  • Save abnormal structural abnormalities environmental information and thread

    typedef struct _EXCEPTION_POINTERS {
         PEXECPTION_RECORD ExceptionRecord;   //保存了[异常类型]和[产生异常的指令所在的位置]
         PCONTEXT ContextRecord;             //保存的是异常发生时的寄存器环境,通过修改可以恢复异常
    } EXCEPTION_POINTERS, * PEXCEPTION_POINTERS;
  • Filter function: according to different situations, a different type of return value

    DWORD FilterHandler(DWORD ExceptionCode, PEXCEPTION_POINTERS ExceptionInfo)
    {
      // 假设产生的是一个整数除零异常,尝试对异常进行处理,并返回继续执行
      if (ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
      {
          ExceptionInfo->ContextRecord->Ecx = 1;
          return EXCEPTION_CONTINUE_EXECUTION;
      }
    
      // 否则其它的异常不做处理,向上传递
      return EXCEPTION_CONTINUE_SEARCH;
    }
  • Content __except () filter expression can be any form, but its value must be one of the following three, usually a function call

    1. EXCEPTION_EXECUTE_HANDLER (1): indicates capturing the exception, the code needs to perform exception handling block and continue
    2. EXCEPTION_CONTINUE_SEARCH (0): represents nothing, to other exception handlers, it usually does not return a process.
    3. EXCEPTION_CONTINUE_EXECUTION (-1): said they did not believe can not be executed, you need to re-run it again, the only exception handling will be used.
  • Exception filter function typically requires two function calls

    • GetExceptionCode(): The type of acquired abnormality generated, only the filter expression and exception handling block in use
    • GetExceptionInformation(): Gets the exception of environmental information and thread when an exception is generated, only == filter expressions == use
int main()
{
    __try
    {
        printf("__try{ ... }\n");

        //可能会产生异常的指令,只有产生了异常才会执行 __except
        __asm mov eax, 100
        __asm xor edx, edx
        __asm xor ecx, ecx
        __asm idiv ecx

        printf("异常已经被处理了!\n");

        //用来触发内存访问异常
        //*(DWORD*)0 = 0;
    }

    __except (FilterHandler(GetExceptionCode(), GetExceptionInformation()))
    {
        //只有在异常类型为EXCEPTION_EXCUTE_HANDLER才会执行
        printf("__except (EXCEPTION_EXECUTE_HANDLER) { ... }");
    }

    return 0;

Top-level exception ( UEH)

  • Top-level exception handler ( UEH): is the last line of defense applications, when all SEHare not able to handle the exception, it will be executed
    • UEHError information (type of exception thread context and memory) are commonly used to perform a memory dump operation, the collected submitted to the server
    • UEH Within the debugger in 64-bit operating system is never executed == == requires a separate operation.

Top custom exception handler, even if no custom, there will be a default handler, and only one, type, and its return value SEHare the same, but the lack of EXCEPTION_EXECUTE_HANDLER

LONG WINAPI TopLevelExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
    printf("TopLevelExceptionHandler(): %08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);

    // 假设产生的是一个整数除零异常,尝试对异常进行处理,并返回继续执行
    if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
    {
        ExceptionInfo->ContextRecord->Ecx = 1;
        return EXCEPTION_CONTINUE_EXECUTION;    // -1
    }

    // 否则其它的异常不做处理,向上传递
    return EXCEPTION_CONTINUE_SEARCH;           // 0
}



int main()
{
    // 顶层异常处理的设置依赖于一个函数
    SetUnhandledExceptionFilter(TopLevelExceptionHandler);

    __try
    {
        // 产生除零异常
        __asm mov eax, 100
        __asm xor edx, edx
        __asm xor ecx, ecx
        __asm idiv ecx
    }
    __except (EXCEPTION_CONTINUE_SEARCH)
    {
        // 这里永远不会执行,因为不是 EXCEPTION_EXECUTE_HANDLER(1)
        printf("__except (EXCEPTION_CONTINUE_SEARCH)\n");

    }

    printf("异常处理成功!");
    system("pause");

    return 0;
}

Vectored exception handler ( VEH)

  • A mechanism for user-level support in SEHthe execution before, stored in a global list, the entire process can be accessed.
  • Custom VEHexception handler, its execution is located SEHbefore, if VEHnot dealt with successfully, will be calledSEH
LONG WINAPI VectoredExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
    printf("VectoredExceptionHandler(): %08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);

    // 假设产生的是一个整数除零异常,尝试对异常进行处理,并返回继续执行
    if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
    {
        ExceptionInfo->ContextRecord->Ecx = 1;
        return EXCEPTION_CONTINUE_EXECUTION;    // 0
    }

    // 否则其它的异常不做处理,向上传递
    return EXCEPTION_CONTINUE_SEARCH;           // 1
}


int main()
{
    // 设置一个向量化异常处理函数(VEH),参数一表示添加到异常处理函数链表的位置
    AddVectoredExceptionHandler(TRUE, VectoredExceptionHandler);

    __try
    {
        // 产生除零异常
        __asm mov eax, 100
        __asm xor edx, edx
        __asm xor ecx, ecx
        __asm idiv ecx
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        // 这里永远不会执行,因为不是 EXCEPTION_EXECUTE_HANDLER(1)
        printf("__except (EXCEPTION_EXECUTE_HANDLER)\n");

    }

    printf("异常处理成功!");
    system("pause");

    return 0;
}

Vectored exception handlerVCH

  • Vectored exception handler ( VCH): User A mechanism support layer, the last to be executed

    • Stored in a global list, the entire process can access to, and VEHat the same table, but different flag
    • VCH Only in the case of the exception it is handled, the last to be executed
    • VEH -> SEH -> UEH -> VCH
  • Custom UEHFunctions in SEHafter execution

    LONG WINAPI TopLevelExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
    {
      printf("TopLevelExceptionHandler(): %08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    
      // 假设产生的是一个整数除零异常,尝试对异常进行处理,并返回继续执行
      if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
      {
          ExceptionInfo->ContextRecord->Ecx = 1;
          return EXCEPTION_CONTINUE_EXECUTION;
      }
    
      // 否则其它的异常不做处理,向上传递
      return EXCEPTION_CONTINUE_SEARCH;
    }
  • Custom VEHexception handler, his execution is located SEHbefore, if VEHnot dealt with successfully, will be calledSEH

    LONG WINAPI VectoredExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
    {
      printf("VectoredExceptionHandler(): %08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    
      // 否则其它的异常不做处理,向上传递
      return EXCEPTION_CONTINUE_SEARCH;
    }
  • Custom VCHexception handler, the only exception handling in case of success, the final will be called

    LONG WINAPI VectoredContinueHandler(EXCEPTION_POINTERS* ExceptionInfo)
    {
      printf("VectoredContinueHandler(): %08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
      return EXCEPTION_CONTINUE_SEARCH;
    }
  • Filter function: according to different situations, the return value of different types of

    DWORD FilterHandler(DWORD ExceptionCode, PEXCEPTION_POINTERS ExceptionInfo)
    {
      printf("FilterHandler(): %08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    
      // 否则其它的异常不做处理,向上传递
      return EXCEPTION_CONTINUE_SEARCH;
    }
int main()
{
    // 设置一个向量化异常处理函数(VEH)
    AddVectoredExceptionHandler(TRUE, VectoredExceptionHandler);
    // 设置一个向量化异常处理函数(VCH)
    AddVectoredContinueHandler(TRUE, VectoredContinueHandler);
    // UEH 处理函数
    SetUnhandledExceptionFilter(TopLevelExceptionHandler);

    __try
    {
        // 产生除零异常
        __asm mov eax, 100
        __asm xor edx, edx
        __asm xor ecx, ecx
        __asm idiv ecx
    }
    __except (FilterHandler(GetExceptionCode(), GetExceptionInformation()))
    {
        // 这里永远不会执行,因为不是 EXCEPTION_EXECUTE_HANDLER(1)
        printf("__except (EXCEPTION_EXECUTE_HANDLER)\n");
    }

    printf("异常处理成功!");
    system("pause");

    return 0;
}

SEHPrinciple analysis

  • SEHStored in a TEBstructure where the offset is 0, is a linked list, SEHthe list can FS : [0]find such an address

    TEBYou can FS:[0X18]find such an address.

  • try exceptIn principle it is SEHto add a new node in the list

// 自定义的SEH 函数
EXCEPTION_DISPOSITION NTAPI ExceptionHandler(
    struct _EXCEPTION_RECORD* ExceptionRecord,
    PVOID EstablisherFrame,
    struct _CONTEXT* ContextRecord,
    PVOID DispatcherContext)
{
    return ExceptionContinueSearch;
}

//遍历当前线程中的所有 SEH函数
void GetThreadList()
{
    //1. 获取当前 SEH 链表的头节点
    PEXCEPTION_REGISTRATION_RECORD ExceptionList = nullptr;
    __asm
    {
        push FS : [0]
        POP ExceptionList
    }

    //遍历 SEH 中的所有函数
    while (ExceptionList != (PEXCEPTION_REGISTRATION_RECORD)-1)
    {
        //输出当前层,对应的处理函数
        printf("0x%08X\n", ExceptionList->Handler);

        //将指针指向下一个节点
        ExceptionList = ExceptionList->Next;
    }
    printf("\n");
}

int main()
{
    // 0 保存 SEH 头节点,主要用于恢复
    PEXCEPTION_REGISTRATION_RECORD ExceptionList = nullptr;
    __asm
    {
        push FS : [0];
        pop ExceptionList;
    }

    // 1 添加自定义 SEH 函数之前的 SEH 链
    GetThreadList();

    // 2 添加自定义 SEH 函数之前的 SEH 链
    __asm
    {
        push ExceptionHandler
        push fs : [0]
        mov fs : [0], esp
    }

    // 3 添加自定义 SEH 函数之后的 SEH 链
    GetThreadList();

    // 4 恢复旧的 SEH 头节点
    __asm
    {
        add esp, 0x08
        mov eax, ExceptionList
        mov fs : [0], eax
    }

    // 5 应该和以前的节点是相同的
    GetThreadList();

    return 0;
}

Abnormal distribution process

Abnormal distribution processes _00

  1. Processing int3function abnormality isKitTrap03
  2. Exception handling starts at the beginning, the first structure TRAP_FRAMEwhen the frame structure of the trap, the trap frame refers to a structure used to save the system calls, interrupts, register on-site when an exception occurs, the user space to facilitate future back / back to the interrupted, recovery the values of those registers continue.
  3. Notes that KitTrap03actually callsCommonDispatchException

supplement

IDT:Interrupt descriptor table Interrupt Descriptor Table( )

CPUPrivilege Level R0- R3a total of three levels, the operating system execution state into the kernel mode and user mode , the CPU is set at the particular stage of kernel mode R0, in particular for the subscriber station counter stageR3

Guess you like

Origin www.cnblogs.com/TJTO/p/11373984.html
Recommended