📄 toolhelp.c
字号:
do
{
PSYSTEM_THREAD_INFORMATION ThreadInfo;
ULONG n;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
for(n = 0; n < ProcessInfo->NumberOfThreads; n++)
{
ThreadListEntry->dwSize = sizeof(THREADENTRY32);
ThreadListEntry->cntUsage = 0; /* no longer used */
ThreadListEntry->th32ThreadID = (ULONG)ThreadInfo->ClientId.UniqueThread;
ThreadListEntry->th32OwnerProcessID = (ULONG)ThreadInfo->ClientId.UniqueProcess;
ThreadListEntry->tpBasePri = ThreadInfo->BasePriority;
ThreadListEntry->tpDeltaPri = 0; /* no longer used */
ThreadListEntry->dwFlags = 0; /* no longer used */
ThreadInfo++;
ThreadListEntry++;
}
ProcOffset = ProcessInfo->NextEntryOffset;
} while(ProcOffset != 0);
}
/*
* We're done, unmap the view and return the section handle
*/
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
if(NT_SUCCESS(Status))
{
*SectionHandle = hSection;
}
else
{
NtClose(hSection);
}
return Status;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
BOOL
STDCALL
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));
DebugInfo = RtlCreateQueryDebugBuffer(0,
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;
}
/*
* @implemented
*/
BOOL
STDCALL
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));
DebugInfo = RtlCreateQueryDebugBuffer(0,
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;
}
/*
* @implemented
*/
BOOL
STDCALL
Heap32ListFirst(HANDLE hSnapshot, LPHEAPLIST32 lphl)
{
PTH32SNAPSHOT Snapshot;
LARGE_INTEGER SOffset;
ULONG ViewSize;
NTSTATUS Status;
CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
SOffset.QuadPart = 0;
ViewSize = 0;
Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot,
NtCurrentProcess(),
(PVOID*)&Snapshot,
0,
0,
&SOffset,
&ViewSize,
ViewShare,
0,
PAGE_READWRITE);
if(NT_SUCCESS(Status))
{
BOOL Ret;
if(Snapshot->HeapListCount > 0)
{
LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset);
Snapshot->HeapListIndex = 1;
RtlCopyMemory(lphl, &Entries[0], sizeof(HEAPLIST32));
Ret = TRUE;
}
else
{
SetLastError(ERROR_NO_MORE_FILES);
Ret = FALSE;
}
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
return Ret;
}
SetLastErrorByStatus(Status);
return FALSE;
}
/*
* @implemented
*/
BOOL
STDCALL
Heap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lphl)
{
PTH32SNAPSHOT Snapshot;
LARGE_INTEGER SOffset;
ULONG ViewSize;
NTSTATUS Status;
CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
SOffset.QuadPart = 0;
ViewSize = 0;
Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot,
NtCurrentProcess(),
(PVOID*)&Snapshot,
0,
0,
&SOffset,
&ViewSize,
ViewShare,
0,
PAGE_READWRITE);
if(NT_SUCCESS(Status))
{
BOOL Ret;
if(Snapshot->HeapListCount > 0 &&
Snapshot->HeapListIndex < Snapshot->HeapListCount)
{
LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset);
RtlCopyMemory(lphl, &Entries[Snapshot->HeapListIndex++], sizeof(HEAPLIST32));
Ret = TRUE;
}
else
{
SetLastError(ERROR_NO_MORE_FILES);
Ret = FALSE;
}
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
return Ret;
}
SetLastErrorByStatus(Status);
return FALSE;
}
/*
* @implemented
*/
BOOL
STDCALL
Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
{
MODULEENTRY32W me;
BOOL Ret;
CHECK_PARAM_SIZEA(lpme, sizeof(MODULEENTRY32));
me.dwSize = sizeof(MODULEENTRY32W);
Ret = Module32FirstW(hSnapshot, &me);
if(Ret)
{
lpme->th32ModuleID = me.th32ModuleID;
lpme->th32ProcessID = me.th32ProcessID;
lpme->GlblcntUsage = me.GlblcntUsage;
lpme->ProccntUsage = me.ProccntUsage;
lpme->modBaseAddr = me.modBaseAddr;
lpme->modBaseSize = me.modBaseSize;
lpme->hModule = me.hModule;
WideCharToMultiByte(CP_ACP, 0, me.szModule, -1, lpme->szModule, sizeof(lpme->szModule), 0, 0);
WideCharToMultiByte(CP_ACP, 0, me.szExePath, -1, lpme->szExePath, sizeof(lpme->szExePath), 0, 0);
}
return Ret;
}
/*
* @implemented
*/
BOOL
STDCALL
Module32FirstW(HANDLE hSnapshot, LPMODULEENTRY32W lpme)
{
PTH32SNAPSHOT Snapshot;
LARGE_INTEGER SOffset;
ULONG ViewSize;
NTSTATUS Status;
CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W));
SOffset.QuadPart = 0;
ViewSize = 0;
Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot,
NtCurrentProcess(),
(PVOID*)&Snapshot,
0,
0,
&SOffset,
&ViewSize,
ViewShare,
0,
PAGE_READWRITE);
if(NT_SUCCESS(Status))
{
BOOL Ret;
if(Snapshot->ModuleListCount > 0)
{
LPMODULEENTRY32W Entries = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, Snapshot->ModuleListOffset);
Snapshot->ModuleListIndex = 1;
RtlCopyMemory(lpme, &Entries[0], sizeof(MODULEENTRY32W));
Ret = TRUE;
}
else
{
SetLastError(ERROR_NO_MORE_FILES);
Ret = FALSE;
}
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
return Ret;
}
SetLastErrorByStatus(Status);
return FALSE;
}
/*
* @implemented
*/
BOOL
STDCALL
Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
{
MODULEENTRY32W me;
BOOL Ret;
CHECK_PARAM_SIZEA(lpme, sizeof(MODULEENTRY32));
me.dwSize = sizeof(MODULEENTRY32W);
Ret = Module32NextW(hSnapshot, &me);
if(Ret)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -