Win32编程

7、异常处理

1、课程目标

  1. 理解Windows异常处理机制
  2. 掌握SEH和VEH的使用
  3. 学会异常过滤器的编写
  4. 理解反调试中的异常利用

2、名词解释

术语 英文 说明
SEH Structured Exception Handling 结构化异常处理
VEH Vectored Exception Handling 向量化异常处理
异常记录 EXCEPTION_RECORD 描述异常的结构
上下文 CONTEXT CPU寄存器状态

3、代码实现

3.1、示例1:SEH基础

#include <windows.h>
#include <stdio.h>

void SEHDemo() {
    __try {
        int* p = NULL;
        *p = 123;  // 触发访问违规
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        printf("Exception caught!\n");
    }
    
    printf("Program continues\n");
}

3.2、示例2:异常过滤器

#include <windows.h>
#include <stdio.h>

int ExceptionFilter(EXCEPTION_POINTERS* pExp) {
    DWORD code = pExp->ExceptionRecord->ExceptionCode;
    
    printf("Exception Code: 0x%08X\n", code);
    printf("Exception Address: %p\n", pExp->ExceptionRecord->ExceptionAddress);
    
    if (code == EXCEPTION_ACCESS_VIOLATION) {
        printf("Access Violation!\n");
        return EXCEPTION_EXECUTE_HANDLER;
    }
    
    return EXCEPTION_CONTINUE_SEARCH;
}

void FilterDemo() {
    __try {
        int* p = NULL;
        *p = 123;
    }
    __except (ExceptionFilter(GetExceptionInformation())) {
        printf("Handling exception\n");
    }
}

3.3、示例3:VEH向量化异常处理

#include <windows.h>
#include <stdio.h>

LONG CALLBACK VectoredHandler(EXCEPTION_POINTERS* pExp) {
    if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
        printf("VEH: Access Violation at %p\n", 
               pExp->ExceptionRecord->ExceptionAddress);
        
        // 可以修改上下文继续执行
        pExp->ContextRecord->Eip += 2;  // 跳过指令
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    
    return EXCEPTION_CONTINUE_SEARCH;
}

void VEHDemo() {
    // 注册VEH处理器(优先于SEH)
    PVOID handle = AddVectoredExceptionHandler(1, VectoredHandler);
    
    // 触发异常
    int* p = NULL;
    *p = 123;
    
    printf("Continued after exception\n");
    
    RemoveVectoredExceptionHandler(handle);
}

3.4、示例4:自定义异常

#include <windows.h>
#include <stdio.h>

#define MY_EXCEPTION 0xE0000001

void RaiseCustomException() {
    __try {
        RaiseException(MY_EXCEPTION, 0, 0, NULL);
    }
    __except (GetExceptionCode() == MY_EXCEPTION ? 
              EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        printf("Custom exception caught!\n");
    }
}

4、课后作业

  1. 基础练习:使用SEH处理除零异常
  2. VEH应用:实现全局异常日志记录
  3. 异常过滤:根据异常类型执行不同处理
  4. 反调试:利用异常机制检测调试器