#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)
没有评论:
发表评论