📄 memchk.cpp
字号:
/* Now reserve region */
pbyBuf=(PBYTE)VirtualAlloc(NULL, ulResSize, MEM_RESERVE, PAGE_READWRITE);
if (pbyBuf == NULL)
{
DPFERROR((L"GuardPageAlloc : Failed to reserve linear range for alloc"));
DebugBreak();
return NULL;
}
/* Now commit the pages we need to */
if (VirtualAlloc((PVOID)(pbyBuf + (gsHeaps.sGuradPageConfig.ulFrontGuradPages * 4096)), ulCommitSize, MEM_COMMIT, PAGE_READWRITE) == NULL)
{
DPFERROR((L"GuardPageAlloc : Failed to commit linear range for alloc"));
DebugBreak();
VirtualFree(pbyBuf, ulResSize, MEM_RELEASE);
return NULL;
}
/* Now find spare alloc entry */
psAlloc = FindAlloc(psHeap, 0);
if (psAlloc == NULL)
{
PALLOC_LIST psNewList;
/* Ok no spare in all the tables so alloc another table and add to list */
psNewList = (PALLOC_LIST)malloc(sizeof(ALLOC_LIST));
if (psNewList == NULL)
{
DPFERROR((L"GuardPageAlloc : Failed to alloc new AllocList"));
DebugBreak();
}
/* Zero all entries */
memset(psNewList, 0, sizeof(ALLOC_LIST));
/* Add to start of list */
psNewList->psNext=psHeap->psAllocList;
psHeap->psAllocList=psNewList;
/* Use first in list */
psAlloc=&psNewList->asAllocs[0];
}
/* Now set buffer up, first move past the front guard pages */
pbyPos = pbyBuf + (gsHeaps.sGuradPageConfig.ulFrontGuradPages * 4096);
/* Now setup buffer */
if (gsHeaps.sGuradPageConfig.bFindUnderRuns == FALSE)
{
ULONG ulFrontBufSize;
/* Looking for over-runs so buffer is placed at end of pages, store ptr at start */
*((PALLOC_INFO*)pbyPos)=psAlloc;
pbyPos+=sizeof(psAlloc);
/* Setup front buffer size */
ulFrontBufSize = ulCommitSize-(sizeof(psAlloc) + ulBytes);
memset((PVOID)pbyPos, FRONT_RGN_VAL, ulFrontBufSize);
pbyPos += ulFrontBufSize;
/* Now we are at the user buffer */
psAlloc->pvUserBuf=(PVOID)pbyPos;
/* Now set alloc buf */
if ((ulFlags & HEAP_ZERO_MEMORY) == 0)
{
memset((PVOID)pbyPos, ALLOC_MEM_VAL, ulBytes);
}
else
{
memset((PVOID)pbyPos, 0, ulBytes);
}
}
else
{
ULONG ulBackBufSize;
/* Looking for under-runs so buffer is placed at begining of pages */
psAlloc->pvUserBuf=(PVOID)pbyPos;
/* Now set alloc buf */
if ((ulFlags & HEAP_ZERO_MEMORY) == 0)
{
memset((PVOID)pbyPos, ALLOC_MEM_VAL, ulBytes);
}
else
{
memset((PVOID)pbyPos, 0, ulBytes);
}
pbyPos += ulBytes;
/* Setup back buffer size */
ulBackBufSize = ulCommitSize-(sizeof(psAlloc) + ulBytes);
memset((PVOID)pbyPos, BACK_RGN_VAL, ulBackBufSize);
pbyPos += ulBackBufSize;
/* Now store ptr at end of pages */
*((PALLOC_INFO*)pbyPos)=psAlloc;
}
/* Now store some info */
psAlloc->ulCallersEIP= ulCallerAddr;
psAlloc->ulSize = ulBytes;
psAlloc->pvBufStart = (PVOID)pbyBuf;
psAlloc->ulRgnSize = ulResSize;
/* Now update stats */
psHeap->sStats.ulAllocCount++;
psHeap->sStats.ulCurrentAllocs++;
psHeap->sStats.ulCurrentAllocSize += ulBytes;
gsHeaps.sGlbStats.ulAllocCount++;
gsHeaps.sGlbStats.ulCurrentAllocs++;
gsHeaps.sGlbStats.ulCurrentAllocSize += ulBytes;
/* Should we check all the heaps */
if (gsHeaps.ulCheckLevel >= MEMCHK_LEV_ALL_GUARD)
{
MemChkCheckAllHeaps(FALSE);
}
return (psAlloc->pvUserBuf);
}
/**************************************************************************
* Function Name : GuardPageFree
* Inputs : HANDLE hHeap, ULONG ulFlags, PVOID pvMem
* Outputs :
* Returns :
* Description :
**************************************************************************/
BOOL GuardPageFree(HANDLE hHeap, ULONG ulFlags, PVOID pvMem)
{
PHEAP_INFO psHeap=(PHEAP_INFO)hHeap;
PALLOC_INFO psAlloc;
PALLOC_INFO psFound;
PBYTE pbyCommitStart;
ULONG ulCommitSize;
/* Find alloc struct */
if (gsHeaps.sGuradPageConfig.bFindUnderRuns == FALSE)
{
PALLOC_INFO *ppsAlloc;
/* Ok alloc struct pointer is stored at front of commited buffer */
ppsAlloc=((PALLOC_INFO *)(((ULONG)pvMem) & ~0xfff)); //Not 64bit safe
/*
If buffer was a multiple of a page in size then ptr would be stored at
begining of previous page
*/
if (pvMem == (PVOID)ppsAlloc)
{
psAlloc=*((PALLOC_INFO *)((PBYTE)ppsAlloc - 4096));
}
else
{
psAlloc=*ppsAlloc;
}
}
else
{
PBYTE pbyRgnStart;
/*
Ok alloc struct is stored at end of commited pages, we do not know the
size of the alloc so we must look up the alloc struct
*/
pbyRgnStart=(PBYTE)(((ULONG)pvMem) & ~0xfff) - (4096 * gsHeaps.sGuradPageConfig.ulFrontGuradPages); //Not 64bit safe
psAlloc=FindAlloc(psHeap, (PVOID)pbyRgnStart);
}
/* Check this buffer is in our list */
psFound=FindAlloc(psHeap, psAlloc->pvBufStart);
if (psFound != psAlloc || psAlloc == NULL)
{
if (psFound == NULL)
{
DPFERROR((L"GuardBufFree : Caller free'ing buffer that is not currently allocated"));
}
else
{
DPFERROR((L"GuardBufFree : Buffer found in different alloc slot than store ptr shows"));
}
DebugBreak();
}
/* First check that buffers have not been corrupted */
GuardPageIsAllocCorrupt(psAlloc);
/* Now set alloced memory to dealloced value */
memset(pvMem, FREE_MEM_VAL, psAlloc->ulSize);
/* Decommit the commited pages */
pbyCommitStart = ((PBYTE)psAlloc->pvBufStart) + (gsHeaps.sGuradPageConfig.ulFrontGuradPages * 4096);
ulCommitSize = ulCommitSize=((psAlloc->ulSize + sizeof(PALLOC_INFO)) + 0xfff) & ~0xfff;
if (VirtualFree((PVOID)pbyCommitStart, ulCommitSize, MEM_DECOMMIT) == FALSE)
{
DPFERROR((L"GuardPageFree : VirtualFree() failed when decommiting the commited pages"));
DebugBreak();
}
/* Now free linear address range*/
if (VirtualFree(psAlloc->pvBufStart, 0, MEM_RELEASE) == FALSE)
{
DPFERROR((L"GuardPageFree : VirtualFree() failed when releasing the region"));
DebugBreak();
}
/* Now update stats */
psHeap->sStats.ulFreeCount++;
psHeap->sStats.ulCurrentAllocs--;
psHeap->sStats.ulCurrentAllocSize -=psAlloc->ulSize;
gsHeaps.sGlbStats.ulFreeCount++;
gsHeaps.sGlbStats.ulCurrentAllocs--;
gsHeaps.sGlbStats.ulCurrentAllocSize-=psAlloc->ulSize;
/* Mark alloc as free */
memset(psAlloc, 0, sizeof(ALLOC_INFO));
/* Should we check all the heaps */
if (gsHeaps.ulCheckLevel >= MEMCHK_LEV_ALL_GUARD)
{
MemChkCheckAllHeaps(FALSE);
}
return (TRUE);
}
/**************************************************************************
* Function Name : GuardPageIsAllocCorrupt
* Inputs : PALLOC_INFO psAlloc
* Outputs :
* Returns :
* Description :
**************************************************************************/
PBYTE GuardPageIsAllocCorrupt(PALLOC_INFO psAlloc)
{
PBYTE pbyFailure;
PBYTE pbyGuardBuf;
ULONG ulGuardBufSize;
BYTE byGuardValue;
/* Check if the buffer to check is in front or behind the buffer */
if (gsHeaps.sGuradPageConfig.bFindUnderRuns == FALSE)
{
/* Checking buffer overrun so guard buffer is before alloc */
pbyGuardBuf=(PBYTE)(((ULONG)psAlloc->pvUserBuf) & ~0xfff);
/*
If buffer was a multiple of a page in size then ptr would be stored at
begining of previous page
*/
if (psAlloc->pvUserBuf == (PVOID)pbyGuardBuf)
{
pbyGuardBuf-=4096;
}
pbyGuardBuf += sizeof(PALLOC_INFO);
ulGuardBufSize = 4096 - ((psAlloc->ulSize & 0xfff) + sizeof(PALLOC_INFO));
byGuardValue = FRONT_RGN_VAL;
}
else
{
/* Checking for buffer underun so guard page is after allocation */
pbyGuardBuf = (PBYTE)psAlloc->pvUserBuf + psAlloc->ulSize;
ulGuardBufSize = 4096 - ((psAlloc->ulSize & 0xfff) + sizeof(PALLOC_INFO));
byGuardValue = BACK_RGN_VAL;
}
/* Check region for corruptions */
pbyFailure = IsMemRgnCorrupt((PVOID)pbyGuardBuf, ulGuardBufSize, byGuardValue);
if (pbyFailure != NULL)
{
DPFERROR((L"GuardPageIsAllocCorrupt : Caller has corrupted guard rgn at 0x%lx for associated buffer alloced at 0x%lx", pbyFailure, psAlloc->pvUserBuf));
DebugBreak();
return pbyFailure;
}
return (NULL);
}
/**************************************************************************
* Function Name : MemChkMalloc
* Inputs : ULONG ulSize
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID MemChkMalloc(ULONG ulSize)
{
/* Check if malloc heap has created */
if (ghMallocHeap ==INVALID_HANDLE_VALUE)
{
ghMallocHeap=MemChkHeapCreate(HEAP_NO_SERIALIZE, 4096, 0);
}
return (MemChkHeapAlloc(ghMallocHeap, 0, ulSize));
}
//#define MEMCHK
#ifdef MEMCHK
/*****************************************************************************
Function Name : DBGMemChkMalloc
Inputs : none
Outputs : none
Returns : pointer to allocated memory
Globals used : none
Description : As MemChkMalloc but with debug info printed
*****************************************************************************/
PVOID DBGMemChkMalloc(DWORD dwSize, PSTR pszFile, DWORD dwLine)
{
LPVOID pvPointer = NULL; // Return value for this function.
pvPointer = MemChkMalloc(dwSize);
DPF("DBGMemChkMalloc: User buf 0x%lx size 0x%lx by caller @ %hs line %d",
pvPointer, dwSize, pszFile, dwLine);
return (pvPointer);
}
#endif /* #ifdef MEMCHK */
/**************************************************************************
* Function Name : MemChkCalloc
* Inputs : ULONG ulNumItems, ULONG ulItemSize
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID MemChkCalloc(ULONG ulNumItems, ULONG ulItemSize)
{
/* Check if malloc heap has created */
if (ghMallocHeap ==INVALID_HANDLE_VALUE)
{
ghMallocHeap=MemChkHeapCreate(HEAP_NO_SERIALIZE, 4096, 0);
}
return (MemChkHeapAlloc(ghMallocHeap, HEAP_ZERO_MEMORY, ulNumItems * ulItemSize));
}
/**************************************************************************
* Function Name : MemChkFree
* Inputs : PVOID pvMem
* Outputs :
* Returns :
* Description :
**************************************************************************/
void MemChkFree(PVOID pvMem)
{
MemChkHeapFree(ghMallocHeap, 0, pvMem);
}
/**************************************************************************
* Function Name : MemChkRealloc
* Inputs : PVOID pvMem, ULONG dwNewSize
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID MemChkRealloc(PVOID pvMem, ULONG ulNewSize)
{
DPFWARNING ((L"MemChkRealloc : Not impliemented"));
DebugBreak();
return (NULL);
}
/********************************** end of file ******************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -