VC利用調試寄存器實現硬件斷點源碼
阿新 • • 發佈:2018-07-31
.com new 繼續 add proc 興趣 xe8 else if 發生 【文章標題】:VC利用調試寄存器實現硬件斷點源碼
【文章作者】:yhswwr(SilenceRet)
【作者QQ】:3412259
【編寫語言】:C++
【使用工具】:VS2008.VC++9
【本文鏈接】:http://bbs.pediy.com/showthread.php?p=1122838
【參考鏈接】:http://bbs.pediy.com/showthread.php?t=107515
【作者聲明】:只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!(當前行剽竊自justhxy)
jpg改rar
【文章作者】:yhswwr(SilenceRet)
【作者QQ】:3412259
【編寫語言】:C++
【使用工具】:VS2008.VC++9
【本文鏈接】:http://bbs.pediy.com/showthread.php?p=1122838
【參考鏈接】:http://bbs.pediy.com/showthread.php?t=107515
【作者聲明】:只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!(當前行剽竊自justhxy)
/************************************************************************ SetHardWareBP: 設置線程硬件斷點 hThread: 線程句柄 dwAddr: 斷點地址 dwDrIndex: 硬件寄存器(0~3) nType: 斷點類型(0:執行,1:讀取,2:寫入) nLen: 讀寫斷點數據長度(1,2,4) /************************************************************************/ BOOL SetHardWareBP(HANDLE hThread,DWORD dwAddr,DWORD dwDrIndex=0,UINT nType=0,UINT nLen=1) { BOOL bResult=FALSE; CONTEXT context = {0}; context.ContextFlags=CONTEXT_DEBUG_REGISTERS; if(::GetThreadContext(hThread,&context)) { DWORD dwDrFlags=context.Dr7; //將斷點地址復制進入對應Dr寄存器(參考CONTEXT結構) memcpy(((BYTE *)&context)+4+dwDrIndex*4,&dwAddr,4); //決定使用哪個寄存器 dwDrFlags|=(DWORD)0x1<<(2*dwDrIndex); //見OD讀寫斷點時 這個置位了,執行沒有(置位也正常-_-) dwDrFlags|=0x100; //先[COLOR="Sienna"]將對應寄存器對應4個控制位清零(先或,再異或,還有其它好方法嗎)[/COLOR] =.= 悲催的小學生 dwDrFlags|=(DWORD)0xF<<(16+4*dwDrIndex); dwDrFlags^=(DWORD)0xF<<(16+4*dwDrIndex); //設置斷點類型,執行:00 讀取:11 寫入:01 //([B][COLOR="Olive"]不知何故,測試時發現不論是11還是01,讀寫數據時均會斷下來[/COLOR][/B]) if (nType==1) dwDrFlags|=(DWORD)0x3<<(16+4*dwDrIndex); //讀取 else if(nType==2) dwDrFlags|=(DWORD)0x1<<(16+4*dwDrIndex); //寫入 //else if(nType==0) //dwDrFlags=dwDrFlags //執行 //設置讀寫斷點時數據長度 if (nType!=0) { if(nLen==2 && dwAddr%2==0) dwDrFlags|=(DWORD)0x1<<(18+4*dwDrIndex); //2字節 else if(nLen==4 && dwAddr%4==0) dwDrFlags|=(DWORD)0x3<<(18+4*dwDrIndex); //4字節 } context.Dr7=dwDrFlags; if (::SetThreadContext(hThread,&context)) bResult=TRUE; } return bResult; }
//異常處理 //直接從工程中拷出來的 typedef ULONG (WINAPI *pfnRtlDispatchException)(PEXCEPTION_RECORD pExcptRec,CONTEXT * pContext); static pfnRtlDispatchException m_fnRtlDispatchException=NULL; BOOL RtlDispatchException(PEXCEPTION_RECORD pExcptRec,CONTEXT * pContext); ULONG WINAPI CSysHook::_RtlDispatchException( PEXCEPTION_RECORD pExcptRec,CONTEXT * pContext ) { if(RtlDispatchException(pExcptRec,pContext)) return 1; return m_fnRtlDispatchException(pExcptRec,pContext); } //Hook程序異常處理,當程序發生異常時,由ring0轉回ring3時調用的第一個函數:KiUserExceptionDispatcher BOOL CSysHook::HookSystemSEH() { BOOL bResult=FALSE; BYTE *pAddr=(BYTE *)::GetProcAddress(::GetModuleHandleA("ntdll"),"KiUserExceptionDispatcher"); if (pAddr) { while (*pAddr!=0xE8)pAddr++; //XP~Win7正常,Win8尚無緣得見 m_fnRtlDispatchException=(pfnRtlDispatchException)((*(DWORD *)(pAddr+1))+5+(DWORD)pAddr); //得到原函數地址 DWORD dwNewAddr=(DWORD)_RtlDispatchException-(DWORD)pAddr-5; //計算新地址 CMemory::WriteMemory((DWORD)pAddr+1,(BYTE *)&dwNewAddr,4); //這個寫內存的自己改造吧 bResult=TRUE; } return bResult; } [COLOR="Olive"]//異常處理函數 BOOL RtlDispatchException(PEXCEPTION_RECORD pExcptRec,CONTEXT * pContext) { 返回TRUE,這個異常我已經處理好了,繼續運行程序 返回FALSE,這個異常不是我的,找別人處理去 }[/COLOR]
VC利用調試寄存器實現硬件斷點源碼