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(); } }
在这种情况下,在IDA中,如果姓名最后一位是0的话,程序会是个怎样的图形呢?
如上图所示的,在处理函数中IDA中的显示会有三个不同的函数头……而最右边成功时,是独立出来的。看起来好像在任何情况下都无法到达成功…………
在OD中程序又会是这个样子的……
进入这个有异常处理的函数401542后,是这个样子的……
上面代码中的
xor ecx, ecx
idiv ecx
会触发异常,程序就会跳到函数头时注册的异常处理函数中执行(就是在0040154C处注册的地方)……。
如果我们在调试到这个处理函数时,没有在异常处理函数中下断,在F7走到idiv ecx时,程序就会运行到系统领空,也就是程序跑飞了…………
解决方法:
所以如果要想走到正常的流程中,在这个函数头运行到0040154C的下一行代码是,在它的处理函数(00401c70处)上下断,就能把程序断下……
原文:http://blog.csdn.net/xiaocaiju/article/details/25995495