程序使用API SetUnhandledExceptionFilter 来注册一个未处理异常的函数1,如果进程没有被调试,那么会触发一个未处理异常,导致操作系统会将控制权交给函数1。如果进程被调试,则调试器会捕捉这个未处理异常。这样,我们的函数1也就不会被执行了。 这里在触发异常时,则是跳回原来的代码来执行,而不会退出程序。 UnhandledExceptionFilter 这个函数修改了EIP的值,在参数_EXCEPTION_POINTERS中,保存了触发异常的指令地址。所以根据这个指令地址修改寄存器中EIP的值就可以了。 如果写成控制台程序,则这个控制台程序要支持MFC。 我的IDLE是VS2012。
- #include "stdafx.h"
- #include "ConsoleApplication66.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- CWinApp theApp;
- using namespace std;
- LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pei);
- bool UnhandledExceptionFilterApproach();
- int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
- {
- int nRetCode = 0;
- HMODULE hModule = ::GetModuleHandle(NULL);
- if (hModule != NULL)
- {
- if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
- {
- _tprintf(_T("错误\n"));
- nRetCode = 1;
- }
- else
- {
- if(!UnhandledExceptionFilterApproach())
- {
- puts("Hello World!");
- printf("Press any key to continue");
- getchar();
- }
- return 0;
- }
- }
- else
- {
- _tprintf(_T("错误: GetModuleHandle 失败\n"));
- nRetCode = 1;
- }
- return nRetCode;
- }
- LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *BlackDragon)
- {
- SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)BlackDragon->ContextRecord->Eax);
- BlackDragon->ContextRecord->Eip += 2;
- //继续执行进程剩余指令
- return EXCEPTION_CONTINUE_EXECUTION;
- }
- bool UnhandledExceptionFilterApproach()//检测调试器
- {
- SetUnhandledExceptionFilter(UnhandledExceptionFilter);
- __asm
- {
- //初始化
- xor eax,eax
- //触发异常
- div eax
- }
- return false;
- }
复制代码
|