mirror of
https://github.com/cheat-engine/cheat-engine
synced 2026-08-15 02:26:08 -04:00
386 lines
12 KiB
ObjectPascal
386 lines
12 KiB
ObjectPascal
program Kernelmoduleunloader;
|
|
|
|
uses
|
|
windows,
|
|
winsvc,
|
|
SysUtils,
|
|
multicpuexecution in '..\multicpuexecution.pas';
|
|
|
|
{$R ic.res}
|
|
{$R ..\..\manifest.res}
|
|
|
|
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 TIsWow64Process=function (processhandle: THandle; var isWow: BOOL): BOOL; stdcall;
|
|
|
|
|
|
var kernel32dll: thandle;
|
|
IsWow64Process: TIsWow64Process;
|
|
iswow64: bool;
|
|
|
|
|
|
var
|
|
hSCManager: SC_HANDLE;
|
|
hservice: SC_HANDLE;
|
|
hDevice: THANDLE;
|
|
cc: dword;
|
|
x: dword;
|
|
servicestatus:_service_status;
|
|
ok,ok2: boolean;
|
|
count: integer;
|
|
setup: boolean;
|
|
|
|
|
|
function noIsWow64(processhandle: THandle; var isWow: BOOL): BOOL; stdcall;
|
|
begin
|
|
if @isWow<>nil then
|
|
isWow:=false;
|
|
|
|
result:=false;
|
|
end;
|
|
|
|
|
|
function UpperCase(const S: string): string;
|
|
var
|
|
Ch: Char;
|
|
L: Integer;
|
|
Source, Dest: PChar;
|
|
begin
|
|
L := Length(S);
|
|
SetLength(Result, L);
|
|
Source := Pointer(S);
|
|
Dest := Pointer(Result);
|
|
while L <> 0 do
|
|
begin
|
|
Ch := Source^;
|
|
if (Ch >= 'a') and (Ch <= 'z') then Dec(Ch, 32);
|
|
Dest^ := Ch;
|
|
Inc(Source);
|
|
Inc(Dest);
|
|
Dec(L);
|
|
end;
|
|
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 disableGlobalDebug(parameters: pointer): BOOL; stdcall;
|
|
{
|
|
Sets the global debug flag to 0 for the current cpu
|
|
}
|
|
var state: BOOL;
|
|
begin
|
|
state:=false;
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0830 {IOCTL_CE_SETGLOBALDEBUGSTATE}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
result:=deviceiocontrol(hdevice,cc,@state,sizeof(state),nil,0,x,nil);
|
|
if not result then
|
|
begin
|
|
if not setup then messagebox(0,'Failure stopping the debugging','driver error',mb_ok or MB_ICONERROR);
|
|
ExitProcess(1);
|
|
end;
|
|
end;
|
|
|
|
function disableInterruptHooks(parameters: pointer): BOOL; stdcall;
|
|
{
|
|
Sets the global debug flag to 0 for the current cpu
|
|
}
|
|
var state: BOOL;
|
|
begin
|
|
state:=false;
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $083b {IOCTL_CE_UNHOOKALLINTERRUPTS}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
result:=deviceiocontrol(hdevice,cc,nil,0,nil,0,x,nil);
|
|
if not result then
|
|
begin
|
|
if not setup then messagebox(0,'Failure stopping the debugging','driver error',mb_ok or MB_ICONERROR);
|
|
ExitProcess(1);
|
|
end;
|
|
end;
|
|
|
|
var f,driverdat: textfile;
|
|
s: string;
|
|
i: integer;
|
|
|
|
|
|
dataloc: string;
|
|
apppath: pchar;
|
|
begin
|
|
kernel32dll:=loadlibrary('kernel32.dll');
|
|
loadlibrary('user32.dll');
|
|
loadlibrary('comctl32.dll');
|
|
IsWow64Process:=GetProcAddress(kernel32dll, 'IsWow64Process');
|
|
if not assigned(IsWow64Process) then IsWow64Process:=noIsWow64;
|
|
|
|
IsWow64Process(getcurrentprocess,iswow64);
|
|
|
|
outputdebugstring('Kernelmodule unloader');
|
|
if iswow64 then
|
|
outputdebugstring('Running in wow64');
|
|
|
|
setup:=false;
|
|
if ParamCount>0 then
|
|
begin
|
|
for i:=1 to paramcount do
|
|
begin
|
|
s:=paramstr(i);
|
|
if uppercase(s)='/SETUP' then
|
|
setup:=true;
|
|
end;
|
|
end;
|
|
|
|
|
|
count:=0;
|
|
ok:=false;
|
|
|
|
if setup then
|
|
outputdebugstring('Setup. So do not show messages')
|
|
else
|
|
outputdebugstring('Setup is false');
|
|
|
|
while (not ok) and (count<5) do
|
|
begin
|
|
outputdebugstring('attempting to unload');
|
|
|
|
hSCManager := OpenSCManager(nil, nil, GENERIC_READ or GENERIC_WRITE);
|
|
if hscmanager<>0 then
|
|
begin
|
|
outputdebugstring('SCManager opened');
|
|
hservice:=OpenService(hSCManager, 'DBKDRVR', SERVICE_ALL_ACCESS);
|
|
if hservice<>0 then
|
|
begin
|
|
outputdebugstring('Opened service DBKDRVR');
|
|
hDevice := CreateFile('\\.\DBKDRVR',
|
|
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
|
|
begin
|
|
//unhook (in case it was protecting something)
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080e {unprotect}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
ok:=deviceiocontrol(hdevice,cc,@x,4,@x,4,x,nil);
|
|
closehandle(hdevice);
|
|
end else ok:=false;
|
|
|
|
ok:=ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
|
|
ok2:=DeleteService(hService);
|
|
end;
|
|
|
|
hservice:=OpenService(hSCManager, 'DRIVER1111', SERVICE_ALL_ACCESS);
|
|
if hservice<>0 then
|
|
begin
|
|
outputdebugstring('Opened service DRIVER1111');
|
|
hDevice := CreateFile('\\.\DRIVER1111',
|
|
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
|
|
begin
|
|
//unhook (in case it was protecting something)
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080e {unprotect}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
ok:=deviceiocontrol(hdevice,cc,@x,4,@x,4,x,nil);
|
|
closehandle(hdevice);
|
|
end else ok:=false;
|
|
|
|
ok:=ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
|
|
ok2:=DeleteService(hService);
|
|
end;
|
|
|
|
|
|
hService := OpenService(hSCManager, 'CEDRIVER50', SERVICE_ALL_ACCESS);
|
|
if hservice<>0 then
|
|
begin
|
|
outputdebugstring('Opened service CEDRIVER50');
|
|
hDevice := CreateFile('\\.\CEDRIVER50',
|
|
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
|
|
begin
|
|
//unhook (in case it was protecting something)
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080e {unprotect}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
ok:=deviceiocontrol(hdevice,cc,@x,4,@x,4,x,nil);
|
|
if not ok then
|
|
begin
|
|
if not setup then messagebox(0,'The driver was found and present. But it can''t unload itself right now','driver error',mb_ok or MB_ICONERROR);
|
|
end;
|
|
|
|
closehandle(hdevice);
|
|
end else ok:=false;
|
|
|
|
ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
|
|
ok:=DeleteService(hService);
|
|
|
|
CloseServiceHandle(hservice);
|
|
end;
|
|
|
|
|
|
hService := OpenService(hSCManager, 'CEDRIVER51', SERVICE_ALL_ACCESS);
|
|
if hservice<>0 then
|
|
begin
|
|
outputdebugstring('Opened service CEDRIVER51');
|
|
hDevice := CreateFile('\\.\CEDRIVER51',
|
|
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
|
|
begin
|
|
//unhook (in case it was protecting something)
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080e {unprotect}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
ok:=deviceiocontrol(hdevice,cc,@x,4,@x,4,x,nil);
|
|
if not ok then
|
|
begin
|
|
if not setup then messagebox(0,'The driver was found and present. But it can''t unload itself right now','driver error',mb_ok or MB_ICONERROR);
|
|
end;
|
|
|
|
closehandle(hdevice);
|
|
end else ok:=false;
|
|
|
|
ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
|
|
ok:=DeleteService(hService);
|
|
|
|
CloseServiceHandle(hservice);
|
|
end;
|
|
|
|
hService := OpenService(hSCManager, 'CEDRIVER52', SERVICE_ALL_ACCESS);
|
|
if hservice<>0 then
|
|
begin
|
|
outputdebugstring('Opened service CEDRIVER52');
|
|
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
|
|
begin
|
|
//unhook (in case it was protecting something)
|
|
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080e {unprotect}, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
|
|
ok:=deviceiocontrol(hdevice,cc,@x,4,@x,4,x,nil);
|
|
if not ok then
|
|
begin
|
|
if not setup then messagebox(0,'The driver was found and present. But it can''t unload itself right now','driver error',mb_ok or MB_ICONERROR);
|
|
end;
|
|
|
|
closehandle(hdevice);
|
|
end else ok:=false;
|
|
|
|
ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
|
|
ok:=DeleteService(hService);
|
|
|
|
CloseServiceHandle(hservice);
|
|
end;
|
|
|
|
|
|
try
|
|
s:='CEDRIVER55';
|
|
getmem(apppath,250);
|
|
GetModuleFileName(0,apppath,250);
|
|
|
|
if iswow64 then
|
|
dataloc:=extractfilepath(apppath)+'driver64.dat'
|
|
else
|
|
dataloc:=extractfilepath(apppath)+'driver.dat';
|
|
|
|
if fileexists(dataloc) then
|
|
begin
|
|
assignfile(driverdat,dataloc);
|
|
reset(driverdat);
|
|
readln(driverdat,s);
|
|
closefile(driverdat);
|
|
end;
|
|
finally
|
|
freemem(apppath);
|
|
end;
|
|
|
|
hService := OpenService(hSCManager, pchar(s), SERVICE_ALL_ACCESS);
|
|
if hservice<>0 then
|
|
begin
|
|
outputdebugstring(pchar('Opened service '+s));
|
|
hDevice := CreateFile(pchar('\\.\'+s),
|
|
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
|
|
begin
|
|
//unhook (in case it was protecting something)
|
|
outputdebugstring('Calling disableglobaldebug');
|
|
foreachcpu(disableGlobalDebug,nil);
|
|
|
|
outputdebugstring('calling disableInterruptHooks');
|
|
foreachcpu(disableInterruptHooks,nil);
|
|
|
|
closehandle(hdevice);
|
|
end else ok:=false;
|
|
|
|
ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
|
|
ok:=DeleteService(hService);
|
|
|
|
CloseServiceHandle(hservice);
|
|
end else
|
|
if count=0 then
|
|
begin
|
|
outputdebugstring('count=0');
|
|
if not setup then
|
|
begin
|
|
// outputdebugstring('showing message that the driver isn''t in the registry');
|
|
messageboxA(0,'Failed to find the driver in the registry','driver error',mb_ok);
|
|
// outputdebugstring('AFTER the messagebox');
|
|
end
|
|
else outputdebugstring('setup=true');
|
|
exit;
|
|
end;
|
|
|
|
CloseServiceHandle(hSCManager);
|
|
end;
|
|
|
|
if not ok then
|
|
begin
|
|
sleep(1000);
|
|
inc(count);
|
|
end;
|
|
end;
|
|
|
|
|
|
outputdebugstring('near the end');
|
|
if not setup then
|
|
begin
|
|
if ok or ok2 then
|
|
messagebox(0,'The driver is successfully unloaded.','dbk32.sys unloaded',MB_ICONINFORMATION or MB_OK)
|
|
else
|
|
messagebox(0,'The driver failed to unload or is already unloaded. If you think it''s still loaded then reboot and run the unloader again.','DBK32.sys unloader',MB_ICONERROR or MB_OK)
|
|
end;
|
|
end.
|