Windows内存详解(四)OD内存断点初步分析
来源:互联网 发布:mac桌面下方图标怎么加 编辑:程序博客网 时间:2024/04/28 16:26
内存断点原理:
内存断点原理,通过将内存断点所在内存页的属性修改为内存断点属性(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内存断点初步分析
- OD内存断点初步分析
- OD内存断点
- OD内存断点
- OD硬件断点,OD内存断点,API断点
- OD硬件断点,OD内存断点,API断点命令
- OD 内存断点和硬件断点 小结
- OD的 CC断点,内存访问断点,硬件断点 解析
- OD的 CC断点,内存访问断点,硬件断点 解析
- OD笔记2 内存断点与硬件断点
- 校验OD内存断点的方法和实现...
- OllyDBG 入门系列(四)-内存断点
- OllyDBG 入门系列(四)-内存断点
- OllyDBG 入门系列(四)-内存断点
- OllyDBG 入门系列(四)-内存断点
- OllyDBG 入门系列(四)-内存断点
- OllyDBG 入门系列(四)-内存断点
- OllyDBG 入门系列(四)-内存断点
- Configure,Makefile.am, Makefile.in, Makefile文件之间关系
- iOS消息推送机制的实现
- hdu 3555
- 直方图阈值法
- 依赖注入和注解,为什么 Java 比你想象的要好
- Windows内存详解(四)OD内存断点初步分析
- XSS的原理分析与解剖
- Oracle变化数据捕获CDC
- (二)NS3如何编译、运行脚本和 Command Line命令行参数设置
- HDU ACM 1532 Drainage Ditches->网络最大流模版题(EK算法实践)
- 计算字符串的不同,优化之后
- 写博客?
- 水题,蛇形填数
- POJ 2007 || Scrambled Polygon(逆时针输出凸包顶点,以原点为起始点