int _tmain(int argc, _TCHAR* argv[]) { if( argc<2 ) { Usage(); return 1; } if( 0 == strncmp(argv[1], "-g", 2) ) { // generate test files and registry values return Generate(); } else if( 0 == strncmp(argv[1], "-c", 2) ) { // check generated files return Check(); } else if( 0 == strncmp(argv[1], "-s", 2) ) { // return ShowRegValue(); } else if( 0 == strncmp(argv[1], "-d", 2) ) { return DeleteValue(); } else { Usage(); return 1; } 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; }
int Generate() { char sBuf[255]; DWORD dwSize; HANDLE hFile = NULL; BOOL fReturnValue; const char szxReplacedFile[] = "c:\\testFileIsReplaced"; const char szxMovedFileWithRepl[] = "c:\\testFileShouldBeMovedW"; const char szxMovedFile[] = "c:\\testFileShouldBeMoved"; const char szxNewMovedFile[] = "c:\\testFileIsMoved"; const char szxDeletedFile[] = "c:\\testFileShouldBeDeleted"; memset(sBuf, 0xaa, sizeof(sBuf)); // create the first file for moving hFile = CreateFile( szxMovedFile, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(NULL == hFile) { printf("Can't create the %s file, err=%ld \n", szxMovedFile, GetLastError()); return 1; } WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL); CloseHandle(hFile); // create the second file for removing hFile = CreateFile( szxDeletedFile, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(NULL == hFile) { printf("Can't create the %s file, err=%ld \n", szxDeletedFile, GetLastError()); return 1; } WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL); CloseHandle(hFile); hFile = CreateFile( szxReplacedFile, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(NULL == hFile) { printf("Can't create the %s file, err=%ld \n", szxReplacedFile, GetLastError()); return 1; } WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL); CloseHandle(hFile); hFile = CreateFile( szxMovedFileWithRepl, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(NULL == hFile) { printf("Can't create the %s file, err=%ld \n", szxMovedFileWithRepl, GetLastError()); return 1; } WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL); CloseHandle(hFile); fReturnValue = MoveFileEx( szxDeletedFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); if( !fReturnValue ) { printf("Can't move the %s file, err=%ld \n", szxDeletedFile, GetLastError()); return 1; } ShowRegValue(); fReturnValue = MoveFileEx( szxMovedFile, szxNewMovedFile, MOVEFILE_DELAY_UNTIL_REBOOT); if( !fReturnValue ) { printf("Can't move the %s file, err=%ld \n", szxMovedFile, GetLastError()); return 1; } ShowRegValue(); fReturnValue = MoveFileEx( szxMovedFileWithRepl, szxReplacedFile, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING); if( !fReturnValue ) { printf("Can't move the %s file, err=%ld \n", szxMovedFileWithRepl, GetLastError()); return 1; } ShowRegValue(); return 0; }