#include "stdafx.h" /* 硬件断点很有用,它的原理就不说了。 在调试的时候很容易做到:ba wX 0xXXXXXXXX. 在编程的时候如何做到呢? 当然是改变内存的属性了。 这个包括全局的变量和堆上申请的内存。 栈上的内存被非法篡改,理论上不属于这个范畴了,是另一个说法:栈溢出等。 注意:全局的变量一般所在的节的内存属性都是可写的。 可以利用异常处理/或者自己发出异常,然后捕获,获取发生时的信息。 made by correy made at 2014.03.28 email:kouleguan at hotmail dot com homepage:http://correy.webs.com 觉得有效的利用此属性的办法还是老老实实的用VirtualAlloc 申请一片内存(当某个变量等). 至少申请的内存的大小是页的倍数. 全局的变量还得另想办法.修改PE文件的格式等. */ #ifndef UNICODE #define UNICODE #endif #include <windows.h> int test[2]; void test_global_variable() /* 功能:使全局变量不可以写. 目的:以编程的手段实现一种断点. */ { DWORD OldProtect = 0; BOOL B = VirtualProtect(&test[0], sizeof(int), PAGE_READONLY, &OldProtect); if (!B) { int x = GetLastError(); } /* 这个也是不可以的. 可能是内存属性的划分是以页为单位进行的. */ test[1] = 1; /* 把上面的测试给屏蔽了. 运行到这里访问发生了异常. 可以用异常处理的办法处理捕获然后再恢复内存属性. */ test[0] = 1; } void test_heap() /* 功能:测试堆的非法访问的拦截. 结果:测试成功,满足要求. */ { char * c = (char *) HeapAlloc(GetProcessHeap(), 0, 2); if (c == NULL) { return; } * c = 9;//测试应该成功. DWORD OldProtect = 0; BOOL B = VirtualProtect(c, 1, PAGE_READONLY, &OldProtect); if (!B) { int x = GetLastError(); } /* 应该失败. 假定这里是非法修改内存,如别的指令的内存溢出越界等. 这里满足要求,弹出了异常界面. */ * c = 1; /* 把上面的测试给屏蔽了. 运行到这里访问发生了异常. 可能是内存属性的划分是以页为单位进行的. */ c++; * c = 1; } int wmain(int argc, wchar_t *argv[]) { //test_global_variable(); test_heap(); /* 相信:VirtualAlloc和GlobalAlloc/LocalAlloc/NEW的内存在理论上也应该成功. 但是栈上的局部变量建议不要这样做,也不应该这样做. */ return 0; }
2014年3月28日星期五
内存/硬断点之编程实现
订阅:
博文评论 (Atom)
没有评论:
发表评论