Jun 14, 2006 10:26
>_O# This is eating MY BRAIN RAWRRRRRRR
unit DBK32functions;
interface
uses windows,sysutils,winsvc,psapi,classes,types;
//xp sp2
//ThreadsProcess=220
//ThreadListEntry=22c
const currentversion=2000007;
const FILE_ANY_ACCESS=0;
const FILE_SPECIAL_ACCESS=FILE_ANY_ACCESS;
const FILE_READ_ACCESS=$0001;
const FILE_WRITE_ACCESS=$0002;
const METHOD_BUFFERED= 0;
const METHOD_IN_DIRECT= 1;
const METHOD_OUT_DIRECT= 2;
const METHOD_NEITHER= 3;
const FILE_DEVICE_UNKNOWN=$00000022;
const IOCTL_UNKNOWN_BASE=FILE_DEVICE_UNKNOWN;
type thandlelist=record
processhandle: thandle;
processid: dword;
validhandle: boolean;
end;
type TClient_ID=record
processid: thandle;
threadid: thandle;
end;
type PClient_ID=^TClient_ID;
type THookIDTThread=class(tthread)
public
cpunr: byte;
done: boolean;
succeeded: boolean;
procedure execute; override;
end;
type THookIDTConstantly=class(tthread)
public
procedure execute; override;
end;
var cpuidt: array of dword;
type TGetIDTThread=class(tthread)
public
cpunr: byte;
done: boolean;
procedure execute; override;
end;
var hdevice: thandle; //handle to my the device driver
handlelist: array of thandlelist;
driverloc: string;
iamprotected:boolean;
SDTShadow: DWORD;
debugport,processname: dword;
ThreadsProcess,ThreadListEntry:dword;
processevent,threadevent:thandle;
ownprocess: thandle; //needed for simple kernelmemory access
Successfullyloaded:boolean;
usealternatedebugmethod: boolean;
function CTL_CODE(DeviceType, Func, Method, Access : integer) : integer;
function tehuberITSKOK(hProcess:THandle):BOOL; stdcall;
Function {OpenProcess}tehuberPO(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwProcessId:DWORD):THANDLE; stdcall;
Function {OpenThread}tehuberTO(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwThreadId:DWORD):THANDLE; stdcall;
function {ReadProcessMemory}tehuberRP(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
function {WriteProcessMemory}tehuberWP(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
function {VirtualQueryEx}tehuberVQ(hProcess: THandle; address: pointer; var mbi: _MEMORY_BASIC_INFORMATION; bufsize: DWORD):dword; stdcall;
Function {NtOpenProcess}tehuberNO(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
Function {NtOpenThread}NtOT(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
Function {VirtualAllocEx}tehuberVA(hProcess: THandle; lpAddress: Pointer; dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
Function tehuberPAC(threadid: dword; lpStartAddress: TFNAPCProc): THandle; stdcall;
Function tehuberGETPPROCESS(ProcessID: dword):dword; stdcall;
Function tehuberGETPTHREAD(Threadid: dword):dword; stdcall;
function GetDebugportOffset: DWORD; stdcall;
function GetProcessnameOffset: dword; stdcall;
function tehuberGTPO: dword; stdcall;
function GetThreadListEntryOffset: dword; stdcall;
function tehuberREADPMEM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
function tehuberWRITEPMEM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
function tehuberGETPADR(hProcess:THandle;lpBaseAddress:pointer;var Address:int64): BOOL; stdcall;
function tehuberPROTECT(ProtectedProcessID: dword; denylist,globaldenylist:BOOL;list:pchar; listsize:dword):BOOL; stdcall; //or should I give it a array of processid's?
function tehuberSTOPIT:bool; stdcall;
function tehuberGET4:DWORD; stdcall;
function tehuberGET3(hProcess:THANDLE;var CR3:DWORD):BOOL; stdcall;
function tehuberSET3(hProcess:THANDLE;CR3: DWORD):BOOL; stdcall;
function tehuberGETSTD:DWORD; stdcall;
function tehuberGETSTDS:DWORD; stdcall;
function tehuberSADM(var int1apihook:dword; var OriginalInt1handler:dword):BOOL; stdcall;
function tehuberGADM:BOOL; stdcall;
function tehuberDEBUG(processid:dword;address:DWORD;size: byte;debugtype:byte):BOOL; stdcall;
function tehuberSTOPDEBUG:BOOL; stdcall;
function tehuberSTOPRCHG(regnr:integer):BOOL; stdcall;
function tehuberGETBUGDATA(Buffer: pointer):integer; stdcall;
function ChangeRegOnBP(Processid:dword; address: dword; debugreg: integer; changeEAX,changeEBX,changeECX,changeEDX,changeESI,changeEDI,changeEBP,changeESP,changeEIP,changeCF,changePF,changeAF,changeZF,changeSF,changeOF:BOOLEAN; newEAX,newEBX,newECX,newEDX,newESI,newEDI,newEBP,newESP,newEIP:DWORD; newCF,newPF,newAF,newZF,newSF,newOF:BOOLEAN):BOOLEAN; stdcall;
function StartProcessWatch:BOOL;stdcall;
function WaitForProcessListData(processpointer:pointer;threadpointer:pointer;timeout:dword):dword; stdcall;
function GetProcessNameFromPEProcess(peprocess:dword; buffer:pchar;buffersize:dword):integer; stdcall;
function GetProcessNameFromID(processid:dword; buffer:pointer;buffersize:dword):integer; stdcall;
function MakeWritable(Address,Size:dword;copyonwrite:boolean): boolean; stdcall;
function RewriteKernel32:boolean; stdcall;
function RestoreKernel32:boolean; stdcall;
function InitializeDriver(Address,size:dword):BOOL; stdcall;
function GetWin32KAddress(var address:DWORD;var size:dworD):boolean;
function GetDriverVersion: dword;
function GetIDTCurrentThread:dword; stdcall;
function GetIDTs(idtstore: pointer; maxidts: integer):integer; stdcall;
function GetLoadedState: BOOLEAN; stdcall;
function test: boolean; stdcall;
procedure useIOCTL(use: boolean); stdcall;
function DBKSuspendThread(ThreadID:dword):boolean; stdcall;
function DBKResumeThread(ThreadID:dword):boolean; stdcall;
function DBKSuspendProcess(ProcessID:dword):boolean; stdcall;
function DBKResumeProcess(ProcessID:dword):boolean; stdcall;
var hooker: THookIDTConstantly;
kernel32dll: thandle;
ioctl: boolean;
implementation
procedure FSC;
asm
mov edx,esp
sysenter
end;
function GetLoadedState: BOOLEAN; stdcall;
begin
result:=(hdevice<>INVALID_HANDLE_VALUE) and Successfullyloaded;
end;
procedure useIOCTL(use: boolean); stdcall;
begin
ioctl:=use;
end;
function Test:boolean; stdcall;
{$W+}
procedure test_noioctl(p1:integer; p2: integer); stdcall;
asm
pop ebp //used parameters so the stupid compiler added a push ebp
mov eax,$2000
call fsc
ret 8
end;
{$W-}
var cc,br: dword;
threadid: dword;
begin
result:=true;
if ioctl then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0804, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@threadid,sizeof(threadid),nil,0,br,nil);
end
else
begin
test_noioctl(1,2);
end;
end;
function GetIDTCurrentThread:dword;
var cc,br: dword;
idtdescriptor: packed record
wLimit:word;
vector: dword;
end;
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080f, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
deviceiocontrol(hdevice,cc,nil,0,@idtdescriptor,6,br,nil);
result:=idtdescriptor.vector;
end else result:=0;
end;
procedure TGetIDTThread.execute;
begin
try
cpuidt[cpunr]:=getidtcurrentthread;
finally
done:=true;
end;
end;
function GetIDTs(idtstore: pointer; maxidts: integer):integer; stdcall;
var ec: dword;
i:integer;
cpunr,PA,SA:Dword;
cpunr2:byte;
begin
//max idt's should be 32, but may be less if you('re a retard!) don't want to allocate the enormous ammount of 32*4=128 bytes
setlength(cpuidt,0);
result:=0; //0 idt's returned
if hdevice<>INVALID_HANDLE_VALUE then
begin
GetProcessAffinityMask(getcurrentprocess,PA,SA);
//first hook the interrupts if needed
cpunr2:=0;
cpunr:=1;
while (cpunr<=PA) do
begin
if ((cpunr) and PA)>0 then
begin
setlength(cpuidt,length(cpuidt)+1);
SetProcessAffinityMask(getcurrentprocess,cpunr);
//create a new thread. (Gues on what cpu it will run at...)
with TGetIDTThread.Create(true) do
begin
try
cpunr:=cpunr2;
resume;
while not done do sleep(20); //the sleep should also cause a taskswitch but I'm not 100% sure
finally
free;
end;
end;
end;
if cpunr=$80000000 then break;
inc(cpunr,cpunr);
inc(cpunr2);//next cpu
end;
SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it
for i:=0 to length(cpuidt)-1 do
TCardinalDynArray(idtstore)[i]:=cpuidt[i];
result:=length(cpuidt);
end;
end;
procedure THookIDTThread.execute;
var cc,br: dword;
begin
try
// outputdebugstring('hooking IDT');
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0810, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
succeeded:=deviceiocontrol(hdevice,cc,@cpunr,1,@cpunr,0,br,nil);
finally
done:=true;
end;
end;
procedure THookIDTConstantly.execute;
var input:TInput;
br,cc: dword;
i:integer;
cpunr,PA,SA:Dword;
cpunr2:byte;
begin
freeonterminate:=true;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0810, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
while not terminated do
begin
// outputdebugstring('writing the idt');
GetProcessAffinityMask(getcurrentprocess,PA,SA);
cpunr2:=0;
cpunr:=1;
while (cpunr<=PA) do
begin
if ((cpunr) and PA)>0 then
begin
SetProcessAffinityMask(getcurrentprocess,cpunr);
//create a new thread. (Gues on what cpu it will run at...)
with THookIDTThread.Create(true) do
begin
try
cpunr:=cpunr2;
resume;
while not done do sleep(10); //the sleep should also cause a taskswitch but I'm not 100% sure
finally
free;
end;
end;
end;
if cpunr=$80000000 then break;
inc(cpunr,cpunr);
inc(cpunr2);
end;
SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it
sleep(5000); //wait a while before rewriting
end;
end;
end;
function GetProcessNameFromPEProcess(peprocess:dword; buffer:pchar;buffersize:dword):integer; stdcall;
var ar:dword;
i:integer;
begin
if buffersize>16 then buffersize:=16;
result:=-1;
if processname=0 then exit;
if (hdevice<>INVALID_HANDLE_VALUE) and (ownprocess<>0) then
begin
if tehuberRP(ownprocess,pointer(peprocess+processname),buffer,buffersize,ar) then
begin
for i:=0 to buffersize-1 do
if buffer[i]=#0 then
begin
result:=i+i;
exit;
end;
end;
end;
end;
function tehuberGET4:DWORD; stdcall;
var x,res,cc:dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0817, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@res,4,@res,4,x,nil) then
result:=res;
end;
end;
function GetDriverVersion:dword;
var x,res,cc:dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0816, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@res,4,@res,4,x,nil) then
result:=res;
end;
end;
function GetProcessNameFromID(processid:dword; buffer:pointer;buffersize:dword):integer; stdcall;
begin
//just a simple stub
result:=GetProcessNameFromPEProcess(tehuberGETPPROCESS(processid),buffer,buffersize);
end;
function tehuberGTPO: dword; stdcall;
begin
result:=ThreadsProcess;
end;
function GetThreadListEntryOffset: dword; stdcall;
begin
result:=ThreadListEntry;
end;
function GetProcessnameOffset: dword; stdcall;
begin
result:=processname;
end;
function GetDebugportOffset: DWORD; stdcall;
begin
result:=debugport;
end;
function tehuberGETSTDS:DWORD; stdcall;
begin
result:=SDTShadow;
end;
function tehuberGETSTD:DWORD; stdcall;
var res,x,cc:dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080c, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@res,4,@res,4,x,nil) then
result:=res;
end;
end;
function tehuberGET3(hProcess:THANDLE;var CR3:DWORD):BOOL; stdcall;
var cc:dword;
x,y:dword;
i: integer;
begin
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080a, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
x:=handlelist[i].processid;
result:=deviceiocontrol(hdevice,cc,@x,4,@x,4,y,nil);
if result then CR3:=x else cr3:=$11223344;
end;
end;
end;
function tehuberSET3(hProcess:THANDLE;CR3: DWORD):BOOL; stdcall;
var cc:dword;
ar: array [0..7] of byte;
x:dword;
i: integer;
begin
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080b, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
pdword(@ar[0])^:=handlelist[i].processid;
pdword(@ar[4])^:=CR3;
result:=deviceiocontrol(hdevice,cc,@ar[0],4,@ar[0],4,x,nil);
end;
end;
end;
function tehuberPROTECT(ProtectedProcessID: dword; denylist,globaldenylist:BOOL;list:pchar; listsize:dword):BOOL; stdcall; //or should I give it a array of processid's?
type tinput=record
processid: dword;
DenyList: DWORD;
GlobalDenyList: DWORD;
ListSize:DWORD;
end;
var cc,x: dword;
input: ^tinput;
win32kaddress,win32size:dword;
begin
OutputDebugString('Zomg the protector has been summoned');
result:=false;
if GetWin32KAddress(win32kAddress,win32size) then
if not InitializeDriver(win32kAddress,win32size) then exit;
if hdevice<>INVALID_HANDLE_VALUE then
begin
getmem(input,sizeof(tinput)+listsize);
try
input.processid:=ProtectedProcessID;
if denylist then
input.DenyList:=1 else input.DenyList:=0;
if globaldenylist then
input.GlobalDenyList:=1 else input.GlobalDenyList:=0;
input.ListSize:=listsize;
copymemory(pointer(dword(@input.listsize)+4),list,listsize);
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0809, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,input,sizeof(tinput)+listsize,input,4,x,nil);
finally
freemem(input);
end;
Iamprotected:=result;
end;
end;
function tehuberSTOPIT:bool; stdcall;
var cc,x: dword;
begin
result:=false;
if (hdevice<>INVALID_HANDLE_VALUE) and (Iamprotected) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080e, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,0,@x,0,x,nil);
end;
end;
function DBKSuspendThread(ThreadID:dword):boolean; stdcall;
var cc,x: dword;
begin
outputdebugstring('DBKSuspendThread');
result:=false;
x:=ThreadId;
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0822, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,sizeof(x),nil,0,x,nil);
end;
end;
function DBKResumeThread(ThreadID:dword):boolean; stdcall;
var cc,x: dword;
begin
outputdebugstring('DBKResumeThread');
result:=false;
x:=threadid;
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0823, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,sizeof(x),nil,0,x,nil);
end;
end;
function DBKSuspendProcess(ProcessID:dword):boolean; stdcall;
var cc,x: dword;
begin
result:=false;
x:=ProcessID;
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0824, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,sizeof(x),nil,0,x,nil);
end;
end;
function DBKResumeProcess(ProcessID:dword):boolean; stdcall;
var cc,x: dword;
begin
result:=false;
x:=ProcessID;
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0825, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,sizeof(x),nil,0,x,nil);
end;
end;
function tehuberGETPADR(hProcess:THandle;lpBaseAddress:pointer;var Address:int64): BOOL; stdcall;
type TInputstruct=record
ProcessID: dword;
BaseAddress: dword;
end;
var cc: dword;
input: TInputStruct;
physicaladdress: int64 absolute input;
x: dword;
i: integer;
begin
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0808, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
input.ProcessID:=handlelist[i].processid;
input.BaseAddress:=dword(lpBaseAddresS);
result:=deviceiocontrol(hdevice,cc,@input,8,@input,8,x,nil);
if result then address:=physicaladdress else address:=0;
end;
end;
end;
function tehuberWRITEPMEM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
type TInputstruct=record
startaddress: dword;
bytestowrite: dword;
end;
var ao: array [0..511] of byte;
input: TInputstruct absolute ao[0];
cc:dword;
i: integer;
ok: boolean;
br: dword;
mempointer: dword;
bufpointer: dword;
bufpointer2: pointer;
towrite: dword;
begin
result:=false;
NumberOfByteswritten:=0;
//find the hprocess in the handlelist, if it isn't use the normal method (I could of course use NtQueryProcessInformation but it's undocumented and I'm too lazy to dig it up
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0807, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
mempointer:=dword(lpBaseAddress);
bufpointer:=dword(lpbuffer);
ok:=true;
while ok do
begin
zeromemory(@ao[0],512);
if nSize-NumberOfByteswritten>=(512-sizeof(TInputstruct)) then
towrite:=(512-sizeof(TInputstruct))
else
towrite:=nSize-NumberOfByteswritten;
input.bytestowrite:=towrite;
input.startaddress:=mempointer;
bufpointer2:=pointer(bufpointer);
copymemory(@ao[sizeof(tinputstruct)],bufpointer2,towrite);
if not deviceiocontrol(hdevice,cc,@ao[0],512,@ao[0],512,br,nil) then exit;
inc(mempointer,towrite);
inc(bufpointer,towrite);
inc(NumberOfByteswritten,towrite);
if NumberOfByteswritten=nSize then
begin
result:=true;
exit;
end;
end;
end;
end;
function tehuberREADPMEM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
type TInputstruct=record
startaddress: dword;
bytestoread: dword
end;
var ao: array [0..600] of byte;
input: TInputstruct absolute ao[0];
br: dword;
cc:dword;
ok:boolean;
toread:dword;
toread2: dword;
mempointeR:dword;
bufpointer:dword;
begin
//processhandle is just there for compatibility in case I want to quickly wrap it over read/writeprocessmemory
result:=false;
numberofbytesread:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0806, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
toread:=nSize;
mempointer:=dword(lpBaseAddress);
bufpointer:=dword(lpBuffer);
ok:=true;
while ok and (toread>0) do
begin
if toread>512 then
toread2:=512
else
toread2:=toread;
dec(toread,toread2);
input.bytestoread:=toread2;
input.startaddress:=mempointer;
if deviceiocontrol(hdevice,cc,@ao[0],512,@ao[0],512,br,nil) then
begin
copymemory(pointer(bufpointer),@ao[0],toread2);
inc(numberofbytesread,toread2);
inc(bufpointer,toread2);
mempointer:=mempointer+toread2;
end
else
ok:=false;
end;
result:=ok;
end;
end;
Function tehuberGETPTHREAD(Threadid: dword):dword; stdcall;
var cc:dword;
x: dword;
pethread: dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0821, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
pethread:=threadid;
if deviceiocontrol(hdevice,cc,@pethread,4,@pethread,4,x,nil) then result:=pethread;
end;
end;
Function tehuberGETPPROCESS(ProcessID: dword):dword; stdcall;
var cc:dword;
x: dword;
peprocess: dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0805, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
peprocess:=processid;
if deviceiocontrol(hdevice,cc,@peprocess,4,@peprocess,4,x,nil) then result:=peprocess else result:=0;
end;
end;
function tehuberITSKOK(hProcess:THandle):BOOL; stdcall;
var i: integer;
begin
result:=false;
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
result:=handlelist[i].validhandle;
exit;
end;
end;
function {ReadProcessMemory}tehuberRP(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
type TInputstruct=record
processid: dword;
startaddress: dword;
bytestoread: word;
end;
var ao: array [0..600] of byte; //give it some space
input: TInputstruct absolute ao[0];
cc:dword;
i: integer;
ok: boolean;
br: dword;
mempointer: dword;
bufpointer: dword;
bufpointer2: pointer;
toread: dword;
begin
result:=false;
numberofbytesread:=0;
//find the hprocess in the handlelist, if it isn't use the normal method (I could of course use NtQueryProcessInformation but it's undocumented and I'm too lazy to dig it up
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0800, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
mempointer:=dword(lpBaseAddress);
bufpointer:=dword(lpbuffer);
ok:=true;
while ok do
begin
input.processid:=handlelist[i].processid;
if nSize-numberofbytesread>=512 then
toread:=512
else
toread:=nSize-numberofbytesread;
input.bytestoread:=toread;
input.startaddress:=mempointer;
if deviceiocontrol(hdevice,cc,@ao[0],512,@ao[0],512,br,nil) then
begin
bufpointer2:=pointer(bufpointer);
copymemory(bufpointer2,@ao[0],toread);
//no check if it works or try except, it's up to the (retarded) user to do it right
end
else
begin
exit;
end;
inc(mempointer,toread);
inc(bufpointer,toread);
inc(numberofbytesread,toread);
if numberofbytesread=nSize then
begin
result:=true;
exit;
end;
end;
exit;
end else if not handlelist[i].validhandle then exit; //else use the normal method...
end;
//not found so ....
result:=windows.ReadProcessMemory(hProcess,lpBaseAddress,lpBuffer,nSize,NumberOfBytesRead);
end;
function {WriteProcessMemory}tehuberWP(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
type TInputstruct=record
processid: dword;
startaddress: dword;
bytestowrite: word;
end;
var ao: array [0..511] of byte;
input: TInputstruct absolute ao[0];
cc:dword;
i: integer;
ok: boolean;
br: dword;
mempointer: dword;
bufpointer: dword;
bufpointer2: pointer;
towrite: dword;
begin
result:=false;
NumberOfByteswritten:=0;
//find the hprocess in the handlelist, if it isn't use the normal method (I could of course use NtQueryProcessInformation but it's undocumented and I'm too lazy to dig it up
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0801, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
mempointer:=dword(lpBaseAddress);
bufpointer:=dword(lpbuffer);
ok:=true;
while ok do
begin
zeromemory(@ao[0],512);
input.processid:=handlelist[i].processid;
if nSize-NumberOfByteswritten>=(512-sizeof(TInputstruct)) then
towrite:=(512-sizeof(TInputstruct))
else
towrite:=nSize-NumberOfByteswritten;
input.bytestowrite:=towrite;
input.startaddress:=mempointer;
bufpointer2:=pointer(bufpointer);
copymemory(@ao[sizeof(tinputstruct)],bufpointer2,towrite);
if not deviceiocontrol(hdevice,cc,@ao[0],512,@ao[0],512,br,nil) then exit;
inc(mempointer,towrite);
inc(bufpointer,towrite);
inc(NumberOfByteswritten,towrite);
if NumberOfByteswritten=nSize then
begin
result:=true;
exit;
end;
end;
exit;
end else if not handlelist[i].validhandle then exit;
end;
//not found so ....
result:=windows.writeProcessMemory(hProcess,lpBaseAddress,lpBuffer,nSize,NumberOfByteswritten);
end;
function {OpenThread}tehuberTO(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwThreadId:DWORD):THANDLE; stdcall;
var
threadhandle: thandle;
cc,x: dword;
begin
result:=0;
if dwThreadId=0 then exit;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0818, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
threadhandle:=dwThreadId;
if deviceiocontrol(hdevice,cc,@threadhandle,4,@threadhandle,4,x,nil) then
result:=threadhandle
else
result:=0;
end;
end;
function {OpenProcess}tehuberPO(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwProcessId:DWORD):THANDLE; stdcall;
var valid:boolean;
Processhandle: thandle;
i:integer;
cc,x: dword;
begin
valid:=true;
if dwProcessId=0 then
begin
result:=0;
exit;
end;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0802, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
processhandle:=dwProcessId; //rest is ignored
if deviceiocontrol(hdevice,cc,@processhandle,4,@processhandle,4,x,nil) then
begin
result:=processhandle
end
else
result:=0;
end else result:=windows.OpenProcess(dwDesiredAccess,bInheritHandle,dwProcessID);
if result=0 then //you can still access memory using the low level stuff, just not normal stuff
begin
valid:=false;
//openprocess isn't working
if length(handlelist)=0 then result:=100+random(32000)
else
result:=handlelist[length(handlelist)-1].processhandle+1;
end;
//check for a duplicate handle and replace it (closehandle/openproces gets you the same handle)
for i:=0 to length(handlelist)-1 do
begin
if handlelist[i].processhandle=result then
begin
handlelist[i].processid:=dwProcessID;
handlelist[i].validhandle:=valid;
exit;
end;
end;
setlength(handlelist,length(handlelist)+1);
handlelist[length(handlelist)-1].processhandle:=result;
handlelist[length(handlelist)-1].processid:=dwProcessID;
handlelist[length(handlelist)-1].validhandle:=valid;
end;
Function {NtOpenThread}NtOT(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
begin
handle:=tehuberPO(STANDARD_RIGHTS_REQUIRED or windows.synchronize or $3ff,true,clientid.processid);
if handle<>0 then result:=0 else result:=$c000000e;
end;
Function {NtOpenProcess}tehuberNO(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
begin
Handle:=tehuberPO(process_all_access,true,clientid.processid);
if handle<>0 then result:=0 else result:=$C000000E;
end;
function {VirtualQueryEx}tehuberVQ(hProcess: THandle; address: pointer; var mbi: _MEMORY_BASIC_INFORMATION; bufsize: DWORD):dword; stdcall;
type TOUTP=record
length : DWORD ;
protection : DWORD ;
end;
var buf: TOUTP;
i: integer;
br,cc: dword;
begin
result:=0;
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
buf.length:=handlelist[i].processid;
buf.protection:=dword(address);
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0803, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@buf,sizeof(buf),@buf,sizeof(buf),br,nil) then
begin
mbi.BaseAddress:=pointer((dword(address) div $1000) *$1000);
mbi.AllocationBase:=mbi.BaseAddress;
mbi.AllocationProtect:=buf.protection;
mbi.RegionSize:=buf.length;
mbi.State:=MEM_COMMIT;
mbi.Protect:=buf.protection;
mbi.Type_9:=MEM_PRIVATE;
result:=sizeof(mbi);
end;
exit; //we're done here
end;
end;
result:=windows.VirtualQueryEx(hProcess,address,mbi,bufsize);
end;
Function {VirtualAllocEx}tehuberVA(hProcess: THandle; lpAddress: Pointer; dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
var i: integer;
br,cc: dword;
x: record
processid: dword;
baseaddress: pointer;
size: dword;
AllocationType: dword;
Protect: dword;
end;
r: pointer;
begin
result:=0;
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
x.processid:=handlelist[i].processid;
x.baseaddress:=lpAddress;
x.size:=dwsize;
x.AllocationType:=flAllocationType;
x.Protect:=flProtect;
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $081f, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
deviceiocontrol(hdevice,cc,@x,sizeof(x),@r,sizeof(r),br,nil);
result:=r;
exit; //we're done here
end;
end;
//still here
result:=VirtualAllocEx(hprocess,lpAddress,dwSize,flAllocationType,flProtect);
end;
procedure testapc( NormalContext:pointer; SystemArgument1:pointer; SystemArgument2:pointer);stdcall;
var tid: dword;
s: string;
begin
s:=inttohex(dword(NormalContext),8)+' - '+inttohex(dword(SystemArgument1),8)+' - '+inttohex(dword(SystemArgument2),8);
//CreateThread(nil,0,systemArgument1,SystemArgument2,false,@tid);
messagebox(0,pchar(s),'APC rules',mb_ok);
end;
Function tehuberPAC(threadid: dword; lpStartAddress: TFNAPCProc): THandle; stdcall;
var i: integer;
br,cc: dword;
x:record
threadid: dword;
addresstoexecute: pointer;
end;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
x.addresstoexecute:=lpStartAddress;
x.threadid:=threadid;
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0820, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@x,sizeof(x),nil,0,br,nil) then
result:=666 //sorry dude, no threadid returned, and no way of checking if it succeeded or not
else
result:=0;
end;
end;
function tehuberSADM(var int1apihook:dword; var OriginalInt1handler:dword):BOOL; stdcall;
var
x:record
int1apihook: dword;
Originalint1handler: dword;
end;
br,cc: dword;
i:integer;
begin
outputdebugstring('setAlternateDebugMethod');
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $081d, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,nil,0,@x,sizeof(x),br,nil) then
begin
//this data will be send to cheat engine. it will know what to do with it...
int1apihook:=x.int1apihook;
OriginalInt1handler:=x.Originalint1handler;
result:=true;
end;
usealternatedebugmethod:=result; //once set you can't unset it
end;
end;
function tehuberGADM:BOOL; stdcall;
var
x: boolean;
br,cc: dword;
begin
outputdebugstring('getAlternateDebugMethod');
//check the kernel if this method has been set
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $081e, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,nil,0,@x,sizeof(x),br,nil) then
result:=x;
usealternatedebugmethod:=x;
end else result:=false;
end;
function StartCEKernelDebug:BOOL; stdcall;
var
br,cc: dword;
i:integer;
cpunr,PA,SA:Dword;
cpunr2:byte;
begin
result:=false;
outputdebugstring('DebugProcess function');
if usealternatedebugmethod then
begin
result:=true;
exit;
end;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0810, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
GetProcessAffinityMask(getcurrentprocess,PA,SA);
//first hook the interrupts if needed
cpunr2:=0;
cpunr:=1;
while (cpunr<=PA) do
begin
if ((cpunr) and PA)>0 then
begin
SetProcessAffinityMask(getcurrentprocess,cpunr);
//create a new thread. (Gues on what cpu it will run at...)
with THookIDTThread.Create(true) do
begin
try
cpunr:=cpunr2;
resume;
while not done do sleep(10); //the sleep should also cause a taskswitch but I'm not 100% sure
if not succeeded then
begin
SetProcessAffinityMask(getcurrentprocess,PA);
messagebox(0,pchar('Failure when changing the interrupt handler on CPU '+inttostr(cpunr)),'',mb_ok);
exit;
end;
finally
free;
end;
end;
end;
if cpunr=$80000000 then break;
inc(cpunr,cpunr);
inc(cpunr2);
end;
SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it
outputdebugstring('going to start the hooker');
hooker:=thookidtconstantly.Create(false);
result:=true;
end;
end;
function SetMemoryAccessWatch(processid:dword;address:DWORD;size: byte;debugtype:byte):BOOL; stdcall;
type Tinput=record
ProcessID:DWORD;
Address:DWORD;
Length:BYTE;
RWE:BYTE;
end;
var input:TInput;
br,cc: dword;
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
result:=StartCEKernelDebug;
input.Processid:=processid;
input.Address:=address;
input.length:=size;
input.RWE:=debugtype;
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0811, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=result and deviceiocontrol(hdevice,cc,@input,sizeof(input),@input,0,br,nil);
end;
end;
function tehuberSTOPRCHG(regnr:integer):BOOL; stdcall;
var x,cc: dword;
begin
outputdebugstring('DBK32: StopRegisterChange called');
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $081c, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@regnr,4,nil,0,x,nil);
end;
end;
function tehuberSTOPDEBUG:BOOL; stdcall;
var x,cc: dword;
begin
outputdebugstring('DBK32: StopDebugging called');
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $081b, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,nil,0,nil,0,x,nil);
end;
end;
function tehuberDEBUG(processid:dword;address:DWORD;size: byte;debugtype:byte):BOOL; stdcall;
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
result:=StartCEKernelDebug;
result:=result and SetMemoryAccessWatch(processid,address,size,debugtype);
end;
end;
function ChangeRegOnBP(Processid:dword; address: dword; debugreg: integer; changeEAX,changeEBX,changeECX,changeEDX,changeESI,changeEDI,changeEBP,changeESP,changeEIP,changeCF,changePF,changeAF,changeZF,changeSF,changeOF:BOOLEAN; newEAX,newEBX,newECX,newEDX,newESI,newEDI,newEBP,newESP,newEIP:DWORD; newCF,newPF,newAF,newZF,newSF,newOF:BOOLEAN):BOOLEAN; stdcall;
type TChangeReg=record
BreakAddress: DWORD;
newEAX,newEBX,newECX,newEDX,newESI,newEDI,newEBP,newESP,newEIP: DWORD;
newCF,newPF,newAF,newZF,newSF,newOF:BOOLEAN;
changeEAX,changeEBX,changeECX,changeEDX,changeESI,changeEDI,changeEBP,changeESP,changeEIP:BOOLEAN;
changeCF,changePF,changeAF,changeZF,changeSF,changeOF:BOOLEAN;
Active:BOOLEAN;
end;
type TBuf=record
ProcessID: DWORD;
debugreg: integer;
ChangeReg: TChangeReg;
end;
var buf: TBuf;
x,cc: dword;
begin
outputdebugstring('DBK32: ChangeRegOnBP called');
if hdevice<>INVALID_HANDLE_VALUE then
begin
result:=StartCEKernelDebug;
if not result then exit;
buf.ProcessID:=Processid;
buf.debugreg:=debugreg;
buf.ChangeReg.BreakAddress:=address;
buf.ChangeReg.newEAX:=neweax;
buf.ChangeReg.newEBX:=newebx;
buf.ChangeReg.newECX:=newecx;
buf.ChangeReg.newEDX:=newedx;
buf.ChangeReg.newESI:=newesi;
buf.ChangeReg.newEDI:=newedi;
buf.ChangeReg.newEBP:=newebp;
buf.ChangeReg.newESP:=newesp;
buf.ChangeReg.newEIP:=neweip;
buf.ChangeReg.newCF:=newcf;
buf.ChangeReg.newPF:=newpf;
buf.ChangeReg.newAF:=newaf;
buf.ChangeReg.newZF:=newzf;
buf.ChangeReg.newSF:=newsf;
buf.ChangeReg.newOF:=newof;
buf.ChangeReg.changeEAX:=changeeax;
buf.ChangeReg.changeEBX:=changeebx;
buf.ChangeReg.changeECX:=changeecx;
buf.ChangeReg.changeEDX:=changeedx;
buf.ChangeReg.changeESI:=changeesi;
buf.ChangeReg.changeEDI:=changeedi;
buf.ChangeReg.changeEBP:=changeebp;
buf.ChangeReg.changeESP:=changeesp;
buf.ChangeReg.changeEIP:=changeeip;
buf.ChangeReg.changeCF:=changecf;
buf.ChangeReg.changePF:=changepf;
buf.ChangeReg.changeAF:=changeaf;
buf.ChangeReg.changeZF:=changezf;
buf.ChangeReg.changeSF:=changesf;
buf.ChangeReg.changeOF:=changeof;
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $081a, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=result and deviceiocontrol(hdevice,cc,@buf,sizeof(buf),@buf,0,x,nil);
end;
end;
function tehuberGETBUGDATA(Buffer: pointer):integer; stdcall; //buffer has to be at least 1800 bytes
var x,cc: dword;
buf: pointer;
begin
//50*35 bytes=
result:=-1; //-1=error
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
getmem(buf,1801); //1801 because the first byte is the count
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0812, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,buf,1801,buf,1801,x,nil) then
begin
result:=pbyte(buf)^;
copymemory(buffer,pointeR(dword(buf)+1),1801);
end;
freemem(buf);
end;
end;
function WaitForProcessListData(processpointer:pointer;threadpointer:pointer;timeout:dword):dword; stdcall;
type tprocesseventstruct=record
Created:BOOL;
ProcessID:DWORD;
PEProcess:DWORD;
end;
type tthreadeventstruct=record
Created:BOOL;
ProcessID:DWORD;
ThreadID:dword;
end;
var cc,x:dword;
eventarray: array of thandle;
begin
//assuming the buffer is at least the size of 50* the biggest struct (threadstruct in this case)
//retrieve the processevents
//wait for a process create event to be set
setlength(eventarray,2);
eventarray[0]:=processevent;
eventarray[1]:=threadevent;
result:=WaitForMultipleObjects(2,@eventarray[0],false,timeout);
// result:=WaitForSingleObject(processevent,timeout);
if result<>WAIT_FAILED then
begin
//processevent
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0814, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
deviceiocontrol(hdevice,cc,processpointer,sizeof(tprocesseventstruct)*50+1,processpointer,sizeof(tprocesseventstruct)*50+1,x,nil);
end;
//thread event
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0815, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
deviceiocontrol(hdevice,cc,threadpointer,sizeof(tthreadeventstruct)*50+1,threadpointer,sizeof(tthreadeventstruct)*50+1,x,nil);
end;
end;
end;
function StartProcessWatch:BOOL;stdcall;
var cc,x: dword;
begin
result:=false;
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0813, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,0,@x,0,x,nil);
end;
end;
function MakeWritable(Address,Size:dword;copyonwrite:boolean): boolean; stdcall;
type TMemoryDesignation=record
StartAddress:DWORD;
Size: DWORD;
CopyOnWrite: BYTE;
end;
var cc: dword;
x: TMemoryDesignation;
begin
result:=false;
x.StartAddress:=Address;
x.Size:=Size;
if copyonwrite then x.CopyOnWrite:=1 else x.CopyOnWrite:=0;
if (hdevice<>INVALID_HANDLE_VALUE) then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0819, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@x,sizeof(x),@x,0,cc,nil);
end;
end;
function RewriteKernel32:boolean; stdcall;
begin
//modifies the code of NtOpenProcess,NtOpenThread,OpenProcess,OpenThread to point to this dll's functions
end;
function RestoreKernel32: boolean; stdcall;
begin
end;
function CTL_CODE(DeviceType, Func, Method, Access : integer) : integer;
begin
Result := (DeviceType shl 16) or (Access shl 14) or (Func shl 2) or Method;
end;
function InitializeDriver(Address,size:dword):BOOL; stdcall;
type tinput=record
address: dword;
size:dword;
NtUserBuildHwndList_callnumber: Dword;
NtUserQueryWindow_callnumber:dword;
NtUserFindWindowEx_callnumber:DWORD;
NtUserGetForegroundWindow_callnumber:DWORD;
activelinkoffset: dword;
processnameoffset:dword;
debugportoffset:dword;
end;
var cc: dword;
buf: tinput;
res: dword absolute buf;
x:dword;
callnumberfile: tfilestream;
windowsversion:_osversioninfoa;
majorversion,minorversion,buildnumber: dword;
CSDVersion: array [0..127] of char;
a: boolean;
i: integer;
begin
result:=false;
sdtshadow:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
processevent:=OpenEvent(SYNCHRONIZE,false,'DBKProcList51');
threadevent:=OpenEvent(SYNCHRONIZE,false,'DBKThreadList51');
zeromemory(@buf,sizeof(buf));
buf.address:=address;
buf.size:=size;
buf.NtUserBuildHwndList_callnumber:=0;
buf.NtUserQueryWindow_callnumber:=0;
buf.NtUserFindWindowEx_callnumber:=0;
buf.NtUserGetForegroundWindow_callnumber:=0;
buf.activelinkoffset:=0;
buf.processnameoffset:=0;
buf.debugportoffset:=0;
//check if there is a callnumber.txt file in the rootdir, and if so use it
if fileexists(extractfilepath(driverloc)+'kerneldata.dat') then
begin
//read the file, first 4 bytes is the callnumber of NtUserBuildHwndList_callnumber
try
callnumberfile:=tfilestream.create(extractfilepath(driverloc)+'kerneldata.dat',fmOpenRead,fmShareDenyNone );
try
windowsversion.dwOSVersionInfoSize:=sizeof(windowsversion);
getversionex(windowsversion);
callnumberfile.ReadBuffer(MajorVersion,4);
callnumberfile.ReadBuffer(MinorVersion,4);
callnumberfile.ReadBuffer(BuildNumber,4);
callnumberfile.ReadBuffer(CSDVersion,128);
// a:=comparemem(@CSDVersion[0],@windowsversion.szCSDVersion[0],128);
a:=true;
i:=0;
while a and (i<128) and (windowsversion.szCSDVersion[i]<>#0) and (CSDVersion[i]<>#0) do
begin
a:=CSDVersion[i]=windowsversion.szCSDVersion[i];
inc(i);
end;
if (not a) or (majorversion<>windowsversion.dwMajorVersion) or (MinorVersion<>windowsversion.dwMinorVersion) or (buildnumber<>windowsversion.dwBuildNumber) then
begin
messagebox(0,'Your windows version has changed. Run the Kerneldata retriever so CE can use up-to-date data','tehuber32dbk.DLL Error',MB_ICONERROR or MB_OK);
exit;
end;
callnumberfile.ReadBuffer(x,4);
buf.NtUserBuildHwndList_callnumber:=x;
callnumberfile.ReadBuffer(x,4);
buf.NtUserQueryWindow_callnumber:=x;
callnumberfile.ReadBuffer(x,4);
buf.NtUserFindWindowEx_callnumber:=x;
callnumberfile.ReadBuffer(x,4);
buf.NtUserGetForegroundWindow_callnumber:=x;
callnumberfile.ReadBuffer(buf.activelinkoffset,4);
callnumberfile.ReadBuffer(buf.processnameoffset,4);
callnumberfile.ReadBuffer(buf.debugportoffset,4);
debugport:=buf.debugportoffset;
processname:=buf.processnameoffset;
//----------------Add this part to the file---------
ThreadsProcess:=$220;
ThreadListEntry:=$3c;
finally
callnumberfile.free;
end;
except
end;
end;
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080d, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@buf,sizeof(tinput),@buf,sizeof(tinput),x,nil) then
begin
result:=true;
SDTShadow:=res;
end;
ownprocess:=tehuberPO(PROCESS_ALL_ACCESS,false,getcurrentprocessid);
end;
end;
function GetWin32KAddress(var address:DWORD;var size:dworD):boolean;
var need:dword;
p: pointer;
oldx: dword;
x: array of pointer;
i,j: integer;
count: integer;
drivername: pchar;
nearest: dword; //nearest other driver (AFTER win32k.sys)
begin
result:=false;
copymemory(@oldx,@x,4);
EnumDevicedrivers(nil,0,need);
count:=need div 4;
getmem(p,need);
try
if enumDevicedrivers(p,need,need) then
begin
getmem(drivername,200);
copymemory(@x,@p,4);
try
for i:=0 to count-1 do
begin
GetDevicedriverBaseName(x[i],drivername,200);
if lowercase(drivername)='win32k.sys' then
begin
address:=dword(x[i]);
nearest:=$ffffffff;
for j:=0 to count-1 do
if (dword(x[j])>dword(x[i])) and (dword(x[j])0 then
begin
hService := OpenService(hSCManager, 'CEDRIVER52', SERVICE_ALL_ACCESS);
if hService=0 then
begin
hService:=CreateService(
hSCManager, // SCManager database
'CEDRIVER52', // name of service
'CEDRIVER52', // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER,// service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
pchar(driverloc), // service's binary
nil, // no load ordering group
nil, // no tag identifier
nil, // no dependencies
nil, // LocalSystem account
nil // no password
);
end
else
begin
//make sure the service points to the right file
ChangeServiceConfig(hservice,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
pchar(driverloc),
nil,
nil,
nil,
nil,
nil,
'CEDRIVER52');
end;
if hservice<>0 then
begin
sav:=nil;
startservice(hservice,0,sav);
closeservicehandle(hservice);
end else
begin
messagebox(0,'The service couldn''t get opened and also couldn''t get created.'+' Check if you have the needed rights to create a service, or call your system admin (Who''ll probably beat you up for even trying this). Untill this is fixed you won''t be able to make use of the enhancements the driver gives you','DBK32 Error',MB_ICONERROR or mb_ok);
hDevice:=INVALID_HANDLE_VALUE;
exit;
end;
hdevice:=0;
hDevice := CreateFile('\\.\CEDRIVER52',
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if hdevice=INVALID_HANDLE_VALUE then
messagebox(0,'The driver couldn''t be opened! It''s not loaded or not responding. I recommend to reboot your system and try again','tehuber32dbk.DLL Error',MB_ICONERROR or MB_OK)
else
begin
//Get the address of win32k.sys
if GetDriverVersion<>currentversion then
begin
closehandle(hdevice);
messagebox(0,'The driver that is currently loaded belongs to a previous version of Cheat Engine. Please unload this old driver or reboot.','tehuber32dbk.dll',MB_ICONERROR or MB_OK);
hdevice:=INVALID_HANDLE_VALUE;
end
else
begin
if GetWin32KAddress(win32kAddress,win32size) then
begin
if not InitializeDriver(win32kAddress,win32size) then
begin
messagebox(0,'The driver failed to successfully initialize. Some functions may not completly work','tehuber32dbk.dll',MB_ICONERROR or MB_OK);
end;
end
else
messagebox(0,'There was an error while trying to find the win32k.sys device driver. This means that some functions will not work','tehuber32dbk.dll',MB_ICONERROR or MB_OK);
Successfullyloaded:=true;
end;
end;
closeservicehandle(hscmanager);
end;
end;
finalization
begin
closehandle(ownprocess);
if hooker<>nil then hooker.Terminate;
freelibrary(kernel32dll);
end;
end.