简单调试器的实现(四)断点

Int3断点原理:

在一个指令处设置断点有2步,1.将指令的第1个字节保存起来,2.将这个字节替换成 0xCC

我们可以用我写的调试器看一下:

u指令显示了在地址 14e1bbb处的指令   E8 3EAC000;   Call  14ec7fe  。

然后查看这个地址存放的内容。

接着,在14e1bbb设置一个断点, bp 14e1bbb 。

再次查看14e1bbb的内容,明显发现  前1个字节设置成了0xCC。

断点实现流程:

以下是设置INT3 断点的实现代码。

DWORD SetBreakPoint(DWORD Address)    //传入需要设置的地址
{
  BYTE lpBYTE;
  BYTE Check = 0xCC;
  SIZE_T bytesRead;

  //1.获得该地址的前1字节
  if (ReadProcessMemory(G_Process, (LPCVOID)Address, &lpBYTE, sizeof(BYTE), &bytesRead) == 0)
  {
    printf("\nError in the SetBreakPoint ->ReadProcessMemory, LastError:%d", GetLastError());
    return 2;
  }

  //2.判断这一点是否已经存在 int3 断点
  if (memcmp(&lpBYTE, &Check, sizeof(BYTE)) == 0)
  {
    printf("This Address Had set BreakPoint\n");
    return 1;
  }

  //3.操作链表加入这个节点,记录断点地址与原来的内容
  if (FALSE == Record_Breakpoint_List(Address, lpBYTE))
  {
    return 5;
  }

  //修改地址BYTE —> INT 3
  if( 0 == WriteProcessMemory(G_Process, (LPCVOID)Address, &Check, sizeof(BYTE), &bytesRead))
  {
    printf("\nError in the SetBreakPoint->WriteProcessMemory, LastError:%d", GetLastError());

    return 3;
  }

  return 0;
}

接着是删除断点的实现代码

DWORD DeleteBreakPoint(DWORD Address)
{
  BYTE lpBYTE;
  BYTE Check = 0xCC;
  SIZE_T bytesRead;

  //获得该地址的字节
  if (ReadProcessMemory(G_Process, (LPCVOID)Address, &lpBYTE, sizeof(BYTE), &bytesRead) == 0)
  {
    printf("\nError in the SetBreakPoint->ReadProcessMemory, LastError:%d", GetLastError());
    return 2;
  }
 
  //先判断这一点是否存在 int3
  if (memcmp(&lpBYTE, &Check, sizeof(BYTE)) != 0)
  {
    printf("This Address don‘t has BreakPoint\n");
    return 1;
  }

    //操作链表删除这个节点 ,并且实现修改地址 INT 3 -> BYTE
  if (FALSE == Delete_Breakpoint_List(Address))
  {
    return 3;
  }

  return 0;
}

 

时间: 2024-10-12 07:52:35

简单调试器的实现(四)断点的相关文章

windows简单调试器源码2700行左右代码

简单调试器项目中on开头的函数为接收系统的调试事件并做相应的处理,简单调试器实现过程中主要的调试事件为异常事件,相应的处理函数为DispatchException. 在异常事件中访问异常.int3异常.单步异常是跟实现调试器功能密切相关的异常事件,这里用三个函数分别处理三个函数分别为OnExceptionAccess.OnExceptionBreakPoint.OnExceptionSingleStep. 异常处理函数中如果为调试器自己设置的异常程序就会停下来接收用户输入等待下一步处理,相应的用

简单调试器的实现(二)使用反汇编引擎&建立第一个程序

让程序停下来: 动态调试器的一个重要特点就是:让程序停下来,这样我们才可以观测到程序的即时情况. 不过现在我们并不需要研究怎么下断点,系统已经帮我们激活了第一个断点.在创建调试进程时,系统会帮我们在ntdll.dll中设置一个INT3断点,我们就让程序在这里断下来. switch (DebugEvent->u.Exception.ExceptionRecord.ExceptionCode)//Int3断点的事件 { case EXCEPTION_BREAKPOINT: // ((DWORD )0

简单调试器的实现(一)调试循环与反汇编引擎

最近对调试器的原理感兴趣,自己写了一个简单的demo 打开调试进程: 要调试一个进程,需要在使用CreateProcess打开一个文件时,将第6个参数设为DEBUG_PROCESS. BOOL WINAPI CreateProcess( _In_opt_     LPCTSTR lpApplicationName, _Inout_opt_  LPTSTR lpCommandLine, _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,

简单调试器的实现(三)

单步的实现 就是之前设置的TF标志位 //设置TF标志位 void SetTrapFlag() { CONTEXT context = {0}; GetDebuggeeContext(&context); context.EFlags |= 0x100; SetDebuggeeContext(&context); } 步出则是在ebp+4的地址设置断点 BOOL MoveOut() { // 获取ebp CONTEXT Context = {0}; GetDebuggeeContext(&

MyDebugeer 一个简单调试器的实现

学习的是网上的帖子,所以就不贴源码了. 整个程序以调试循环为主体,实现了启动调试,继续执行,内存查看,读取寄存器值,显示源代码,断点的设置.查看.删除,三种单步执行:StepIn.StepOver.StepOut,显示变量列表.显示指定类型内存内容,显示函数调用栈等功能. 原贴写的很好,从中学到了很多,特别是对<DbgHelp.h>有了接触和了解,学习了Windows提供给用户调试的API,当然这可能是这个程序的不足,因为基本上所有的功能都是利用API实现的,没有提及一些特别的知识和方法.不过

VC调试器高级应用----高级断点篇ykcj

2017 已经悄悄的走了,2018 也已经匆匆的来了,我们在总结过去的同时,也要展望一下未来.俗话说一年之计在于春,虽说距立春还有一个多月,我觉得我们如果想从小白升级到大牛,应该早做计划,规划一下今年要学哪些新的技能呢?我们来一一探讨一下. SpringBoot Spring Boot:是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring B

简单调试器的实现(三)完善调试器

Dll加载: case LOAD_DLL_DEBUG_EVENT: // Read the debugging information included in the newly // loaded DLL. Be sure to close the handle to the loaded DLL // with CloseHandle. //Dll加载时会进行这个事件 dwContinueStatus = OnLoadDllDebugEvent(DebugEvent); break; DWO

[Win32]一个调试器的实现(八)单步执行

[Win32]一个调试器的实现(八)单步执行 作者:Zplutor 出处:http://www.cnblogs.com/zplutor/ 本文版权归作者和博客园共有,欢迎转载.但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 上回讲解了如何实现断点功能,这回讲解如何实现与断点紧密相关的单步执行功能.单步执行有三种类型:StepIn,StepOver和StepOut,它们的实现方式比较多样化,单独实现它们的话并不困难,但是将它们整合到一起就比较困难了,

手把手教你写Windows 64位平台调试器

本文网页排版有些差,已上传了doc,可以下载阅读.本文中的所有代码已打包,下载地址在此. -------------------------------------------------------------------------------------------------------------------------------------------------------------- 手写一个调试器有助于我们理解hook.进程注入等底层黑客技术具体实现,在编写过程中需要涉及大