首页
社区
课程
招聘
[原创]调试器设计_硬件断点
发表于: 2009-9-9 18:50 11977

[原创]调试器设计_硬件断点

2009-9-9 18:50
11977

最近一直在实现一个有OD所有功能的调试器,下面给出对于实现部分的方法和遇到的问题,希望对也在实现调试器的朋友有所帮助。

设置内存断点和对输入表函数里面的函数等等,如果大家觉得需要,我在发帖写出来。

下面是硬件断点的设置问题。

主要实现代码是:
       
           CONTEXT cx;

        cx.ContextFlags = CONTEXT_DEBUG_REGISTERS;

        if(FALSE==GetThreadContext(pi->hThread, &cx))
               
                {

                err=GetLastError();       

                }                       

        cx.Dr0 = dwBreakPointAddress;//硬件断点地址
       
                cx.Dr7 |= 0x401;
       
                if(FALSE==SetThreadContext(pi->hThread, &cx))
               
               {

                err=GetLastError();       

                };

代码虽然很短,但是有很多需要注意的地方,比如,pi的权限,获取线程信息的时间。
我就只挑我出现问题的地方做出解释:

cx.ContextFlags = CONTEXT_DEBUG_REGISTERS;这句不能用CONTEXT_CONTROL。
看定义

#define CONTEXT_CONTROL         (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP  

知道为什么了吧。

这句

cx.Dr7 |= 0x401;

设置dr7不是很复杂的问题,大家看看intel的手册就明白了 ,如果只想用dr0设置一个断点,那么这里用0x1或者0x101都可以。如果要有其他复杂的控制,就仔细看看Intel  的手册吧。

下硬件断点的时间需要重点注意下:

在进入调试循环后,第一次EXCEPT_BREAKPOINT就设置硬件断点,肯定不会行的(我在网上查资料的时候,看见很多人犯了这个错误),因为他不是main真正的现场CONTEXT(It's because at the time of the DEBUG_BREAK hasn't the main thread it's real context. NT sets the real context later via the NtContinue API. So a possible method to set a BPM directly at the EntryPoint...)。所以需要在入口地址后下断点 ,然后设置硬件断点。

其他问题和一些异常处理太多我就没有给出代码和分析了。


[注意]APP应用上架合规检测服务,协助应用顺利上架!

收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
2
不错,支持一下~
2009-9-9 20:10
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
3
写调试器的一般都是牛人了,至少那些调试API比一般API函数复杂多了
2009-9-9 20:16
0
雪    币: 153
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
SetThreadContext(pi->hThread, &cx)
由这个函数可以看出,硬件断点只对某一线程有效的。如果希望对所有线程有效,显然需要在CREATE_PROCESS_DEBUG_EVENT和CREATE_THREAD_DEBUG_EVENT中,EXIT_THREAD_DEBUG_EVENT都要进行监视,保存好所有的线程Handle,再对所有线程Handle调用SetThreadContext(hThread, &cx)才行。

“在进入调试循环后,第一次EXCEPT_BREAKPOINT就设置硬件断点,肯定不会行的”
所以我认为这句话是不对的。如果监视了所有线程的创建和销毁,再对所有线程下硬件断点的话是不会出现问题的。
2009-9-9 22:27
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
第一次EXCEPT_BREAKPOINT 时发生在APC中,线程真实的CONTEXT暂时被存放在栈上,当APC结束调用NtContinue返回内核时写回去,如果此时调用SetThreadContext,断点只在APC期间有效,但是我们可以直接改写在栈上的CONTEXT,这样就能把断点预先设好了
2009-9-10 08:17
0
雪    币: 118
活跃值: (44)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
6
好主意,我空了一定试试
2009-9-10 09:37
0
雪    币: 377
活跃值: (10)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
7
调试器第一次收到int 3异常时 此时的线程还是Loader 也就是说这时候程序实际上还没有初始化完毕 只有在调用程序入口点后 程序的线程才建立 ollydbg并没有把这个断点报出来
2010-2-24 02:57
0
雪    币: 246
活跃值: (101)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
这个我不大同意,我测试过线程创建时,每创建一个就下硬件断点,还是断不了。
2010-2-24 08:23
0
雪    币: 622
活跃值: (65)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
9
正解。。。。
2010-2-24 13:08
0
雪    币: 118
活跃值: (44)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
10
谢谢大家的意见。

当时对调试的认识还不是很好。

这个是 实现代码下载地址  http://bbs.pediy.com/showthread.php?t=107005

期待你更多的意见
2010-2-24 13:34
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
劫杀过路高手
2010-10-29 19:55
0
雪    币: 146
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
都是牛人啊,学习了
2011-5-7 12:26
0
雪    币: 29
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
长见识了!!
2011-5-13 02:46
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
走过路过不要,错过
2011-5-13 08:30
0
游客
登录 | 注册 方可回帖
返回
//