侧边栏壁纸
博主头像
胜星的博客博主等级

行动起来,活在当下

  • 累计撰写 23 篇文章
  • 累计创建 38 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

调试器原理——各种断点的实现原理

胜星
2021-03-09 / 0 评论 / 0 点赞 / 354 阅读 / 2495 字

软件断点

  • 在目标进程指定写入0xCC(int 3),当目标进程执行这个位置,会触发异常,发给调试器
bool SetBreakPoint(HANDLE hProcess, LPVOID Address)
{
	BREAKPOINT bp;
	DWORD dwSize;
	DWORD oldProtect;
	// 1.修改目标分页属性
	VirtualProtectEx(hProcess, Address, 1, 	PAGE_EXECUTE_READWRITE,
&oldProtect);
	//2 .读取目标进程中的1个字节
	ReadProcessMemory(hProcess, Address, &bp.bp_olddata, 1, &dwSize);
	//3 .将0xcc 写入内存地址
	WriteProcessMemory(hProcess, Address, "\xCC", 1, &dwSize);
	//4. 恢复目标分页属性
	VirtualProtectEx(hProcess, Address, 1, oldProtect, &oldProtect);
	//5. 保存断点信息
	bp.bp_enable = TRUE;
	bp.bp_address = Address;
	// 6. 保存到断点列表
	bp_list.push_back(bp);
	return true;
}

单步断点

  • 设置ELFAGS->TF位,CPU每执行一条汇编指令都会检查TF,如果出现TF,会在下一个位置断下,同时CPU会自动将TF置为0
void SetSingleBreakPoint(HANDLE hThread)
{
	// 线程上下文
	CONTEXT context = { CONTEXT_FULL };
	// 获取线程上下文
	GetThreadContext(hThread, &context);
	((PEFLAGS)&context.EFlags)->TF = 1;
	// 设置线程上下文
	SetThreadContext(hThread, &context);
}

硬件断点

  • CPU提供了Dr0-Dr7八个调试寄存器,其中Dr0-Dr3用于设置断点位置,DR6用于检查哪一个调试寄存器触发的,DR7用于配置DR0-DR3启用,(对于读写,长度,类型),执行长度与类型都必须是0
  • 硬件断点寄存器-a4bc015518404551bf5b1718b7e55f01
Dr0~3用于设置硬件断点,即在调试器中经常使用的bpm断点,由于只有4个断点寄存器,所以最多只能设置4
个bpm断点。Dr7是一些控制位,用于控制断点的方式,Dr6用于显示是哪些引起断点的原因,如果是Dr0~3
或单步(EFLAGS的TF)或由于GD置位时访问调试寄存器引起1号调试陷阱的话,则相应设置对应的位。下面对
Dr6和Dr7的对应位做一些详细介绍:

调试控制寄存器Dr7:
	位0 L0和位1 G0:用于控制Dr0是全局断点还是局部断点,如果G0置位则是全局断点,L0置位则是局部
断点。 L0有效,G0无效,G1 L1~G3 L3用于控制D1~Dr3,其功能同上。
LEN0:占两个位,开始于位15,用于控制Dr0的断点长度,可能取值:
	00 1字节
	01 2字节
	10 保留
	11 4字节
RWE0:从第17位开始,占两个位,控制Dr0的断点是读、写还是执行断点或是I/O端口断点:
	00 只执行
	01 写入数据断点
	10 I/O端口断点(只用于pentium+,需设置CR4的DE位)
	11 读或写数据断点
RWE1~3,LEN1~3分别用于控制Dr1~3的断点方式,含义如上。

调试状态寄存器Dr6:
DR6 前两个字节,用于检查DR0-DR1的哪一个硬件断点产生的:
	00 DR0异常由于DR0产生的。
	01 DR1异常由于DR1产生的。
	10 DR2异常由于DR2产生的。
	11 DR3异常由于DR3产生的。

内存断点

  • 根据windows分页内存属性来设置内存断点。比如代码段可以设置不可执行,当指令执行到这个位置就会触发访问异常。
  • 内存读写断点,如果设置读写断点需要查看 Exception.ExceptionInformation[1] 里的内容来确定这个异常是我们产生的
// 通过这个函数来设置内存断点
VirtualProtectEx(hProcess, Address, 1, PAGE_EXECUTE_READWRITE, &oldProtect)
0

评论区