mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +00:00
Implement Heap32First and Heap32Next based on the documentation on http://securityxploded.com/enumheaps.php
svn path=/trunk/; revision=27692
This commit is contained in:
parent
938646d914
commit
4aa6574ca2
1 changed files with 167 additions and 6 deletions
|
@ -25,6 +25,15 @@
|
||||||
|
|
||||||
/* INTERNAL DEFINITIONS *******************************************************/
|
/* INTERNAL DEFINITIONS *******************************************************/
|
||||||
|
|
||||||
|
typedef struct _RTLP_HEAP_ENTRY
|
||||||
|
{
|
||||||
|
ULONG Size;
|
||||||
|
USHORT Flags;
|
||||||
|
USHORT Unknown1; /* FIXME */
|
||||||
|
ULONG Unknown2; /* FIXME */
|
||||||
|
PVOID Address;
|
||||||
|
} RTLP_HEAP_ENTRY, *PRTLP_HEAP_ENTRY;
|
||||||
|
|
||||||
#define CHECK_PARAM_SIZE(ptr, siz) \
|
#define CHECK_PARAM_SIZE(ptr, siz) \
|
||||||
if((ptr) == NULL || (ptr)->dwSize != (siz)) \
|
if((ptr) == NULL || (ptr)->dwSize != (siz)) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -473,30 +482,182 @@ TH32CreateSnapshotSectionInitialize(DWORD dwFlags,
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
Heap32First(LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID)
|
Heap32First(LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID)
|
||||||
{
|
{
|
||||||
|
PRTL_DEBUG_INFORMATION DebugInfo;
|
||||||
|
PRTL_HEAP_INFORMATION Heap;
|
||||||
|
PRTLP_HEAP_ENTRY Block, LastBlock;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
|
CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
|
||||||
|
|
||||||
SetLastError(ERROR_NO_MORE_FILES);
|
DebugInfo = RtlCreateQueryDebugBuffer(0,
|
||||||
return FALSE;
|
FALSE);
|
||||||
|
if (DebugInfo == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = RtlQueryProcessDebugInformation(th32ProcessID,
|
||||||
|
RTL_DEBUG_QUERY_HEAPS | RTL_DEBUG_QUERY_HEAP_BLOCKS,
|
||||||
|
DebugInfo);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MORE_FILES;
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
i != DebugInfo->Heaps->NumberOfHeaps;
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
Heap = &DebugInfo->Heaps->Heaps[i];
|
||||||
|
|
||||||
|
if ((ULONG_PTR)Heap->BaseAddress == th32HeapID)
|
||||||
|
{
|
||||||
|
lphe->hHandle = (HANDLE)Heap->BaseAddress;
|
||||||
|
lphe->dwAddress = 0;
|
||||||
|
lphe->dwBlockSize = 0;
|
||||||
|
lphe->dwFlags = 0;
|
||||||
|
lphe->dwLockCount = 0;
|
||||||
|
lphe->dwResvd = 0;
|
||||||
|
lphe->th32ProcessID = th32ProcessID;
|
||||||
|
lphe->th32HeapID = (ULONG_PTR)Heap->BaseAddress;
|
||||||
|
|
||||||
|
Block = (PRTLP_HEAP_ENTRY)Heap->Entries;
|
||||||
|
LastBlock = Block + Heap->NumberOfEntries;
|
||||||
|
|
||||||
|
while (Block != LastBlock && (Block->Flags & PROCESS_HEAP_UNCOMMITTED_RANGE))
|
||||||
|
{
|
||||||
|
lphe->dwResvd++;
|
||||||
|
lphe->dwAddress = (ULONG_PTR)((ULONG_PTR)Block->Address + Heap->EntryOverhead);
|
||||||
|
Block++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Block != LastBlock && lphe->dwResvd != 0)
|
||||||
|
{
|
||||||
|
lphe->dwBlockSize = Block->Size;
|
||||||
|
|
||||||
|
if (Block->Flags & 0x2F1) /* FIXME */
|
||||||
|
lphe->dwFlags = LF32_FIXED;
|
||||||
|
else if (Block->Flags & 0x20) /* FIXME */
|
||||||
|
lphe->dwFlags = LF32_MOVEABLE;
|
||||||
|
else if (Block->Flags & 0x100) /* FIXME */
|
||||||
|
lphe->dwFlags = LF32_FREE;
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlDestroyQueryDebugBuffer(DebugInfo);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
Heap32Next(LPHEAPENTRY32 lphe)
|
Heap32Next(LPHEAPENTRY32 lphe)
|
||||||
{
|
{
|
||||||
|
PRTL_DEBUG_INFORMATION DebugInfo;
|
||||||
|
PRTL_HEAP_INFORMATION Heap;
|
||||||
|
PRTLP_HEAP_ENTRY Block, LastBlock;
|
||||||
|
BOOLEAN FoundUncommitted = FALSE;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
|
CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
|
||||||
|
|
||||||
SetLastError(ERROR_NO_MORE_FILES);
|
DebugInfo = RtlCreateQueryDebugBuffer(0,
|
||||||
return FALSE;
|
FALSE);
|
||||||
|
if (DebugInfo == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = RtlQueryProcessDebugInformation(lphe->th32ProcessID,
|
||||||
|
RTL_DEBUG_QUERY_HEAPS | RTL_DEBUG_QUERY_HEAP_BLOCKS,
|
||||||
|
DebugInfo);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MORE_FILES;
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
i != DebugInfo->Heaps->NumberOfHeaps;
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
Heap = &DebugInfo->Heaps->Heaps[i];
|
||||||
|
|
||||||
|
if ((ULONG_PTR)Heap->BaseAddress == lphe->th32HeapID)
|
||||||
|
{
|
||||||
|
if (++lphe->dwResvd < Heap->NumberOfEntries)
|
||||||
|
{
|
||||||
|
lphe->dwFlags = 0;
|
||||||
|
|
||||||
|
Block = (PRTLP_HEAP_ENTRY)Heap->Entries + lphe->dwResvd;
|
||||||
|
LastBlock = (PRTLP_HEAP_ENTRY)Heap->Entries + Heap->NumberOfEntries;
|
||||||
|
|
||||||
|
while (Block < LastBlock && (Block->Flags & PROCESS_HEAP_UNCOMMITTED_RANGE))
|
||||||
|
{
|
||||||
|
lphe->dwResvd++;
|
||||||
|
lphe->dwAddress = (ULONG_PTR)((ULONG_PTR)Block->Address + Heap->EntryOverhead);
|
||||||
|
FoundUncommitted = TRUE;
|
||||||
|
Block++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Block < LastBlock)
|
||||||
|
{
|
||||||
|
if (!FoundUncommitted)
|
||||||
|
lphe->dwAddress += lphe->dwBlockSize;
|
||||||
|
|
||||||
|
lphe->dwBlockSize = Block->Size;
|
||||||
|
|
||||||
|
if (Block->Flags & 0x2F1) /* FIXME */
|
||||||
|
lphe->dwFlags = LF32_FIXED;
|
||||||
|
else if (Block->Flags & 0x20) /* FIXME */
|
||||||
|
lphe->dwFlags = LF32_MOVEABLE;
|
||||||
|
else if (Block->Flags & 0x100) /* FIXME */
|
||||||
|
lphe->dwFlags = LF32_FREE;
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlDestroyQueryDebugBuffer(DebugInfo);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue