原理回顾:硬件断点就是通过对cpu的寄存器进行设置,把断点的地址存在dr0~dr3里,然后在dr7设置属性。在跑到该地址时,进行中断处理。同样处理完后要把寄存器里这些改动再改回去。
在实现上,需要添加2个函数:bp_set_hw用来添加硬件断点和exception_handler_single_step用来处理中断事件。
添加硬件断点的步骤:
1. CreateToolhelp32Snapshot获取线程HANDLE
2. 对每个线程,用GetThreadContext获取寄存器的值
3. 根据已有硬件断点状态,将地址放到dr0~dr3中的空闲available的一个
4. 对dr7进行设置
5. 用SetThreadContext将新值写进寄存器里
这里贴一张dr7的图:
第一个要设置的是告诉我们哪个寄存器被用了。
其中,0~7位对应的是dr0到dr3,L位表示对当前任务有效,为局部设置,而G位为全局设置。只用设置一个就可以了。
通过设置
context.Dr7 |= 1 << (available * 2)
可以让available寄存器对应的位置1.如available值为0,表示地址写入dr0,那么dr7的值就是1<<0 = 1
第二个要设置的是对应的condition。condition包含3种:HW_ACCESS(读写断点11), HW_EXECUTE(执行断点00), HW_WRITE(数据写入断点01)。还有一个10号是未定义的。
context.Dr7 |= condition << ((available * 4) + 16)
这里我们用的是执行断点,所以condition =0,available = 0,所以结果还是0
最后是设置长度,
context.Dr7 |= length << ((available * 4) + 18)
对执行断点来说,length=1,available = 1,所以第18位被置1
实验结果:
Enter pid:8380
OpenProcess Successful, HANDLE 508
Get Module Handle 1989869568
Get Address: 0x76a27960
[*]Address of wprintf: 0x76a27960
0 original 0b0
0 original 00000000
1 flag 0b1
1 flag 00000001
2 condition 0b1
2 condition 00000001
3 length 0b1
3 length 00000001
0 original 0b0
0 original 00000000
1 flag 0b1
1 flag 00000001
2 condition 0b1
2 condition 00000001
3 length 0b1
3 length 00000001
0 original 0b0
0 original 00000000
1 flag 0b1
1 flag 00000001
2 condition 0b1
2 condition 00000001
3 length 0b1
3 length 00000001
0 original 0b0
0 original 00000000
1 flag 0b1
1 flag 00000001
2 condition 0b1
2 condition 00000001
3 length 0b1
3 length 00000001
0 original 0b0
0 original 00000000
1 flag 0b1
1 flag 00000001
2 condition 0b1
2 condition 00000001
3 length 0b1
3 length 00000001
Event Code: 3 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 2 Thread ID: 5420
Event Code: 2 Thread ID: 636
Event Code: 2 Thread ID: 9580
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 6 Thread ID: 11692
Event Code: 2 Thread ID: 12760
Event Code: 1 Thread ID: 12760
[*] Exception address: 0x77318d20
[*] Hit the first breakpoint.
Event Code: 4 Thread ID: 12760
Event Code: 1 Thread ID: 11692
Single Step.
[*] Exception address: 0x76a27960
[*] Hardware breakpoint removed.
Event Code: 2 Thread ID: 5204
Event Code: 2 Thread ID: 10640
Event Code: 2 Thread ID: 10316
Event Code: 4 Thread ID: 9580
Event Code: 4 Thread ID: 5420
Event Code: 4 Thread ID: 636
说几点问题:
1. 根据print的结果,dr7位的第3步设置长度貌似没有被设置成功?依然是0
2. 在cmd里没法按ctrl+z来终止这个死循环程序了,奇怪。。每次按了之后事件码就增加为214