📄 memchk.cpp
字号:
}
/* Next table please */
psCurList=psCurList->psNext;
}
return (NULL);
}
/**************************************************************************
* Function Name :
* Inputs :
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID GuardBufAlloc(HANDLE hHeap, ULONG ulFlags, ULONG ulBytes)
{
PHEAP_INFO psHeap;
ULONG ulCallerAddr;
PALLOC_INFO psAlloc;
PVOID pvBuf;
PBYTE pbyPos;
/* Find callers addr */
ulCallerAddr=GET_CALLER_ADDR;
/* Find heap struct */
psHeap=(PHEAP_INFO)hHeap;
/* Now alloc buffer */
pvBuf = HeapAlloc(psHeap->hHeap, ulFlags, ulBytes + sizeof(PALLOC_INFO) + FRONT_RGN_SIZE + BACK_RGN_SIZE);
if (pvBuf == NULL)
{
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"GuardBufAlloc : 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 put in pointer back to alloc struct */
*((PALLOC_INFO*)pvBuf)=psAlloc;
pbyPos = (PBYTE)pvBuf + sizeof(psAlloc);
/* Next set front regions */
memset((PVOID)pbyPos, FRONT_RGN_VAL, FRONT_RGN_SIZE);
pbyPos += FRONT_RGN_SIZE;
/* Store callers buffer */
psAlloc->pvUserBuf=(PVOID)pbyPos;
/* Now set alloc buf */
if ((ulFlags & HEAP_ZERO_MEMORY) == 0)
{
memset((PVOID)pbyPos, ALLOC_MEM_VAL, ulBytes);
}
pbyPos += ulBytes;
/* Now set back region */
memset((PVOID)pbyPos, BACK_RGN_VAL, BACK_RGN_SIZE);
/* Now store some info */
psAlloc->ulCallersEIP = ulCallerAddr;
psAlloc->ulSize = ulBytes;
psAlloc->pvBufStart = pvBuf;
/* 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 :
* Inputs :
* Outputs :
* Returns :
* Description :
**************************************************************************/
BOOL GuardBufFree(HANDLE hHeap, ULONG ulFlags, PVOID pvMem)
{
PHEAP_INFO psHeap=(PHEAP_INFO)hHeap;
PALLOC_INFO psAlloc;
PALLOC_INFO psFound;
BOOL bRet;
/* Find alloc struct */
psAlloc=*((PALLOC_INFO*)(((PBYTE)pvMem)-(FRONT_RGN_SIZE+sizeof(PALLOC_INFO))));
/* Check this buffer is in our list */
psFound = FindAlloc(psHeap, psAlloc->pvBufStart);
if (psFound != psAlloc)
{
if (psFound == NULL)
{
DPFINFO((L"GuardBufFree : Caller free'ing buffer that is not currently allocated"));
}
else
{
DPFINFO((L"GuardBufFree : Buffer found in different alloc slot than store ptr shows"));
}
DebugBreak();
}
/* First check that buffers have not been corrupted */
GuardBufIsAllocCorrupt(psAlloc);
/* Now set alloced memory to dealloced value */
memset(pvMem, FREE_MEM_VAL, psAlloc->ulSize);
/* Now free the memory */
bRet=HeapFree(psHeap->hHeap, ulFlags, psAlloc->pvBufStart);
/* 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 bRet;
}
/**************************************************************************
* Function Name :
* Inputs :
* Outputs :
* Returns :
* Description :
**************************************************************************/
PBYTE GuardBufIsAllocCorrupt(PALLOC_INFO psAlloc)
{
PBYTE pbyFailure;
/* First check front regions */
pbyFailure=IsMemRgnCorrupt((PVOID)((PBYTE)psAlloc->pvBufStart + sizeof(PALLOC_INFO)), FRONT_RGN_SIZE, FRONT_RGN_VAL);
if (pbyFailure != NULL)
{
DPFERROR((L"GuardBufIsAllocCorrupt : Caller has underrun and corrupted guard rgn at 0x%lx before buffer alloced at 0x%lx", pbyFailure, psAlloc->pvUserBuf));
DebugBreak();
return pbyFailure;
}
/* Check back regions */
pbyFailure=IsMemRgnCorrupt((PVOID)((PBYTE)psAlloc->pvBufStart + sizeof(PALLOC_INFO) + FRONT_RGN_SIZE + psAlloc->ulSize ), BACK_RGN_SIZE, BACK_RGN_VAL);
if (pbyFailure != NULL)
{
DPFERROR((L"GuardBufIsAllocCorrupt : Caller has overrun and corrupted guard rgn at 0x%lx before buffer alloced at 0x%lx", pbyFailure, psAlloc->pvUserBuf));
DebugBreak();
return pbyFailure;
}
return (NULL);
}
/**************************************************************************
* Function Name : IsMemRgnCorrupt
* Inputs : PVOID pvBuf, ULONG ulSize, BYTE byCorrectValue
* Outputs :
* Returns :
* Description :
**************************************************************************/
PBYTE IsMemRgnCorrupt(PVOID pvBuf, ULONG ulSize, BYTE byCorrectValue)
{
ULONG ulIdx;
ULONG ulCount;
PBYTE pbyPtr=(PBYTE)pvBuf;
PULONG pulPtr;
ULONG ulCorrectValue = byCorrectValue + (byCorrectValue << 8) + (byCorrectValue << 16) + (byCorrectValue << 24);
ULONG ulBytesToComp = ulSize;
/* First do any byte compares to get upto a ULONG alignment */
ulCount = ((ULONG)pvBuf) % 4;
if (ulCount != 0)
{
ulCount = 4 - ulCount;
}
if (ulCount > ulSize)
{
ulCount = ulSize;
}
for (ulIdx=0; ulIdx < ulCount; ulIdx++)
{
if (*pbyPtr != byCorrectValue)
{
return (pbyPtr);
}
pbyPtr++;
}
ulBytesToComp -= ulCount;
/* Now check most of it in DWORDs */
ulCount = ulBytesToComp/4;
pulPtr = (PULONG)pbyPtr;
for (ulIdx=0; ulIdx < ulCount; ulIdx++)
{
if (*pulPtr != ulCorrectValue)
{
return ((PBYTE)pulPtr);
}
pulPtr++;
}
ulBytesToComp -= sizeof(ULONG) * ulCount;
/* Now check last lot of bytes */
ulCount = ulBytesToComp % 4;
pbyPtr = (PBYTE)pulPtr;
for (ulIdx=0; ulIdx < ulCount; ulIdx++)
{
if (*pbyPtr != byCorrectValue)
{
return (pbyPtr);
}
pbyPtr++;
}
return (NULL);
}
/**************************************************************************
* Function Name : MemChkCheckAllHeaps
* Inputs : BOOL bPrintInfo
* Outputs :
* Returns :
* Description :
**************************************************************************/
void MemChkCheckAllHeaps(BOOL bPrintInfo)
{
ULONG ulIdx;
if (bPrintInfo == TRUE)
{
DPFINFO((L"Total heap stats :"));
PrintStats(&gsHeaps.sGlbStats);
}
for (ulIdx=0; ulIdx < MAX_HEAPS; ulIdx++)
{
if (gsHeaps.sHeaps[ulIdx].hHeap != 0)
{
CheckHeap(&gsHeaps.sHeaps[ulIdx], bPrintInfo);
}
}
}
/**************************************************************************
* Function Name : CheckHeap
* Inputs : PHEAP_INFO psHeap, BOOL bPrintInfo
* Outputs :
* Returns :
* Description :
**************************************************************************/
void CheckHeap(PHEAP_INFO psHeap, BOOL bPrintInfo)
{
PALLOC_LIST psCurList=psHeap->psAllocList;
if (bPrintInfo == TRUE)
{
DPFINFO((L"\nHeap was created with init size of 0x%lx (%ldKb) and max size of 0x%lx (%ldKb)", psHeap->ulInitSize, psHeap->ulInitSize/1024, psHeap->ulMaxSize, psHeap->ulMaxSize/1024));
DPFINFO((L"Heap stats are :"));
PrintStats(&psHeap->sStats);
}
/* Look at each list */
while (psCurList != NULL)
{
ULONG ulIdx=0;
/* Read all items in this table */
for (ulIdx=0; ulIdx < ALLOC_PER_TABLE; ulIdx++)
{
if (psCurList->asAllocs[ulIdx].pvBufStart != 0)
{
if (bPrintInfo == TRUE)
{
DPFINFO((L"User buf 0x%lx - 0x%lx size 0x%lx (%ld Kb) by caller @ 0x%lx", psCurList->asAllocs[ulIdx].pvUserBuf, ((PBYTE)psCurList->asAllocs[ulIdx].pvUserBuf) + psCurList->asAllocs[ulIdx].ulSize, psCurList->asAllocs[ulIdx].ulSize, psCurList->asAllocs[ulIdx].ulSize/1024, psCurList->asAllocs[ulIdx].ulCallersEIP));
}
gsHeaps.psfnRoutines->pfnIsAllocCorrupt(&psCurList->asAllocs[ulIdx]);
}
}
/* Next table please */
psCurList = psCurList->psNext;
}
}
/**************************************************************************
* Function Name : PrintStats
* Inputs : PALLOC_STATS psStats
* Outputs :
* Returns :
* Description :
**************************************************************************/
void PrintStats(PALLOC_STATS psStats)
{
DPFINFO((L"Total allocs %ld, total frees %ld", psStats->ulAllocCount, psStats->ulFreeCount));
DPFINFO((L"%ld outstanding allocs 0x%lx (%ldKb) in size ", psStats->ulCurrentAllocs, psStats->ulCurrentAllocSize, psStats->ulCurrentAllocSize/1024));
}
/**************************************************************************
* Function Name : GuardPageAlloc
* Inputs : HANDLE hHeap, ULONG ulFlags, ULONG ulBytes
* Outputs :
* Returns :
* Description :
**************************************************************************/
PVOID GuardPageAlloc(HANDLE hHeap, ULONG ulFlags, ULONG ulBytes)
{
PHEAP_INFO psHeap;
ULONG ulCallerAddr;
PALLOC_INFO psAlloc;
PBYTE pbyBuf;
PBYTE pbyPos;
ULONG ulResSize;
ULONG ulCommitSize;
/* Find callers addr */
ulCallerAddr = GET_CALLER_ADDR;
/* Find heap struct */
psHeap=(PHEAP_INFO)hHeap;
/* Calc the size of the linear address to reserve */
ulCommitSize = ((ulBytes + sizeof(PALLOC_INFO)) + 0xfff) & ~0xfff;
ulResSize = ulCommitSize + ((gsHeaps.sGuradPageConfig.ulBackGuradPages + gsHeaps.sGuradPageConfig.ulFrontGuradPages) * 4096);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -