cheat-engine/DBKKernel/threads.c
2017-01-12 00:33:51 +01:00

255 lines
5.3 KiB
C

#pragma warning( disable: 4103)
#include "threads.h"
#include "processlist.h"
#include "memscan.h"
struct ThreadData* GetThreaddata(ULONG threadid)
{
struct ProcessData *tempProcessData;
struct ThreadData *tempThreadData;
//PRE: Lock the list before calling this routine
tempProcessData=processlist;
while (tempProcessData)
{
tempThreadData=tempProcessData->Threads;
while (tempThreadData)
{
if (tempThreadData->ThreadID==(HANDLE)(UINT_PTR)threadid)
return tempThreadData;
tempThreadData=tempThreadData->next;
}
tempProcessData=tempProcessData->next;
}
return NULL;
}
void Ignore(PKAPC Apc, PKNORMAL_ROUTINE NormalRoutine, PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
//ignore
return;
}
void SuspendThreadAPCRoutine(PVOID arg1, PVOID arg2, PVOID arg3)
{
LARGE_INTEGER Timeout;
struct ThreadData *x;
//DbgPrint("Inside SuspendThreadAPCRoutine\n");
x=arg1;
//DbgPrint("x=%p",x);
DbgPrint("Waiting...\n");
Timeout.QuadPart = -999999999999999;
KeWaitForSingleObject(&(x->SuspendSemaphore), Suspended, KernelMode, FALSE, NULL);
//KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
DbgPrint("Resuming...\n");
}
void DBKSuspendThread(ULONG ThreadID)
{
KIRQL OldIrql;
struct ThreadData *t_data;
if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE))
{
DbgPrint("Going to suspend this thread\n");
//find the thread in the threadlist
//find the threadid in the processlist
t_data = GetThreaddata(ThreadID);
if (t_data)
{
DbgPrint("Suspending thread....\n");
if (!t_data->PEThread)
{
//not yet initialized
t_data->PEThread = (PETHREAD)getPEThread(ThreadID);
KeInitializeApc(&t_data->SuspendApc,
(PKTHREAD)t_data->PEThread,
0,
(PKKERNEL_ROUTINE)Ignore,
(PKRUNDOWN_ROUTINE)NULL,
(PKNORMAL_ROUTINE)SuspendThreadAPCRoutine,
KernelMode,
t_data);
}
DbgPrint("x should be %p", t_data);
t_data->suspendcount++;
if (t_data->suspendcount == 1) //not yet suspended so suspend it
KeInsertQueueApc(&t_data->SuspendApc, t_data, t_data, 0);
}
else
DbgPrint("Thread not found in the list\n");
}
ExReleaseResourceLite(&ProcesslistR);
}
void DBKResumeThread(ULONG ThreadID)
{
KIRQL OldIrql;
struct ThreadData *t_data;
if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE))
{
DbgPrint("Going to resume this thread\n");
//find the thread in the threadlist
//find the threadid in the processlist
t_data = GetThreaddata(ThreadID);
if (t_data)
{
if (t_data->suspendcount)
{
t_data->suspendcount--;
if (!t_data->suspendcount) //suspendcount=0 so resume
KeReleaseSemaphore(&t_data->SuspendSemaphore, 0, 1, FALSE);
}
}
else
DbgPrint("Thread not found in the list\n");
}
ExReleaseResourceLite(&ProcesslistR);
}
void DBKSuspendProcess(ULONG ProcessID)
{
KIRQL OldIrql;
struct ThreadData *t_data=NULL;
struct ProcessData *tempProcessData=NULL;
if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE))
{
DbgPrint("Going to suspend this process\n");
//find the process in the threadlist
tempProcessData = processlist;
while (tempProcessData)
{
if (tempProcessData->ProcessID == (HANDLE)(UINT_PTR)ProcessID)
{
t_data = tempProcessData->Threads;
break;
}
tempProcessData = tempProcessData->next;
}
if (!t_data)
{
DbgPrint("This process was not found\n");
ExReleaseResourceLite(&ProcesslistR);
return; //no process found
}
while (t_data)
{
DbgPrint("Suspending thread....\n");
if (!t_data->PEThread)
{
//not yet initialized
t_data->PEThread = (PETHREAD)getPEThread((UINT_PTR)t_data->ThreadID);
KeInitializeApc(&t_data->SuspendApc,
(PKTHREAD)t_data->PEThread,
0,
(PKKERNEL_ROUTINE)Ignore,
(PKRUNDOWN_ROUTINE)NULL,
(PKNORMAL_ROUTINE)SuspendThreadAPCRoutine,
KernelMode,
t_data);
}
DbgPrint("x should be %p", t_data);
t_data->suspendcount++;
if (t_data->suspendcount == 1) //not yet suspended so suspend it
KeInsertQueueApc(&t_data->SuspendApc, t_data, t_data, 0);
t_data = t_data->next; //next thread
}
}
ExReleaseResourceLite(&ProcesslistR);
}
void DBKResumeProcess(ULONG ProcessID)
{
KIRQL OldIrql;
struct ThreadData *t_data=NULL;
struct ProcessData *tempProcessData=NULL;
if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE))
{
DbgPrint("Going to suspend this process\n");
//find the process in the threadlist
tempProcessData = processlist;
while (tempProcessData)
{
if (tempProcessData->ProcessID == (HANDLE)(UINT_PTR)ProcessID)
{
t_data = tempProcessData->Threads;
break;
}
tempProcessData = tempProcessData->next;
}
if (!t_data)
{
DbgPrint("This process was not found\n");
ExReleaseResourceLite(&ProcesslistR);
return; //no process found
}
while (t_data)
{
DbgPrint("Resuming thread....\n");
if (t_data->suspendcount)
{
t_data->suspendcount--;
if (!t_data->suspendcount) //suspendcount=0 so resume
KeReleaseSemaphore(&t_data->SuspendSemaphore, 0, 1, FALSE);
}
t_data = t_data->next; //next thread
}
}
ExReleaseResourceLite(&ProcesslistR);
}