反调试 - SetUnhandledExceptionFilter

原理

SetUnhandledExceptionFilter 可以注册一个异常处理函数,当一个异常产生且我们的 try - catch(或 try - expect)没有处理处理这个异常时,异常会转交给 SetUnhandledExceptionFilter ,这是我们的应用程序处理异常的最后机会。

我们可以自己触发一个异常,然后不在 try-catch 中处理它,如果存在调试器则调试器就会接管这个异常,那么这个异常就不会走到我们的 SetUnhandledExceptionFilter 注册的异常处理函数(调试器默认情况下是接管的,当然调试器也可以选择不接管这个异常,所以这属于一种比较低级的反调试手段 🙃)

函数介绍

/*
	允许应用程序替代进程的每个线程的顶级异常处理程序
	返回值:用该函数建立的上一个异常过滤器的地址
*/
LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter	// 一个指向顶级异常过滤器函数的指针,这个函数的返回值必须是 EXCEPTION_EXECUTE_HANDLER 或 EXCEPTION_CONTINUE_EXECUTION 或 EXCEPTION_CONTINUE_SEARCH
);

/*
	在调用线程中引发异常
*/
VOID RaiseException(
  DWORD           dwExceptionCode,			// 异常代码,参考:https://docs.microsoft.com/en-us/windows/win32/debug/getexceptioncode
  DWORD           dwExceptionFlags,			// 异常标志,0表示连续异常,EXCEPTION_NONCONTINUABLE 表示非连续异常
  DWORD           nNumberOfArguments,		// lpArguments 的参数数量
  const ULONG_PTR *lpArguments				// 参数数组
);

代码示例

// Test_Console_1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>

using namespace std;

// 如果有调试器,则不会执行这个函数
BOOL bIsBeinDbg = TRUE;
LONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers){
    bIsBeinDbg = FALSE;
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main()
{
    // 注册异常处理函数
    LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter);

    // 主动抛出一个异常
    RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL);

    if (bIsBeinDbg == TRUE) {
        cout << "发现调试器!" << endl;
    }
    else {
        cout << "没有调试器!" << endl;
    }

main_end:
    getchar();
    return 0;
}

效果图

vs调试:
在这里插入图片描述

正常打开:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值