cheat-engine/DBKKernel/processlist.c

427 lines
11 KiB
C
Raw Permalink Normal View History

#pragma warning( disable: 4100 4103 4706)
2011-07-04 19:53:17 +00:00
#include "ntifs.h"
#include "processlist.h"
#include "threads.h"
#include "memscan.h"
#include "ultimap2.h"
2017-01-12 00:33:51 +01:00
PRTL_GENERIC_TABLE InternalProcessList = NULL;
PEPROCESS WatcherProcess = NULL;
BOOLEAN ProcessWatcherOpensHandles = TRUE;
2017-01-12 00:33:51 +01:00
RTL_GENERIC_COMPARE_RESULTS NTAPI ProcessListCompare(__in struct _RTL_GENERIC_TABLE *Table, __in PProcessListData FirstStruct, __in PProcessListData SecondStruct)
{
//DbgPrint("ProcessListCompate");
2017-01-12 00:33:51 +01:00
if (FirstStruct->ProcessID == SecondStruct->ProcessID)
return GenericEqual;
else
{
if (SecondStruct->ProcessID < FirstStruct->ProcessID)
return GenericLessThan;
else
return GenericGreaterThan;
}
}
PVOID NTAPI ProcessListAlloc(__in struct _RTL_GENERIC_TABLE *Table, __in CLONG ByteSize)
{
PVOID r=ExAllocatePool(PagedPool, ByteSize);
2017-01-12 00:33:51 +01:00
RtlZeroMemory(r, ByteSize);
//DbgPrint("ProcessListAlloc %d",(int)ByteSize);
return r;
2017-01-12 00:33:51 +01:00
}
VOID NTAPI ProcessListDealloc(__in struct _RTL_GENERIC_TABLE *Table, __in __drv_freesMem(Mem) __post_invalid PVOID Buffer)
{
//DbgPrint("ProcessListDealloc");
2019-07-08 10:50:35 +02:00
ExFreePool(Buffer);
2017-01-12 00:33:51 +01:00
}
2011-07-04 19:53:17 +00:00
VOID GetThreadData(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
{
struct ThreadData *tempThreadEntry;
PETHREAD selectedthread;
HANDLE tid;
LARGE_INTEGER Timeout;
PKAPC AP;
tempThreadEntry=Context;
DbgPrint("Gathering PEThread thread\n");
Timeout.QuadPart = -1;
KeDelayExecutionThread(KernelMode, TRUE, &Timeout);
selectedthread=NULL;
2017-01-12 00:33:51 +01:00
if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE))
2011-07-04 19:53:17 +00:00
{
2017-01-12 00:33:51 +01:00
tid = tempThreadEntry->ThreadID;
AP = &tempThreadEntry->SuspendApc;
PsLookupThreadByThreadId((PVOID)tid, &selectedthread);
if (selectedthread)
{
DbgPrint("PEThread=%p\n", selectedthread);
KeInitializeApc(AP,
(PKTHREAD)selectedthread,
0,
(PKKERNEL_ROUTINE)Ignore,
(PKRUNDOWN_ROUTINE)NULL,
(PKNORMAL_ROUTINE)SuspendThreadAPCRoutine,
KernelMode,
NULL);
ObDereferenceObject(selectedthread);
}
else
{
DbgPrint("Failed getting the pethread.\n");
}
}
ExReleaseResourceLite(&ProcesslistR);
2011-07-04 19:53:17 +00:00
}
VOID CreateThreadNotifyRoutine(IN HANDLE ProcessId,IN HANDLE ThreadId,IN BOOLEAN Create)
{
if (KeGetCurrentIrql()==PASSIVE_LEVEL)
{
/*if (DebuggedProcessID==(ULONG)ProcessId)
{
// PsSetContextThread (bah, xp only)
}*/
2017-01-12 00:33:51 +01:00
if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE))
{
if (ThreadEventCount < 50)
{
ThreadEventData[ThreadEventCount].Created = Create;
ThreadEventData[ThreadEventCount].ProcessID = (UINT_PTR)ProcessId;
ThreadEventData[ThreadEventCount].ThreadID = (UINT_PTR)ThreadId;
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
/* if (Create)
DbgPrint("Create ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId);
else
DbgPrint("Destroy ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId);
*/
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
ThreadEventCount++;
}
2011-07-04 19:53:17 +00:00
}
2017-01-12 00:33:51 +01:00
ExReleaseResourceLite(&ProcesslistR);
2011-07-04 19:53:17 +00:00
KeSetEvent(ThreadEvent, 0, FALSE);
KeClearEvent(ThreadEvent);
}
}
VOID CreateProcessNotifyRoutine(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create)
{
2017-01-12 00:33:51 +01:00
PEPROCESS CurrentProcess = NULL;
HANDLE ProcessHandle = 0;
/*
if (PsSuspendProcess)
{
DbgPrint("Suspending process %d", PsGetCurrentThreadId());
PsSuspendProcess(PsGetCurrentProcess());
DbgPrint("After PsGetCurrentProcess()");
}
*/
2017-01-12 00:33:51 +01:00
2011-07-04 19:53:17 +00:00
if (KeGetCurrentIrql()==PASSIVE_LEVEL)
{
struct ProcessData *tempProcessEntry;
//aquire a spinlock
2017-01-12 00:33:51 +01:00
if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE))
{
2019-07-22 22:33:28 +02:00
if (PsLookupProcessByProcessId((PVOID)ProcessId, &CurrentProcess) != STATUS_SUCCESS)
{
ExReleaseResourceLite(&ProcesslistR);
return;
}
if ((ProcessWatcherOpensHandles) && (WatcherProcess))
2011-07-04 19:53:17 +00:00
{
2019-07-22 22:33:28 +02:00
if (Create)
2011-07-04 19:53:17 +00:00
{
2019-07-22 22:33:28 +02:00
//Open a handle to this process
2019-07-22 22:33:28 +02:00
/*
2019-07-22 22:33:28 +02:00
HANDLE ph = 0;
NTSTATUS r = ObOpenObjectByPointer(CurrentProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &ph);
2019-07-22 22:33:28 +02:00
DbgPrint("CreateProcessNotifyRoutine: ObOpenObjectByPointer=%x ph=%x", r, ph);
r = ZwDuplicateObject(ZwCurrentProcess(), ph, WatcherHandle, &ProcessHandle, PROCESS_ALL_ACCESS, 0, DUPLICATE_CLOSE_SOURCE);
2019-07-22 22:33:28 +02:00
DbgPrint("CreateProcessNotifyRoutine: ZwDuplicateObject=%x (handle=%x)", r, ProcessHandle);
*/
2019-07-22 22:33:28 +02:00
KAPC_STATE oldstate;
2019-07-22 22:33:28 +02:00
KeStackAttachProcess((PKPROCESS)WatcherProcess, &oldstate);
__try
{
2017-01-12 00:33:51 +01:00
__try
{
2019-07-22 22:33:28 +02:00
ObOpenObjectByPointer(CurrentProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &ProcessHandle);
2017-01-12 00:33:51 +01:00
}
2019-07-22 22:33:28 +02:00
__except (1)
2017-01-12 00:33:51 +01:00
{
2019-07-22 22:33:28 +02:00
DbgPrint("Exception during ObOpenObjectByPointer");
2017-01-12 00:33:51 +01:00
}
}
2019-07-22 22:33:28 +02:00
__finally
{
KeUnstackDetachProcess(&oldstate);
}
2011-07-04 19:53:17 +00:00
}
2019-07-22 22:33:28 +02:00
2017-01-12 00:33:51 +01:00
if (InternalProcessList == NULL)
2011-07-04 19:53:17 +00:00
{
InternalProcessList = ExAllocatePool(PagedPool, sizeof(RTL_GENERIC_TABLE));
2017-01-12 00:33:51 +01:00
if (InternalProcessList)
RtlInitializeGenericTable(InternalProcessList, ProcessListCompare, ProcessListAlloc, ProcessListDealloc, NULL);
2011-07-04 19:53:17 +00:00
}
2017-01-12 00:33:51 +01:00
if (InternalProcessList)
{
ProcessListData d, *r;
d.ProcessID = ProcessId;
d.PEProcess = CurrentProcess;
d.ProcessHandle = ProcessHandle;
r = RtlLookupElementGenericTable(InternalProcessList, &d);
if (Create)
{
//add it to the list
BOOLEAN newElement = FALSE;
2017-01-12 00:33:51 +01:00
if (r) //weird
{
DbgPrint("Duplicate PID detected...");
2017-01-12 00:33:51 +01:00
RtlDeleteElementGenericTable(InternalProcessList, r);
}
2017-01-12 00:33:51 +01:00
r = RtlInsertElementGenericTable(InternalProcessList, &d, sizeof(d), &newElement);
DbgPrint("Added handle %x for pid %d to the list (newElement=%d r=%p)", (int)(UINT_PTR)d.ProcessHandle, (int)(UINT_PTR)d.ProcessID, newElement, r);
2017-01-12 00:33:51 +01:00
}
else
{
//remove it from the list (if it's there)
DbgPrint("Process %d destruction. r=%p", (int)(UINT_PTR)d.ProcessID, r);
2017-01-12 00:33:51 +01:00
if (r)
{
DbgPrint("Process that was in the list has been closed");
//if (r->ProcessHandle)
// ZwClose(r->ProcessHandle);
2017-01-12 00:33:51 +01:00
//RtlDeleteElementGenericTable(InternalProcessList, r);
r->Deleted = 1;
2017-01-12 00:33:51 +01:00
}
if (CurrentProcess == WatcherProcess)
{
DbgPrint("CE Closed");
//ZwClose(WatcherHandle);
2017-01-12 00:33:51 +01:00
CleanProcessList(); //CE closed
WatcherProcess = 0;
2017-01-12 00:33:51 +01:00
}
}
}
2011-07-04 19:53:17 +00:00
}
2017-01-12 00:33:51 +01:00
//fill in a processcreateblock with data
if (ProcessEventCount < 50)
2011-07-04 19:53:17 +00:00
{
2017-01-12 00:33:51 +01:00
ProcessEventdata[ProcessEventCount].Created = Create;
ProcessEventdata[ProcessEventCount].ProcessID = (UINT_PTR)ProcessId;
ProcessEventdata[ProcessEventCount].PEProcess = (UINT_PTR)CurrentProcess;
ProcessEventCount++;
}
//if (!HiddenDriver)
if (FALSE) //moved till next version
{
if (Create)
2011-07-04 19:53:17 +00:00
{
2017-01-12 00:33:51 +01:00
//allocate a block of memory for the processlist
2011-07-04 19:53:17 +00:00
tempProcessEntry = ExAllocatePool(PagedPool, sizeof(struct ProcessData));
2017-01-12 00:33:51 +01:00
tempProcessEntry->ProcessID = ProcessId;
tempProcessEntry->PEProcess = CurrentProcess;
tempProcessEntry->Threads = NULL;
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
DbgPrint("Allocated a process at:%p\n", tempProcessEntry);
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
if (!processlist)
{
processlist = tempProcessEntry;
processlist->next = NULL;
processlist->previous = NULL;
}
else
{
tempProcessEntry->next = processlist;
tempProcessEntry->previous = NULL;
processlist->previous = tempProcessEntry;
processlist = tempProcessEntry;
}
}
else
{
//find this process and delete it
tempProcessEntry = processlist;
while (tempProcessEntry)
{
if (tempProcessEntry->ProcessID == ProcessId)
2011-07-04 19:53:17 +00:00
{
2017-01-12 00:33:51 +01:00
int i;
if (tempProcessEntry->next)
tempProcessEntry->next->previous = tempProcessEntry->previous;
if (tempProcessEntry->previous)
tempProcessEntry->previous->next = tempProcessEntry->next;
else
processlist = tempProcessEntry->next; //it had no previous entry, so it's the root
/*
if (tempProcessEntry->Threads)
{
2011-07-04 19:53:17 +00:00
struct ThreadData *tempthread,*tempthread2;
KIRQL OldIrql2;
tempthread=tempProcessEntry->Threads;
tempthread2=tempthread;
DbgPrint("Process ended. Freeing threads\n");
while (tempthread)
{
2017-01-12 00:33:51 +01:00
tempthread=tempthread->next;
DbgPrint("Free thread %p (next thread=%p)\n",tempthread2,tempthread);
ExFreePool(tempthread2);
tempthread2=tempthread;
}
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
}
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
ExFreePool(tempProcessEntry);*/
i = 0;
tempProcessEntry = processlist;
while (tempProcessEntry)
{
i++;
tempProcessEntry = tempProcessEntry->next;
}
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
DbgPrint("There are %d processes in the list\n", i);
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
break;
}
tempProcessEntry = tempProcessEntry->next;
2011-07-04 19:53:17 +00:00
}
2017-01-12 00:33:51 +01:00
2011-07-04 19:53:17 +00:00
}
}
}
2017-01-12 00:33:51 +01:00
ExReleaseResourceLite(&ProcesslistR);
2011-07-04 19:53:17 +00:00
if (CurrentProcess!=NULL)
ObDereferenceObject(CurrentProcess);
//signal process event (if there's one waiting for a signal)
if (ProcessEvent)
{
KeSetEvent(ProcessEvent, 0, FALSE);
KeClearEvent(ProcessEvent);
}
}
2017-01-12 00:33:51 +01:00
}
VOID CreateProcessNotifyRoutineEx(IN HANDLE ParentId, IN HANDLE ProcessId, __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo)
{
DbgPrint("CreateProcessNotifyRoutineEx");
CreateProcessNotifyRoutine(ParentId, ProcessId, CreateInfo!=NULL);
}
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
HANDLE GetHandleForProcessID(IN HANDLE ProcessID)
{
if (InternalProcessList)
{
ProcessListData d, *r;
2011-07-04 19:53:17 +00:00
2017-01-12 00:33:51 +01:00
d.ProcessID = ProcessID;
r = RtlLookupElementGenericTable(InternalProcessList, &d);
if (r)
{
DbgPrint("Found a handle for PID %d (%x)", (int)(UINT_PTR)ProcessID, (int)(UINT_PTR)r->ProcessHandle);
return r->ProcessHandle; // r->ProcessHandle;
}
}
return 0;
2011-07-04 19:53:17 +00:00
}
2017-01-12 00:33:51 +01:00
VOID CleanProcessList()
{
if (InternalProcessList)
{
PProcessListData li;
if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE))
2017-01-12 00:33:51 +01:00
{
KAPC_STATE oldstate;
BOOLEAN ChangedContext;
2017-01-12 00:33:51 +01:00
if ((WatcherProcess) && (WatcherProcess != PsGetCurrentProcess()))
{
KeStackAttachProcess((PKPROCESS)WatcherProcess, &oldstate);
ChangedContext = TRUE;
}
while (li = RtlGetElementGenericTable(InternalProcessList, 0))
{
if ((li->ProcessHandle) && (WatcherProcess))
ZwClose(li->ProcessHandle);
2017-01-12 00:33:51 +01:00
RtlDeleteElementGenericTable(InternalProcessList, li);
}
2019-07-08 10:50:35 +02:00
ExFreePool(InternalProcessList);
InternalProcessList = NULL;
}
ExReleaseResourceLite(&ProcesslistR);
2017-01-12 00:33:51 +01:00
}
}