堆前向後後向越界檢查實例,基本上可以檢測不超過一頁的堆越界非法讀寫錯誤!注意初次申請reservered內存頁時,標示它為不可讀寫,不可執行!
// 越界檢查開關
#define SOULCRYSTAL_BOUNDER_CHECK
// 前向越界檢查開關
//#define FRONT_ACROSS
// 後向越界檢查開關
#define POST_ACROSS
struct tagSoulPig {
tagSoulSpec SoulSpec;
#ifdef SOULCRYSTAL_BOUNDER_CHECK
static size_t Roundup(size_t st,int num=8)
{
return ((st + (num-1)) & ~(num-1));
}
void * operator new ( size_t size )
{
DWORD dwAcSize = 1024* 4 * 2;
PBYTE pStart = (PBYTE)VirtualAlloc(NULL,dwAcSize,MEM_RESERVE,PAGE_NOACCESS);
#ifdef POST_ACROSS
pStart = (PBYTE)VirtualAlloc(pStart,size,MEM_COMMIT,PAGE_READWRITE);
pStart = pStart + 1024* 4 - size;
#elif defined( FRONT_ACROSS )
pStart = (PBYTE)VirtualAlloc(pStart+1024* 4,size,MEM_COMMIT,PAGE_READWRITE);
#endif
return pStart;
}
void operator delete ( void * p )
{
PBYTE pAddr = (PBYTE)p;
#ifdef POST_ACROSS
pAddr -= 1024* 4 - sizeof(tagSoulCrystal);
#elif defined( FRONT_ACROSS )
pAddr -= 1024* 4;
#endif
VirtualFree(pAddr,0,MEM_RELEASE);
}
static void testbounder()
{
tagSoulPig * pTest = new tagSoulPig;
// 正常讀寫
pTest->SoulSpec.dwSoulStrength = 9;
#ifdef POST_ACROSS
// 向後越界
//int a = pTest->SoulSpec.nSoulAttID[20] ;
pTest->SoulSpec.nSoulAttID[20] = 3;
#elif defined(FRONT_ACROSS)
// 向前越界
int a = 20 - 40;
int v = pTest->SoulSpec.nSoulAttID[a] ;
pTest->SoulSpec.nSoulAttID[a] = 3;
#endif
}
#endif // SOULCRYSTAL_BOUNDER_CHECK
};