VEH帮你定位程序崩溃地址

   之前朋友有一个服务端程序,总是受到一些人的恶意漏洞攻击,没有源代码,只好反汇编修复了漏洞,并且使用WinLicense加保护授权.

   漏洞总不是一次可以修复完的,恶意攻击并没有停止,然后加了WL保护程序在崩溃的时候在没有提示信息,服务器日志中也没有记录任何有用的信息了,这里所需要有用的信息即是崩溃时候汇编代码运行的内存地址.c++写的程序崩溃的时候我们经常可以看到这种包含了运行址,以及访问内存地址相关信息的对话框.

   首先想到的办法是使用windbg的adplus -crash dump内存分析,cdb刚attach上目标进程就直接退出了,不错,WL检查到了调试器,自动触发了保护,程序退出进程了.所以通过windbg,od类似的调试器方案是行不通了.

  还有一次,攻击影响了客户端,使部分客户端崩溃,通过日志看到的错误内存地址,经过分析发现是在SEH中,即我们平常代码__try{}__except{}的__except{}代码中,关键是这层SEH还被上一层SEH包着,找了很久还是没能有效的定位到崩溃的内存地址.

   后来只好电话求助了小明哥,没说别的,就VEH向量化异常处理解决问题.

   更多的知识可以看雪http://bbs.pediy.com/showthread.php?t=173853

   通过看雪上的这篇文章我们可以了解到,在没有调试器的情况下,程序发生异常,如果有安装VEH,则VEH先处理异常,然后才是SEH,TopLevelEH.

   我要的东西很简单,就是程序崩溃的内存地址,即当时发生崩溃的时候,cpu EIP寄存器的值.

   代码就很简单了    

#define DBG_PRINTEXCEPTION_C             ((DWORD   )0x40010006L) 
LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS * pExceptionInfo)
{
	char lpMsg[512]={0}; 
	switch( pExceptionInfo->ExceptionRecord->ExceptionCode )  
		{  
		case DBG_PRINTEXCEPTION_C:
			 break;  
			 default:
			 {
				 memset(lpMsg,0,512);
				 wsprintfA(lpMsg,"Exp EIP:%x  ExpAddr:%x",pExceptionInfo->ContextRecord->Eip,pExceptionInfo->ExceptionRecord->ExceptionAddress);
				 OutputDebugStringA(lpMsg);
			 }
	}
	return EXCEPTION_CONTINUE_SEARCH;
}
BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		{
			AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)ExceptionHandler);
		}
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;
}

     不错,写一个dll,然后Exe程序启动进入Main函数后,直接反汇编写段代码,loadlibrary一下dll,即可.

     打开DbgView,运行目标进程,崩溃一出现,dbgview中就输出了Eip地址,在反汇编定位到代码处理,具体问题具体分析即可!

原文地址:https://www.cnblogs.com/dreamzgj/p/4374009.html