zoukankan      html  css  js  c++  java
  • VC利用调试寄存器实现硬件断点源码

    【文章标题】: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)
    /************************************************************************
    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]
    
    
    jpg改rar
  • 相关阅读:
    css3 box-shadow
    JS的Document属性和方法
    简单配色方案web
    ps中参考线的使用技巧
    min-width() ie6
    js 模拟右键菜单
    display:table-cell
    js opener 的使用
    js的 new image()
    CSS 中文字体 Unicode 编码方案
  • 原文地址:https://www.cnblogs.com/kuangke/p/9397597.html
Copyright © 2011-2022 走看看