内存断点原理:

内存断点原理,通过将内存断点所在内存页的属性修改为内存断点属性(non-access or non-writable),程序执行时,对目标内存页中所有数据的访问或写,都会抛出异常,OD通过截获此异常,然后对比,存储在某一内存的内存断点信息表的地址,判断是否匹配内存断点地址范围,匹配则中断程序执行,否则,继续执行。

IDA静态分析:

本例利用IDA和OD动静结合,分析OD内存断点基本流程,以及内存断点存储在哪儿段内存地址。

首先将OD丢进IDA中,在程序函数列表中搜索breakpoint字符串,如图:

我们仅分析内存断点,通过function name 可知:_setmembreakpoint是我们需要分析的函数。跳到该函数分析,入口点部分截图:

可知,该函数有3个参数,通过F5(hexray),其反编译伪代码:

     signed int __cdecl Setmembreakpoint(__int16 a1, unsigned int a2, int a3)  {  _DWORD *v3; // eax@3  signed int result; // eax@5  if ( !dword_4D8138 && VersionInformation.dwPlatformId != 2 )  {  v3 = Findmemory(a2);  if ( a2 < 0x80000000 )     //判断内存断点地址是否在用户内存中(0x800000~0xffffffff属于系统内核内存区域)  {  if ( v3 && *((_BYTE *)v3 + 11) & 1 )   //判断内存断点是否在资源内存区域  {  if ( MessageBoxA(  hWnd,  "You are going to set memory breakpoint on resource. This breakpoint, when hit within system DLL, may freeze Windows or cause system crash. Do you really want to set this breakpoint?",  "Memory breakpoint on resource",  0x14u) != 6 )  return -1;  }  else  {  if ( v3 && *((_BYTE *)v3 + 11) & 4 )    //判断内存断点地址是否在堆栈内存区域  {  MessageBoxA(  hWnd,  "You are going to set memory breakpoint on stack. This doesn't work on Win95-based operating systems.",  "Memory breakpoint on stack",  0x10u);  return -1;  }  }  }  else  {  if ( MessageBoxA(  hWnd,  "You are going to set memory breakpoint in system area. This breakpoint may freeze Windows or cause system crash. Do you really want to set this breakpoint?",  "Memory breakpoint in system area",  0x14u) != 6 )  return -1;  }  }  if ( sub_418E24() )  {  result = -1;  }  else  {  dword_4D813C = a2;  dword_4D8140 = a3;  dword_4D8144 = a2 & 0xFFFFF000;  dword_4D8148 = (a3 + a2 + 4095) & 0xFFFFF000;  dword_4D8138 = (HIBYTE(a1) & 0x10) != 0;  dword_4D8D5C = 1;  if ( a1 & 3 && a3 )  {  if ( (a1 & 3) == 2 )  dword_4D814C = 32;  else  dword_4D814C = 1;  if ( dword_4D5A5C == 3 )  sub_419034();  result = 0;  }  else  {  result = 0;  }  }  return result;  }  

OD调试OD动态分析:

我们通过OD来调试OD,分析setmembreakpoint函数的流程。

将OD丢进OD中,并在setmembreakpoint入口地址下断点(F2),并运行被调试的OD。然后在被调试的OD程序中加载调试一个任意程序,并在某一地址下内存访问断点,如图(被调试的od程序中,在红线0x401377处下了内存断点):


下完该内存断点,调试程序OD立即捕获,并中断在setmembreakpoint的入口地址,然后我们通过单步,查看该函数的三个参数分别是神马:

发现esi中的值即我们在被调试程序中所下的内存断点地址,edi为内存断点的字节长度(0x401377处指令为6bytes)。ebx值其实是内存断点的属性(访问:0x00000003,写:0x00000002),这里我们之前下的是内存访问断点,所以ebx:0x00000003。

继续单步执行,在0x4192fb处跳转到0x41938d。先不管这里为什么会调转。继续单步,发现之后的汇编操作将我们所下的内存断点信息存储到了某段内存中,如图:

当前eax=0x401377,即我们的内存断点地址。

分析汇编:

     004193A2  |.  A3 3C814D00   mov     dword ptr [4D813C], eax   //将内存断点地址存储到0x4d813c处         004193A7  |.  8BC8          mov     ecx, eax      //ecx=eax=0x401377 内存断点地址  004193A9  |.  03C2          add     eax, edx      //edx为内存断点字节长度,这里是取内存断点结束地址,本例中,eax=0x401377+6=0x40137d  004193AB  |.  81E1 00F0FFFF and     ecx, FFFFF000   //相当于去该内存地址所在的内存页起始地址   ecx=0x401000  004193B1  |.  05 FF0F0000   add     eax, 0FFF      //将内存断点结束地址加上了一个内存页大小  004193B6  |.  8915 40814D00 mov     dword ptr [4D8140], edx  //将内存断点长度存储到0x4d8140  004193BC  |.  25 00F0FFFF   and     eax, FFFFF000   //取该内存地址所在的内存页地址  004193C1  |.  890D 44814D00 mov     dword ptr [4D8144], ecx   //将内存断点坐在内存也的起始地址存储到0x4d8144处  004193C7  |.  F6C7 10       test    bh, 10    //设置zf属性,执行后,zf=1  004193CA  |.  A3 48814D00   mov     dword ptr [4D8148], eax   //本例中eax=402000  004193CF  |.  0F95C0        setne   al      //if zf=1 then al=0, if zf=0 then al=1  004193D2  |.  83E0 01       and     eax, 1        //之后 eax=0x00000000  004193D5  |.  83E3 03       and     ebx, 3        //ebx之前存储的是内存断点属性(访问or 写)  004193D8  |.  A3 38814D00   mov     dword ptr [4D8138], eax    //存储这个不知道有何用途  004193DD  |.  C705 5C8D4D00>mov     dword ptr [4D8D5C], 1    004193E7  |.  85DB          test    ebx, ebx  004193E9  |.  74 04         je      short 004193EF  004193EB  |.  85FF          test    edi, edi       //edi存的是内存断点字节长度  004193ED  |.  75 04         jnz     short 004193F3   //跳转成功  004193EF  |>  33C0          xor     eax, eax  004193F1  |.  EB 2B         jmp     short 0041941E  004193F3  |>  83FB 02       cmp     ebx, 2           //ebx与2 比较,判断是否是内存写属性  004193F6  |.  75 0C         jnz     short 00419404     //不是则跳转到0x419404(访问属性)  004193F8  |.  C705 4C814D00>mov     dword ptr [4D814C], 20   //内存写属性,则将0x20存储在0x4d814c  00419402  |.  EB 0A         jmp     short 0041940E  00419404  |>  C705 4C814D00>mov     dword ptr [4D814C], 1    //内存访问属性,将0x01存储在0x4d814c  0041940E  |>  833D 5C5A4D00>cmp     dword ptr [4D5A5C], 3  00419415  |.  75 05         jnz     short 0041941C  00419417  |.  E8 18FCFFFF   call    00419034  0041941C  |>  33C0          xor     eax, eax  0041941E  |>  5F            pop     edi  0041941F  |.  5E            pop     esi  00419420  |.  5B            pop     ebx  00419421  |.  5D            pop     ebp  00419422  \.  C3            retn  

通过对上面的汇编代码的分析,我们基本上可以定位内存断点信息的存储地址:0x4d8138~0x4d814f ,本例如图:

0x4d8138~0x40813b:0x00000000 未知

0x4d813c~0x4d813f: 0x00401377 内存断点起始地址

0x4d8140~0x4d8143: 0x00000006 内存断点长度

0x4d8144~0x4d8147: 0x00401000 内存断点地址所在的内存页起始地址

0x4d8148~0x4d814b: 0x00402000 内存断点尾部地址+内存也大小地址后,所在的内存页起始地址(这里有所疑问,为什么要加上0xfff,而不是直接取内存断点尾部地址所在的内存页起始地址,本例中,应该也是0x401000)。

0x4d814c~0x4d814f:0x00000001 内存断点属性(访问:0x00000001,写:0x00000020,与ebx区分开)

对该段内存的赋值其实在初始化一个结构体,该结构体存储内存断点相关信息:

Typedef struct membrakpointinfo

{

Dword unrecognized;//0x4d8138~0x40813b 未知

Dwordmemaddr;   //0x4d813c~0x4d813f 内存断点起始地址

Dword size;        //0x4d8140~0x4d8143:0x00000006 内存断点长度

Dword base1;      //0x4d8144~0x4d8147内存断点地址所在的内存页起始地址

Dword base2;     //0x4d8148~0x4d814b:0x00402000 内存断点尾部地址+内存也大小地址后,所在的内存页起始地址

Dword memtype;  //0x4d814c~0x4d814f 内存断点属性

}

Windows内存详解(四)OD内存断点初步分析相关推荐

  1. Linux进程间通信详解(四) —— 共享内存及函数

    共享内存的概念 共享内存是指多个进程可以把一段内存共同的内存映射到自己的进程空间中,从而实现数据的共享和传输,它是存在与内核级别的一种资源,是所有进程间通信中方式最快的一种. 在shell环境下可以使 ...

  2. linux系统分配文件夹内存,详解Linux系统内存知识及调优方案

    内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁.计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大.内存作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器 ...

  3. Java源码详解四:String源码分析--openjdk java 11源码

    文章目录 注释 类的继承 数据的存储 构造函数 charAt函数 equals函数 hashCode函数 indexOf函数 intern函数 本系列是Java详解,专栏地址:Java源码分析 Str ...

  4. 内存详解-理解 JVM 如何使用 Windows 和 Linux 上的本机内存

    内存详解 理解 JVM 如何使用 Windows 和 Linux 上的本机内存 Java™ 堆耗尽并不是造成 java.lang.OutOfMemoryError 的惟一原因.如果本机内存 耗尽,则会 ...

  5. php 内存池,内存详解: 详解PHP内存池中的存储层_php

    php的内存管理器是分层(hierarchical)的.这个管理器共有三层:存储层(storage).堆(heap)层和 emalloc/efree 层.存储层通过 malloc().mmap() 等 ...

  6. linux 内存 参数,linux free命令参数及用法详解(linux查看内存命令)

    linux free命令参数及用法详解(linux查看内存命令) 2019年05月31日 | 萬仟网科技 | 我要评论 free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段 ...

  7. NAND FLASH 内存详解与读写寻址方式

    目录: 第一章 绪论 1.1 课题来源 1.2 研究背景与意义     1.2.1 Flash介绍     1.2.2 NAND Flash介绍     1.2.3 NAND Flash与NOR Fl ...

  8. NAND_FLASH_内存详解与读写寻址方式

    一.内存详解 NAND闪存阵列分为一系列128kB的区块(block),这些区块是 NAND器件中最小的可擦除实体.擦除一个区块就是把所有的位(bit)设置为"1"(而所有字节(b ...

  9. 内存详解mdash;mdash;理解 JVM 如何使用 AIX 上的本机内存

    理解 JVM 如何使用 AIX 上的本机内存 Java™ 堆耗尽并不是造成 java.lang.OutOfMemoryError 的惟一原因.如果本机内存 耗尽,则会发生普通调试技巧无法解决的 Out ...

  10. DDR3内存详解,存储器结构+时序+初始化过程

    转载 DDR3内存详解,存储器结构+时序+初始化过程 2017-06-17 16:10:33 a_chinese_man 阅读数 23423更多 分类专栏: 硬件开发基础 转自:http://www. ...

最新文章

  1. shell脚本的规范
  2. idea 自定义工具栏
  3. javascript的基础(1)
  4. html开发文档工具栏,添加应用栏和工具栏 (HTML)
  5. 【Python】Matplotlib绘制三维线形图
  6. Spring Boot文档阅读笔记-构建SOAP的web Service服务
  7. 百度十亿级流量的搜索前端,是怎么做架构升级的?
  8. MFC小笔记:系统托盘实现
  9. jquery操作表格
  10. Android studio 不能识别(显示?????)部分手机的解决办法
  11. 华为全系Visio图标下载链接
  12. VScode中文注释乱码问题解决
  13. SpringMVC文件上传下载实战(单文件、多文件)
  14. cpu,内存占用率过高解决方法
  15. 3U VPX XC7VX690T计算处理板
  16. NSX-T 恢复DFW策略
  17. 流程图用什么软件做?这篇文章告诉你(内附详细教程)
  18. 解决微信公众号发布新的版本H5页面有缓存的问题
  19. CF221C Circling Round Treasures
  20. 好工具推荐系列:Windows系统查看各个进程/网速/CPU的软件(查看系统资源工具)

热门文章

  1. 消除小黑点html,word黑点怎么去掉,Word文档项目编号前有个小黑点
  2. XSS Challenges xss-quiz.int21h.jp
  3. 用make qemu启动xv6出现“error: writing 1 byte into a region of size 0”
  4. Unity3d bounds包围盒 和collider碰撞器区别
  5. 网页打开慢,响应时间慢,如何定位这个问题?
  6. c语言罗马数字转十进制,罗马数字转十进制的三种方法
  7. 【医疗人工智能论文】使用深度强化学习的腹腔镜机器人辅助训练
  8. 生产时间戳错误的分析过程及解决办法
  9. Julia数据可视化:Gadfly.jl包的使用
  10. 深入理解Linux内核页表映射分页机制原理