首页 > 代码库 > SEH反调试的实现与调试

SEH反调试的实现与调试

SEH用于反调试或者用于注册码的隐藏时。在没有异常时永远都是错误的注册码,只有当触发异常时,程序才走到注册成功的地方……

代码如下:

void CSehDlg::RegSuc()
{
	HWND hWnd = ::GetDlgItem(NULL, IDC_STC_TIP);
	::SetWindowText(hWnd, "Success!!");
}

void CSehDlg::RegFail()
{
	HWND hDlgWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
	HWND hWnd = ::GetDlgItem(hDlgWnd, IDC_STC_TIP);
	::SetWindowText(hWnd, "Failed!!");
}

void FirstLevelSeh(char chFlag)

{
	
		__try
		{
			INT a = chFlag;
			int b = a/0;
		}
		//定义异常处理模块
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			HWND hDlgWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
			HWND hWnd = ::GetDlgItem(hDlgWnd, IDC_STC_TIP);
			::SetWindowText(hWnd, "Success!!");
		}
}

void CSehDlg::OnReg() 
{
	// TODO: Add your control notification handler code here
	CString strName;
	CString strCode;
	GetDlgItemText(IDC_EDT_USERNAME, strName);
	GetDlgItemText(IDC_EDT_USERCODE, strCode);


	TCHAR chFlag = strName.GetAt(strName.GetLength()-1);
	if (chFlag == ‘0‘)
	{
		FirstLevelSeh(chFlag);
	}
	else
	{
		RegFail();
	}
}


只有当姓名的最后一位是“0”时,程序会调用0/0,引发一个除0异常,而在异常处理函数中才显示正确的注册码。


在这种情况下,在IDA中,如果姓名最后一位是0的话,程序会是个怎样的图形呢?




如上图所示的,在处理函数中IDA中的显示会有三个不同的函数头……而最右边成功时,是独立出来的。看起来好像在任何情况下都无法到达成功…………


在OD中程序又会是这个样子的……


进入这个有异常处理的函数401542后,是这个样子的……



上面代码中的

xor ecx, ecx

idiv ecx

会触发异常,程序就会跳到函数头时注册的异常处理函数中执行(就是在0040154C处注册的地方)……。


如果我们在调试到这个处理函数时,没有在异常处理函数中下断,在F7走到idiv ecx时,程序就会运行到系统领空,也就是程序跑飞了…………


解决方法:

所以如果要想走到正常的流程中,在这个函数头运行到0040154C的下一行代码是,在它的处理函数(00401c70处)上下断,就能把程序断下……


编译好的程序下载