-
-
SetUnhandledExceptionFilter函数在C、C++、VC中的使用
-
发表于:
2010-5-21 16:34
8739
-
SetUnhandledExceptionFilter函数在C、C++、VC中的使用
这个问题终于解决,把最终代码贡献出来,
最近在看异常处理的内容,想用VC实现SetUnhandledExceptionFilter函数的调用,遇到一些问题,向各路大侠求助
(1)VC自动提示的CONTEXT结构与Win32汇编中的CONTEXT结构不同,没有EIP、EAX等系列寄存器,而是一些Gpr0、Fpr0、Msr、Iar、Lr、Ctr寄存器,为什么呢?我自己声明了这个结构来用,可以吗?
(2)如何使异常处理结束后回到一个安全的位置呢? 就是这个新的指向安全位置的EIP的值如何获取
(3)我编写的下列代码有一些问题,它会连续三次弹出“回调函数”、“安全函数”对话框,然后就产生了一个异常,确定后程序退出,忽略后会继续连续弹出上边的两个对话框直至程序自动终止,什么原因哈..
(4)敬请提供在非汇编环境下实现这个SetUnhandledExceptionFilter函数的源码,C、C++、VC、内联汇编皆可,不胜感激。
下面的代码是可以运行的,分别是C++和MFC中的实现
//********************************************************
1. 顶级异常处理 C++
#include <windows.h>
#include <stdio.h>
DWORD NewEip;
DWORD lpOldHandler;
typedef LPTOP_LEVEL_EXCEPTION_FILTER (_stdcall *pSetUnhandledExceptionFilter)(
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
pSetUnhandledExceptionFilter lpSetUnhandledExceptionFilter;
LONG WINAPI TopUnhandledExceptionFilter(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
_asm pushad
MessageBox(NULL,"回调函数被调用","回调函数",MB_OK);
ExceptionInfo->ContextRecord->Eip=NewEip;
lpSetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER )lpOldHandler);
_asm popad
return EXCEPTION_CONTINUE_EXECUTION;
}
/*void Bug()
{
_asm{
mov SafeAddr,offset NewEip
int 3
NewEip:
}
}*/
int main()
{
lpSetUnhandledExceptionFilter=(pSetUnhandledExceptionFilter)GetProcAddress(LoadLibrary(("kernel32.dll")),"SetUnhandledExceptionFilter");
lpOldHandler=(DWORD)lpSetUnhandledExceptionFilter(TopUnhandledExceptionFilter);
// Bug();
_asm{
mov NewEip,offset SafeAddr
int 3
SafeAddr:
}
MessageBox(NULL,"安全位置","成功回到安全位置",MB_OK);
return 1;
}
2. 顶级异常处理 MFC
//********************************************************
static DWORD lpOldHandler;
typedef LPTOP_LEVEL_EXCEPTION_FILTER (_stdcall *pSetUnhandledExceptionFilter)(
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
pSetUnhandledExceptionFilter lpSetUnhandledExceptionFilter;
LONG WINAPI TopUnhandledExceptionFilter(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
_asm pushad
AfxMessageBox("回调函数");
lpSetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER )lpOldHandler);
ExceptionInfo->ContextRecord->Eip=NewEip;//转移到安全位置
_asm popad
return EXCEPTION_CONTINUE_EXECUTION;
}
void CDetectODDlg::OnSetUnhandledExceptionFilter()
{
bool isDebugged=0;
// TODO: Add your control notification handler code here
lpSetUnhandledExceptionFilter = (pSetUnhandledExceptionFilter)GetProcAddress(LoadLibrary(("kernel32.dll")),
"SetUnhandledExceptionFilter");
lpOldHandler=(DWORD)lpSetUnhandledExceptionFilter(TopUnhandledExceptionFilter);
_asm{ //获取这个安全地址
call me //方式一,需要NewEip加上一个偏移值
me:
pop NewEip //方式一结束
mov NewEip,offset safe //方式二,更简单
int 3 //触发异常
}
AfxMessageBox("检测到OD");
isDebugged=1;
_asm{
safe:
}
if(1==isDebugged){
}else{
AfxMessageBox("没有OD");
}
}
//********************************************************
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)