如何实现内存断点?

心留 2010-01-07 03:00:09
1。我目前已经知道一个内存地址address1。

2。这个地址是一个数组long lz[100]的地址。

3。我现在想实现如果有函数企图访问这个数组的数据(读取或者写入)就跳到我的函数上来。

是否可以实现?
...全文
1367 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
masou1987 2010-07-28
  • 打赏
  • 举报
回复
mark
七十二寨寨主 2010-01-16
  • 打赏
  • 举报
回复
mark了
SolidRabbit 2010-01-15
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 a87437734 的回复:]
引用 26 楼 ziplj 的回复:
我就不多废话了  自己看
http://msdn.microsoft.com/zh-cn/library/350dyxd0%28VS.80%29.aspx
数据断点这么多人都没用过???


我是想自己实现。不是用VC去设置一个。
[/Quote]
内存断点就是自己接管内存异常,为了制造异常需要按情况修改目标内存所在页面的属性
内存写断点,就把目标页面属性修改成只读
内存读断点,就是把目标页面属性修改成不能访问
发生异常后,判断引起异常的原因是不是操作了自己指定的内存,不是的话再重新设置一遍页面属性(PAGE_GUARD会被自动清除)
心留 2010-01-15
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 ziplj 的回复:]
我就不多废话了  自己看
http://msdn.microsoft.com/zh-cn/library/350dyxd0%28VS.80%29.aspx
数据断点这么多人都没用过???
[/Quote]

我是想自己实现。不是用VC去设置一个。
ziplj 2010-01-14
  • 打赏
  • 举报
回复
我就不多废话了 自己看
http://msdn.microsoft.com/zh-cn/library/350dyxd0%28VS.80%29.aspx
数据断点这么多人都没用过???
LiuYinChina 2010-01-14
  • 打赏
  • 举报
回复
WinDbg 里面有,
SolidRabbit 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 miaolingshaohua 的回复:]
楼主还没实现么?
再点拨一下:
hThread = OpenProcess();
for()
{
ReadProcessMemory(address1);//最好保存这原来的指令,方便后面使用
WriteProcessMemory(address1,0xccH);//(int 3中断)

//这样就中断下来了
WriteProcessMemory(address1,long lz[100]);//这样恢复后就从这儿执行
}
修改原来的指令为INT 3,中断下来后,再将同一地址的代码修改为JMP ADDRTO,就会恢复执行跳转到你的地址
也不好用文字表达,真麻烦
[/Quote]

你这是软断点,楼主要的是内存断点
似水流年__ 2010-01-11
  • 打赏
  • 举报
回复
去看雪,Od内存断点
哈利路亚1874 2010-01-10
  • 打赏
  • 举报
回复
楼主还没实现么?
再点拨一下:
hThread = OpenProcess();
for()
{
ReadProcessMemory(address1);//最好保存这原来的指令,方便后面使用
WriteProcessMemory(address1,0xccH);//(int 3中断)

//这样就中断下来了
WriteProcessMemory(address1,long lz[100]);//这样恢复后就从这儿执行
}
修改原来的指令为INT 3,中断下来后,再将同一地址的代码修改为JMP ADDRTO,就会恢复执行跳转到你的地址
也不好用文字表达,真麻烦
fly4free 2010-01-09
  • 打赏
  • 举报
回复
说什么本帖也要收藏一下。
wwwhhb4004 2010-01-09
  • 打赏
  • 举报
回复

mark
zoulie 2010-01-08
  • 打赏
  • 举报
回复
就是插 int 3指令
详细见张银奎 的 软件调试
xwsn007 2010-01-08
  • 打赏
  • 举报
回复
哈哈,学习了
sunlin7 2010-01-08
  • 打赏
  • 举报
回复
使用调试API。
SolidRabbit 2010-01-07
  • 打赏
  • 举报
回复
如果楼主是要自己写工具的话,写轮兔说的方法能更好的满足你的要求
关键字:SEH

硬件断点有数据长度的限制
cnzdgs 2010-01-07
  • 打赏
  • 举报
回复
处理器中有一组用于调试的寄存器(DR0~DR7),通过设置寄存器的值可以实现当某个地址的内存被访问时自动产生中断,不过需要在Ring0级才能访问这些寄存器,通常用驱动程序来处理。你可以在网上搜索一下“调试寄存器”。
MoXiaoRab 2010-01-07
  • 打赏
  • 举报
回复
原理其实很简单,自己注册个


struct EXCEPTION_REGISTRATION
{
  EXCEPTION_REGISTRATION* prev;
  DWORD handler;
};



然后放到FS[0]上。mov FS:[0], myExceptionReg


struct EXCEPTION_REGISTRATION
{
  EXCEPTION_REGISTRATION* prev;
  DWORD handler;
};
EXCEPTION_DISPOSITION myHandler(
  _EXCEPTION_RECORD *ExcRecord,
  void * EstablisherFrame,
  _CONTEXT *ContextRecord,
  void * DispatcherContext)
{
  cout << "Just a TEST. exiting..." << endl;
  exit(0);
  return ExceptionContinueExecution; //不会运行到这
}




//initialize EXCEPTION_REGISTRATION structure
EXCEPTION_REGISTRATION reg, *preg = ®
reg.handler = (DWORD)myHandler;

//get the current head of the exception handling chain
DWORD prev;
_asm
{
mov EAX, FS:[0]
mov prev, EAX
}
reg.prev = (EXCEPTION_REGISTRATION*) prev;

//register it!
_asm
{
mov EAX, preg
mov FS:[0], EAX
}

//generate the exception
MoXiaoRab 2010-01-07
  • 打赏
  • 举报
回复
VC有个自己接管异常的,你可以接管那个内存访问异常,转向你自己的异常处理程序

把VC++的处理程序替换掉。从__CxxFrameHandler函数是VC++所有异常处理工作的入口。编译器为每个函数都生成一段代码,它们在发生异常时被调用,把相应的funcinfo结构的指针交给__CxxFrameHandler。

install_my_handler()函数会改写__CxxFrameHandler的入口处的代码,让程序跳转到my_exc_handler()函数。__CxxFrameHandler位于只读的内存页,对它的任何写操作都会导致访问违例,首先用VirtualProtectEx把该内存页的保护方式改成可读写,等改写完毕后,再改回只读。写入的数据是一个jmp_instr结构。

//install_my_handler.cpp
#include <windows.h>
#include "install_my_handler.h"
//C++默认的异常处理程序
extern "C"
EXCEPTION_DISPOSITION __CxxFrameHandler(
  struct _EXCEPTION_RECORD* ExceptionRecord,
  void* EstablisherFrame,
  struct _CONTEXT* ContextRecord,
  void* DispatcherContext
  );
namespace
{
  char cpp_handler_instructions[5];
  bool saved_handler_instructions = false;
}
namespace my_handler
{
  //我的异常处理程序 EXCEPTION_DISPOSITION
  my_exc_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext
  ) throw();
#pragma pack(push, 1)
  struct jmp_instr
  {
    unsigned char jmp;
    DWORD offset;
  };
#pragma pack(pop)
  bool WriteMemory(void* loc, void* buffer, int size)
  {
    HANDLE hProcess = GetCurrentProcess();
    //把包含内存范围[loc,loc+size]的页面的保护方式改成可读写
    DWORD old_protection;
    BOOL ret = VirtualProtectEx(hProcess, loc, size, PAGE_READWRITE, &old_protection);
    if(ret == FALSE)
      return false;
    ret = WriteProcessMemory(hProcess, loc, buffer, size, NULL);
    //恢复原来的保护方式
    DWORD o2;
    VirtualProtectEx(hProcess, loc, size, old_protection, &o2);
    return (ret == TRUE);
  }
  bool ReadMemory(void* loc, void* buffer, DWORD size)
  {
    HANDLE hProcess = GetCurrentProcess();
    DWORD bytes_read = 0;
    BOOL ret = ReadProcessMemory(hProcess, loc, buffer, size, &bytes_read);
    return (ret == TRUE && bytes_read == size);
  }
  bool install_my_handler()
  {
    void* my_hdlr = my_exc_handler; void* cpp_hdlr = __CxxFrameHandler;
    jmp_instr jmp_my_hdlr;
    jmp_my_hdlr.jmp = 0xE9;
    //从__CxxFrameHandler+5开始计算偏移,因为jmp指令长5字节
    jmp_my_hdlr.offset = reinterpret_cast(my_hdlr) - (reinterpret_cast(cpp_hdlr) + 5);
    if(!saved_handler_instructions)
    {
      if(!ReadMemory(cpp_hdlr, cpp_handler_instructions, sizeof(cpp_handler_instructions)))
        return false;
      saved_handler_instructions = true;
    }
    return WriteMemory(cpp_hdlr, &jmp_my_hdlr, sizeof(jmp_my_hdlr));
  }
  bool restore_cpp_handler()
  {
    if(!saved_handler_instructions)
      return false;
    else
    {
      void* loc = __CxxFrameHandler;
      return WriteMemory(loc, cpp_handler_instructions, sizeof(cpp_handler_instructions));
    }
  }
}
MoXiaoRab 2010-01-07
  • 打赏
  • 举报
回复
VirtualProtect 保护这段内存 PAGE_NOACCESS 不被访问

想实现跳转?劝你别这么搞。不值得付出这么大的代价
SolidRabbit 2010-01-07
  • 打赏
  • 举报
回复
VS2008中有这个功能

程序在PAUSE状态下:Debug->New BreakPoint->New Data BreakPoint

另外,int 3是软断点,是只能令程序运行中断,只能断代码。想断数据操作要用硬件断点。
加载更多回复(10)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧