Ai
1 Star 0 Fork 0

phy0292/cheat-engine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
cetc.c 18.67 KB
一键复制 编辑 原始数据 按行查看 历史
cheatengine@gmail.com 提交于 2011-07-05 03:53 +08:00 . No commit message
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
#ifndef CETC
ALLERT! DO NOT PUT THIS FILE IN THE STANDARD CE DISTRIBUTION
#endif
#include "ntifs.h"
#include "extraimports.h"
#include "memscan.h"
#include "tdiwrapper.h"
#include <windef.h>
#include "rootkit.h"
VOID CETC_CORE(IN PVOID StartContext)
{
KLOCK_QUEUE_HANDLE lqh;
PEPROCESS ActivePEPROCESS=NULL;
InitServer();
if (FileObjectConnection!=NULL)
{
StopListener=FALSE;
while (!StopListener)
{
AddressListEntries=0;
DbgPrint("Start listening\n");
if (Listen())
{
ULONG DataSent=0;
BOOLEAN PasswordCorrect=FALSE;
int i;
unsigned char command;
char a;
char *buffer;
char defaultpass[9]="defaultpw";
DbgPrint("Listen=success\n");
connected=TRUE;
DbgPrint("Waiting for password\n");
while ((!PasswordCorrect) && (connected))
{
if (Receive(&command,1))
{
if (command==CS_PASSWORD) //only one possible so use a if
{
if (Receive(&a,1)) //length
{
if (a!=0)
{
buffer=ExAllocatePoolWithTag(NonPagedPool,(ULONG)a,0);
DbgPrint("received passsize=%d\n",a);
//allocate a buffer big enough to receive the password
if (Receive(buffer,a))
{
if (a<=9)
{
for (i=0; i<a; i++)
if (buffer[i]!=defaultpass[i])
break;
PasswordCorrect=(i==9);
}
if (PasswordCorrect)
DbgPrint("Password correct\n");
else
DbgPrint("Password incorrect\n");
}
ExFreePool(buffer);
}
}
}
}
}
if (!connected)
continue;
DataSent=0;
while (connected)
{
DbgPrint("Going to read a new command\n");
if (Receive(&command,1))
{
DbgPrint("command=%d\n",command);
switch (command)
{
case CS_SetTimerSpeed: //(freezeinterval:word)
{
WORD fi;
DbgPrint("Set Timer Speed\n");
Receive(&fi,2);
FreezeInterval.QuadPart=fi*-10000;
//-50000000=5 seconds=5000 ms
//-5000000=500 ms
break;
}
case CS_KERNELDATA:
{
DbgPrint("Kerneldata received\n");
Receive(&ActiveLinkOffset,4);
Receive(&ProcessNameOffset,4);
Receive(&DebugportOffset,4);
Receive(&PIDOffset,4);
break;
}
case CS_SetConfig:
{
//UseDebugRegs:byte;UseDBKQueryMemoryRegion:byte;UseDBKReadWriteMemory:byte;UseDBKOpenProcess:byte)
DbgPrint("SetConfig\n");
Receive(&MemscanOptions.ShowAsSigned,1);
Receive(&MemscanOptions.BinariesAsDecimal,1);
Receive(&MemscanOptions.max,2);
Receive(&MemscanOptions.buffersize,4);
Receive(&MemscanOptions.skip_page_no_cache,1);
Receive(&MemscanOptions.UseDebugRegs,1);
Receive(&MemscanOptions.UseDBKQueryMemoryRegion,1);
Receive(&MemscanOptions.UseDBKReadWriteMemory,1);
Receive(&MemscanOptions.UseDBKOpenProcess,1);
break;
}
case CS_PROCESSLIST:
{
BOOLEAN First;
PEPROCESS pf,p;
KAPC_STATE apc_state;
int pos=0;
char *processname;
char EndList[1]={SC_ENDPROCESSLIST};
char* TempBuffer=ExAllocatePoolWithTag(NonPagedPool,512,0);
__try
{
DbgPrint("ProcessList\n");
RtlZeroMemory(&apc_state,sizeof(apc_state));
pf=PsGetCurrentProcess();
p=pf;
First=TRUE;
while (((p!=NULL) && (p!=pf)) || (First))
{
First=FALSE;
processname=(PVOID)p;
processname=&processname[ProcessNameOffset];
DbgPrint("peprocess=%p processname=%s\n",p,processname);
//get size of processname (less than 32 bytes)
for (i=0; (i<32)&&(processname[i]!=0) ; i++) ;
//(processid:dword;stringlength:byte;processname:array of char)
if ((pos+6+i)<512)
{
//add it to the buffer
TempBuffer[pos]=SC_PROCESSLISTITEM;
pos++;
*(PULONG)(&TempBuffer[pos])=(ULONG)p;
pos+=4;
TempBuffer[pos]=(UCHAR)i;
pos++;
RtlCopyMemory(&TempBuffer[pos],processname,i);
pos+=i;
}
else
{
//buffer is too full, so send it, and start filling again
Send(TempBuffer,pos);
pos=0;
}
p=(PEPROCESS)(*(PULONG)((ULONG)p+ActiveLinkOffset)-ActiveLinkOffset);
}
if (pos>0)
Send(TempBuffer,pos);
ExFreePool(TempBuffer);
Send(EndList,1);
}
__except(1)
{
DbgPrint("Error in processlist\n");
}
break;
}
case CS_OPENPROCESS:
{
unsigned char openedprocess=SC_OPENPROCESSSUCCESS;
DbgPrint("Open Process\n");
if (Receive(&ActivePEPROCESS,4))
DbgPrint("ActivePEPROCESS=%p\n",ActivePEPROCESS);
else
DbgPrint("OpenProcess failed");
Send(&openedprocess,1);
break;
}
case CS_CancelScan:
{
CurrentScan.scanning=FALSE;
addressfile=0;
valuefile=0;
}
case CS_FirstScan:
{
//start,stop:dword;vartype:byte;Scantype:byte;scanvaluelength:byte;scanvalue:array of bytes;scanoptions:byte
DWORD start;
DWORD stop;
BYTE VarType;
BYTE Scantype;
BYTE ScanvalueSize;
char *scanvalue;
BYTE ScanOptions;
Receive(&start,4);
Receive(&stop,4);
Receive(&VarType,1);
Receive(&Scantype,1);
Receive(&ScanvalueSize,1);
scanvalue=ExAllocatePoolWithTag(NonPagedPool,ScanvalueSize,0);
if (scanvalue!=NULL)
{
__try
{
Receive(scanvalue,ScanvalueSize);
Receive(&ScanOptions,1);
//all parameters received, start the scan....
DbgPrint("start=%x stop=%x vartype=%d scantype=%d scanvaluesize=%d scanoptions=%d\n",start,stop,VarType,Scantype,ScanvalueSize);
FirstScan(ActivePEPROCESS,start,stop,VarType,Scantype,ScanvalueSize,scanvalue,ScanOptions);
}
__finally
{
ExFreePool(scanvalue);
}
}
break;
}
case CS_ReadProcessMemory:
{
//ReadProcessMemory(address:dword; length: word);
BOOLEAN ok=FALSE;
ULONG address;
WORD size;
WORD bytesread=0;
char* outputbuffer;
DbgPrint("ReadProcessMemory\n");
Receive(&address,4);
Receive(&size,2);
DbgPrint("address=%x size=%d\n",address,size);
//output SC_ReadProcessMemoryResult(successboolean: byte; actualread: word; bytesread: array of byte)
//allocate memory to hold the data
outputbuffer=ExAllocatePoolWithTag(NonPagedPool,(ULONG)size+4,0);
if (outputbuffer!=NULL)
{
DbgPrint("Allocated memory\n");
DbgPrint("ActivePEPROCESS=%p\n",ActivePEPROCESS);
ok=ReadProcessMemory(0,ActivePEPROCESS,(PVOID)address,size,(PVOID)&outputbuffer[4]);
if (ok)
DbgPrint("ReadProcessMemory successful\n");
else
DbgPrint("ReadProcessMemory failed\n");
bytesread=ok ? (WORD)size : 0;
outputbuffer[0]=SC_ReadProcessMemoryResult;
outputbuffer[1]=ok ? 1:0;
*(PWORD)(&outputbuffer[2])=bytesread;
Send(outputbuffer,bytesread+4);
ExFreePool(outputbuffer);
}
break;
}
case CS_WriteProcessMemory:
{
//WriteProcessMemory(address:dword; length: word; bytes: array of byte);
BOOLEAN ok=FALSE;
ULONG address;
WORD size;
WORD bytesread=0;
char* inputbuffer;
DbgPrint("WriteProcessMemory\n");
Receive(&address,4);
Receive(&size,2);
DbgPrint("address=%x size=%d\n",address,size);
inputbuffer=ExAllocatePoolWithTag(NonPagedPool, (size<=4) ? 4 : (ULONG)size,0);
if (inputbuffer!=NULL)
{
Receive(inputbuffer,size);
ok=WriteProcessMemory(0,ActivePEPROCESS,(PVOID)address,size,inputbuffer);
if (ok)
DbgPrint("WriteProcessMemory successful\n");
else
DbgPrint("WriteProcessMemory failed\n");
inputbuffer[0]=SC_WriteProcessMemoryResult;
inputbuffer[1]=ok ? 1:0;
*(PWORD)(&inputbuffer[2])=ok ? (WORD)size: 0;
Send(inputbuffer,4);
ExFreePool(inputbuffer);
}
break;
}
case CS_ClearRecordList:
{
AddressListEntries=0;
break;
}
case CS_UpdateList: //update list(start:word stop:word) //request a updated list
{
WORD start,stop;
WORD i,j;
DWORD buffersize=1,pos;
char *buffer;
ADDRESSENTRY *templist;
DbgPrint("UpdateList\n");
Receive(&start,2);
Receive(&stop,2);
DbgPrint("start=%d\nstop=%d\n",start,stop);
//read the addresses and send the data to the client
start=start>AddressListEntries-1 ? 0:start;
stop=stop>AddressListEntries-1 ? AddressListEntries:stop;
DbgPrint("After adjusting:\nstart=%d\nstop=%d\n",start,stop);
templist=ExAllocatePoolWithTag(NonPagedPool, (start-stop+1)*sizeof(ADDRESSENTRY),0);
if (templist!=NULL)
{
j=0;
for (i=start;i<stop;i++)
{
buffersize+=AddressList[i].size+4;
templist[j]=AddressList[i];
j++;
}
}
if (templist==NULL)
break;
DbgPrint("Total buffer to read=%d\n",buffersize);
buffer=ExAllocatePoolWithTag(NonPagedPool, buffersize+1,0);
if (buffer!=NULL)
{
DbgPrint("Allocated buffer\n");
buffer[0]=SC_ValueList;
pos=1;
for (i=start;i<stop;i++)
{
DbgPrint("pos=%d\n",pos);
DbgPrint("i=%d\n",i);
DbgPrint("Address=%x\nSize=%x\n",AddressList[i].Address,AddressList[i].size);
*(PWORD)&buffer[pos]=i;
if (ReadProcessMemory(0,ActivePEPROCESS,(PVOID)AddressList[i].Address,(DWORD)AddressList[i].size,&buffer[pos+4]))
{
DbgPrint("Readable\n");
*(PWORD)&buffer[pos+2]=AddressList[i].size;
DbgPrint("Bufferdata:\n");
DbgPrint("Itemnr=%d\n",*(PWORD)&buffer[pos]);
DbgPrint("read=%d bytes\n",*(PWORD)&buffer[pos+2]);
pos+=4+AddressList[i].size;
}
else
{
DbgPrint("Unreadable\n");
*(PWORD)&buffer[pos+2]=0;
pos+=4;
}
//pos+=AddressList[i].size;
}
DbgPrint("Sending data to client\n");
buffer[pos]=SC_ValueListDone; //also tell it's the end of the list (safety first....)
Send(buffer,pos+1);
ExFreePool(buffer);
}
else DbgPrint("Failed to allocate buffer\n");
DbgPrint("End of UpdateList\n");
break;
}
case CS_FreezeAddress:
{
//Freeze Address (recid: word)
WORD recid;
Receive(&recid,2);
if (recid<AddressListEntries)
{
if (AddressList[i].frozen)
{
//cleanup
KeAcquireInStackQueuedSpinLock(&AddressListSpinlock,&lqh);
AddressList[i].frozen=FALSE;
KeReleaseInStackQueuedSpinLock(&lqh);
//freemem
if (AddressList[i].frozendata!=NULL)
ExFreePool(AddressList[i].frozendata);
}
AddressList[i].frozendata=ExAllocatePoolWithTag(NonPagedPool, AddressList[i].size,0);
AddressList[i].frozen=TRUE; //no spinlock required here
}
break;
}
case CS_AddAddress: //AddAddress(address:dword ,size:byte)
{
ADDRESSENTRY x;
ADDRESSENTRY *oldlist=NULL;
BYTE recordreceived=SC_AddressReceived;
Receive(&(x.Address),4);
Receive(&(x.size),1);
x.frozen=FALSE;
x.frozendata=NULL;
DbgPrint("Address=%x - size=%d\n",x.Address,x.size);
KeAcquireInStackQueuedSpinLock(&AddressListSpinlock,&lqh);
//add to the list
//first check if there is already a list or not
if (AddressList==NULL)
{
DbgPrint("Allocating Addresslist buffer\n");
AddressListEntries=0;
AddressListSize=0;
//allocate a buffer to store the list
AddressList=ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE,0);
if (AddressList!=NULL)
{
DbgPrint("Allocated a AddressList. Setting AddressListSize to PAGE_SIZE(%d)\n",PAGE_SIZE);
AddressListSize=PAGE_SIZE;
DbgPrint("AddressListSize=%d\n",AddressListSize);
}
else
{
DbgPrint("couldn\'t allocate buffer");
break;
}
} else DbgPrint("AddressList was already allocated. AddressListSize=%d\n",AddressListSize);
if (AddressListSize<(AddressListEntries+1)*sizeof(ADDRESSENTRY))
{
DbgPrint("AddressListSize too small, allocating more memory\n");
//allocate a new buffer
oldlist=AddressList;
AddressList=ExAllocatePoolWithTag(NonPagedPool,AddressListSize+PAGE_SIZE,0);
if (AddressList!=NULL)
{
DbgPrint("Copying old list to new list\n");
RtlCopyMemory(AddressList,oldlist,AddressListSize);
AddressListSize+=PAGE_SIZE;
ExFreePool(oldlist);
DbgPrint("Allocated more memory and copied the list\n");
}
else
{
DbgPrint("Couldn\'t reallocate list\n");
AddressList=oldlist;
break;
}
}
DbgPrint("Going to add entry\n");
AddressList[AddressListEntries]=x;
AddressListEntries++;
KeReleaseInStackQueuedSpinLock(&lqh);
DbgPrint("Entry added\n");
DbgPrint("AddressListSize=%d\nAddressListEntries=%d\n",AddressListSize,AddressListEntries);
Send(&recordreceived,1);
break;
}
case CS_ChangeValueOfAddress:
{
//change the address of recid x (recid: dword; bufsize:byte; buf: arrau of byte)
WORD recid;
BYTE bufsize;
char *buf;
Receive(&recid,2);
Receive(&bufsize,1);
if (bufsize!=0)
{
buf=(NonPagedPool,bufsize,0);
Receive(buf,bufsize);
if (AddressList[recid].frozen)
{
RtlCopyMemory(AddressList[recid].frozendata,buf,bufsize);
}
WriteProcessMemory(0,ActivePEPROCESS,(PVOID)AddressList[recid].Address,bufsize,buf);
ExFreePool(buf);
}
break;
}
case CS_TERMINATESERVER:
{
DbgPrint("Terminating server\n");
Disconnect();
StopListener=TRUE;
break;
}
}
}
}
}
else
{
LARGE_INTEGER timeout;
KEVENT WaitEvent;
//wait a few seconds and try again
KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE);
DbgPrint("waiting\n");
timeout.QuadPart=-50000000; //5 seconds
KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, &timeout);
DbgPrint("returned\n");
DbgPrint("Error while listening\n");
Disconnect();
//break; //error while listening
}
}
}
StopListener=TRUE; //in case i got out using a break (e.g bug...)
//free the AddressList
if (AddressList!=NULL)
ExFreePool(AddressList);
DbgPrint("Exit thread\n");
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
void InitializeCETC(void)
{
OBJECT_ATTRIBUTES oaCreateThread;
HANDLE th;
AddressList=NULL;
AddressListSize=0;
AddressListEntries=0;
ProcessNameOffset=372;
ActiveLinkOffset=136;
DebugportOffset=188;
StopListener=FALSE;
CurrentScan.process=NULL; //indicates there is no scan
CurrentScan.scanning=FALSE;
CurrentScan.scanvalue=NULL;
KeInitializeEvent(&ListenerStopped, NotificationEvent, FALSE);
KeInitializeSpinLock(&AddressListSpinlock);
{
OBJECT_ATTRIBUTES oaSendEvent;
InitializeObjectAttributes(&oaSendEvent, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
if NT_SUCCESS(ZwCreateEvent(&SendEvent,0,&oaSendEvent,SynchronizationEvent,TRUE))
DbgPrint("Created the event\n");
else
DbgPrint("Failed to create the event\n");
}
addressfile=0;
valuefile=0;
DbgPrint("Spawning thread\n");
th=0;
InitializeObjectAttributes(&oaCreateThread, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
PsCreateSystemThread(&th,0L,&oaCreateThread,NULL,NULL,CETC_CORE,NULL);
if (th!=NULL)
ZwClose(th);
}
NTSTATUS UnloadCETC(void)
{
NTSTATUS ntStatus;
DbgPrint("Unload CE-TC\n");
StopListener=TRUE;
if (FileObjectConnection!=NULL)
{
ntStatus=TdiFuncs_DisAssociateTransportAndConnection(FileObjectConnection);
if (NT_SUCCESS(ntStatus))
DbgPrint("Disassociating worked\n");
else
DbgPrint("Disassociating Failed!\n");
}
if (FileObjectConnection!=NULL)
{
DbgPrint("Dereferencing Connection Object\n");
ObDereferenceObject(FileObjectConnection);
}
if (TdiHandleConnection!=NULL)
{
DbgPrint("Dereferencing Connection Handle\n");
ZwClose(TdiHandleConnection);
}
if (FileObjectTransport!=NULL)
{
DbgPrint("Dereferencing Transport Object\n");
ObDereferenceObject(FileObjectTransport);
}
if (TdiHandleTransport!=NULL)
{
DbgPrint("Dereferencing Transport handle\n");
ZwClose(TdiHandleTransport);
}
ntStatus=ZwWaitForSingleObject(ListenThread,FALSE,NULL);
if (NT_SUCCESS(ntStatus))
DbgPrint("Failed to wait for the thread\n");
return ntStatus;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/phy0292/cheat-engine.git
git@gitee.com:phy0292/cheat-engine.git
phy0292
cheat-engine
cheat-engine
master

搜索帮助