int main(int argc, char* argv[]) { // SHOW_ERROR(0); for (;;) { ShowMainMenu(); switch(WaitForUserInput()) { case 'D': ShowDevManageMenu(); break; case 'A': ShowAuthenticationMenu(); break; case 'P': ShowApplicationMenu(); break; case 'F': ShowFileMenu(); break; case 'C': ShowContainerMenu(); break; case 'Y': ShowCryptoMenu(); break; case '1': // TestAllAuth(); // break; // case '2': TestOpenContainer(); break; case 'X': return 0; break; default: break; } } return 0; }
BOOL CHandleException::HandleInt3Exception()//处理INT3异常 { BOOL bRet; CCPointInfo tempPointInfo; CCPointInfo* pResultPointInfo = NULL; char CodeBuf[24] = {0}; /* 过滤初始断点,当新进程的初始线程在自己的上下文中初始化时,作为进程初始化的一个步骤, ntdll.dll中的LdrpInitializeProcess函数会检查正在初始化的进程是否处于被调试状态(检查 PEB的BeingDebugged字段),如果是,他会调用DbgBreakPoint()触发一个断点异常, 目的是中断到调试器,称为初始断点。 */ //先过掉系统的INT3断点 if (m_IsSystemInt3 == TRUE) { m_IsSystemInt3 = FALSE; return TRUE; } //程序刚启动,停在OEP处 if(m_DbgInfo.ExceptionRecord.ExceptionAddress == m_lpOepAddr && m_bIsStart == TRUE) { m_bIsStart = FALSE; //枚举目标进程的模块,并写入 g_DllList EnumDestMod(); } memset(&tempPointInfo, 0, sizeof(CCPointInfo)); tempPointInfo.lpPointAddr = m_DbgInfo.ExceptionRecord.ExceptionAddress; tempPointInfo.ptType = ORD_POINT; if(!FindPointInList(tempPointInfo, &pResultPointInfo, TRUE)) { //没有找到对应断点,则说明不是用户或者调试器的断点 //返回FALSE,调试器不处理,交给系统继续分派异常 return FALSE; } else //找到了断点 { ShowBreakPointInfo(pResultPointInfo); BOOL bRet = WriteProcessMemory(m_hProcess, //写回原来的字节 m_pFindPoint->lpPointAddr, &(m_pFindPoint->u.chOldByte), 1, NULL); if (bRet == FALSE) { printf("WriteProcessMemory error!\r\n"); return FALSE; } //获取当前线程的Context UpdateContextFromThread(); //0xcc 向前减去 m_Context.Eip--; m_Eip = (LPVOID)m_Context.Eip; if (m_pFindPoint->isOnlyOne == TRUE) //是一次性断点 { g_ptList.remove(m_pFindPoint); delete m_pFindPoint; m_pFindPoint = nullptr; } // else //不是一次性断点,就会是用户设置的断点, //需要设置单步,被调试进程再运行就会触发单步异常,到单步中异常中去处理, { //设置单步#define TF 0x100 标志寄存器TF位 m_Context.EFlags |= TF; m_isNeedResetPoint = TRUE; // } } //更新线程的Context UpdateContextToThread(); //是否是单步记录模式,Trace功能 if (m_isStepRecordMode == TRUE) { bRet = ReadProcessMemory(m_hProcess, (LPVOID)m_Context.Eip, CodeBuf, 24, NULL); if (bRet == FALSE) { printf("ReadProcessMemory error!"); return FALSE; } //记录指令 RecordCode(m_Context.Eip, CodeBuf); return TRUE; } //显示反汇编代码 m_lpDisAsmAddr = m_DbgInfo.ExceptionRecord.ExceptionAddress; ShowAsmCode(); ShowRegValue(NULL); //等待用户输入 bRet = FALSE; while (bRet == FALSE) { bRet = WaitForUserInput(); } return TRUE; }
BOOL CHandleException::HandleAccessException()//处理访问异常部分 内存断点 { BOOL bRet; DWORD dwAccessAddr; //读写地址 DWORD dwAccessFlag; //读写标志 BOOL isExceptionFromMemPoint = FALSE; //异常是否由内存断点设置引起,默认为否 CCPointInfo* pPointInfo = NULL; //命中的断点 BOOL isHitMemPoint = FALSE; //EXCEPTION_ACCESS_VIOLATION //If this value is zero, the thread attempted to read the inaccessible data. //If this value is 1, the thread attempted to write to an inaccessible address. //If this value is 8, the thread causes a user-mode data execution prevention (DEP) violation. dwAccessFlag = m_DbgInfo.ExceptionRecord.ExceptionInformation[0]; dwAccessAddr = m_DbgInfo.ExceptionRecord.ExceptionInformation[1]; //根据 访问地址 到“断点-分页表”中去查找 //同一个内存分页可能有多个断点 //如果没有在“断点-分页表”中查找到,则说明这个异常不是断点引起的 list<CCPointPage*>::iterator it = g_PointPageList.begin(); int nSize = g_PointPageList.size(); //遍历链表中每个节点,将每个匹配的“断点-分页记录”都添加到g_ResetMemBp链表中 for ( int i = 0; i < nSize; i++ ) { CCPointPage* pPointPage = *it; //如果在“断点-分页表”中查找到 //再根据断点表中信息判断是否符合用户所下断点信息 if (pPointPage->dwPageAddr == (dwAccessAddr & 0xfffff000))//判断触发异常的地址在不在断点表中 { CCResetMemBp *p = new CCResetMemBp; p->dwAddr = pPointPage->dwPageAddr; p->nID = pPointPage->nPtNum; g_ResetMemBp.push_back(p); //暂时恢复内存页原来的属性 BOOL bDoOnce = FALSE; if (!bDoOnce) { //这些操作只需要执行一次 bDoOnce = TRUE; isExceptionFromMemPoint = TRUE; TempResumePageProp(pPointPage->dwPageAddr); //暂时恢复页面属性 //设置单步,在单步中将断点设回 UpdateContextFromThread(); m_Context.EFlags |= TF; UpdateContextToThread(); } //先找到断点序号对应的断点 list<CCPointInfo*>::iterator it2 = g_ptList.begin(); for ( int j = 0; j < g_ptList.size(); j++ ) { pPointInfo = *it2; if (pPointInfo->nPtNum == pPointPage->nPtNum) { break; } it2++; } //再判断是否符合用户所下断点信息,断点类型和断点范围均相符 if (isHitMemPoint == FALSE) { if (dwAccessAddr >= (DWORD)pPointInfo->lpPointAddr && dwAccessAddr < (DWORD)pPointInfo->lpPointAddr + pPointInfo->dwPointLen) { if ( pPointInfo->ptAccess == ACCESS || (pPointInfo->ptAccess == WRITE && dwAccessFlag == 1) ) { isHitMemPoint = TRUE; // break; } } } } it++; } //如果异常不是由内存断点设置引起,则调试器不处理 if (isExceptionFromMemPoint == FALSE) { return FALSE; } //如果命中内存断点,则暂停,显示相关信息并等待用户输入 if (isHitMemPoint) { ShowBreakPointInfo(pPointInfo); //显示反汇编代码 m_lpDisAsmAddr = m_DbgInfo.ExceptionRecord.ExceptionAddress; ShowAsmCode(); ShowRegValue(NULL); //等待用户输入 bRet = FALSE; while (bRet == FALSE) { bRet = WaitForUserInput(); } } return TRUE; }