
move the processlist function from cefuncproc to it's own unit start work on the jni library for java
283 lines
8.7 KiB
ObjectPascal
283 lines
8.7 KiB
ObjectPascal
unit CEDebugger;
|
|
//OLD debugger. Obsolete , just here till all old references have been removed
|
|
|
|
{$MODE Delphi}
|
|
|
|
interface
|
|
|
|
uses windows, Classes,LCLIntf,sysutils,CEFuncProc,Messages,forms,SyncObjs,
|
|
dialogs,controls,Graphics,NewKernelHandler,symbolhandler,StrUtils,
|
|
ComCtrls ,Assemblerunit,addressparser, debughelper;
|
|
|
|
|
|
type TReadonly = record
|
|
pagebase: uint_ptr;
|
|
pagesize: uint_ptr;
|
|
Address: uint_ptr;
|
|
size: integer;
|
|
originalprotection: dword;
|
|
end;
|
|
|
|
type tThreadEntry=record
|
|
threadHandle: thandle;
|
|
address: uint_ptr;
|
|
end;
|
|
|
|
|
|
type Process=record
|
|
ProcessID: dword;
|
|
running: boolean;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type TDbgUIDebugActiveProcess = function(processhandle:THandle):boolean; stdcall;
|
|
type TDebugBreakProcess = function(processhandle:THandle):boolean; stdcall;
|
|
type TDebugActiveProcessStop= function(pid: dword):boolean; stdcall;
|
|
type TDebugSetProcessKillOnExit=function(KillOnExit: boolean):boolean; stdcall;
|
|
type TIsDebuggerPresent=function:boolean; stdcall;
|
|
type TntSuspendProcess=function(ProcessID:Dword):DWORD; stdcall;
|
|
type TntResumeProcess=function(ProcessID:Dword):DWORD; stdcall;
|
|
|
|
|
|
|
|
|
|
type
|
|
TProcessBasicInformation = record
|
|
ExitStatus : Longint;
|
|
PebBaseAddress : Pointer;
|
|
AffinityMask : DWORD;
|
|
BasePriority : Longint;
|
|
UniqueProcessId : DWORD;
|
|
InheritedFromUniqueProcessId : DWORD
|
|
end;
|
|
|
|
NTSTATUS = LONG;
|
|
_CLIENT_ID = record
|
|
UniqueProcess: HANDLE;
|
|
UniqueThread: HANDLE;
|
|
end;
|
|
CLIENT_ID = _CLIENT_ID;
|
|
PCLIENT_ID = ^CLIENT_ID;
|
|
TClientID = CLIENT_ID;
|
|
PClientID = ^TClientID;
|
|
|
|
KPRIORITY = LONG;
|
|
KAFFINITY = ULONG_PTR;
|
|
|
|
_THREAD_BASIC_INFORMATION = record // Information Class 0
|
|
ExitStatus: NTSTATUS;
|
|
TebBaseAddress: pointer;
|
|
ClientId: CLIENT_ID;
|
|
AffinityMask: KAFFINITY;
|
|
Priority: KPRIORITY;
|
|
BasePriority: KPRIORITY;
|
|
end;
|
|
THREAD_BASIC_INFORMATION = _THREAD_BASIC_INFORMATION;
|
|
PTHREAD_BASIC_INFORMATION = ^THREAD_BASIC_INFORMATION;
|
|
TThreadBasicInformation = THREAD_BASIC_INFORMATION;
|
|
PThreadBasicInformation = ^TThreadBasicInformation;
|
|
|
|
TProcessInfoClass=(
|
|
ProcessBasicInformation,ProcessQuotaLimits,ProcessIoCounters,ProcessVmCounters,ProcessTimes,
|
|
ProcessBasePriority,ProcessRaisePriority,ProcessDebugPort,ProcessExceptionPort,ProcessAccessToken,
|
|
ProcessLdtInformation,ProcessLdtSize,ProcessDefaultHardErrorMode,ProcessIoPortHandlers,
|
|
ProcessPooledUsageAndLimits,ProcessWorkingSetWatch,ProcessUserModeIOPL,ProcessEnableAlignmentFaultFixup,
|
|
ProcessPriorityClass,ProcessWx86Information,ProcessHandleCount,ProcessAffinityMask,ProcessPriorityBoost,
|
|
ProcessDeviceMap,ProcessSessionInformation,ProcessForegroundInformation,ProcessWow64Information,
|
|
MaxProcessInfoClass);
|
|
|
|
_THREADINFOCLASS = (
|
|
ThreadBasicInformation,
|
|
ThreadTimes,
|
|
ThreadPriority,
|
|
ThreadBasePriority,
|
|
ThreadAffinityMask,
|
|
ThreadImpersonationToken,
|
|
ThreadDescriptorTableEntry,
|
|
ThreadEnableAlignmentFaultFixup,
|
|
ThreadEventPair_Reusable,
|
|
ThreadQuerySetWin32StartAddress,
|
|
ThreadZeroTlsCell,
|
|
ThreadPerformanceCount,
|
|
ThreadAmILastThread,
|
|
ThreadIdealProcessor,
|
|
ThreadPriorityBoost,
|
|
ThreadSetTlsArrayAddress,
|
|
ThreadIsIoPending,
|
|
ThreadHideFromDebugger,
|
|
ThreadBreakOnTermination, // was added in XP - used by RtlSetThreadIsCritical()
|
|
MaxThreadInfoClass);
|
|
THREADINFOCLASS = _THREADINFOCLASS;
|
|
{.$ENDIF JWA_INCLUDEMODE}
|
|
THREAD_INFORMATION_CLASS = THREADINFOCLASS;
|
|
|
|
|
|
TThreadInfoClass = THREADINFOCLASS;
|
|
|
|
|
|
type TNtQueryInformationProcess=function(Handle : THandle; infoClass : TProcessInfoClass; processInformation : Pointer; processInformationLength : ULONG; returnLength : PULONG) : DWORD; stdcall;
|
|
type TNtQueryInformationThread=function(Handle : THandle; infoClass : TThreadinfoClass; ThreadInformation: pointer; processInformationLength : ULONG; returnLength : PULONG) : DWORD; stdcall;
|
|
|
|
var //DebuggerThread: TDebugger;
|
|
|
|
DbgUIDebugActiveProcess:TDbgUIDebugActiveProcess;
|
|
DebugBreakProcess:TDebugBreakProcess;
|
|
DebugActiveProcessStop:TDebugActiveProcessStop;
|
|
DebugSetProcessKillOnExit:TDebugSetProcessKillOnExit;
|
|
IsDebuggerPresent:TIsDebuggerPresent;
|
|
ntSuspendProcess: TntSuspendProcess;
|
|
ntResumeProcess: tntResumeProcess;
|
|
|
|
NtQueryInformationProcess: TNtQueryInformationProcess;
|
|
NtQueryInformationThread: TNtQueryInformationThread;
|
|
DbgBreakPointLocation:ptrUint;
|
|
|
|
|
|
krn: thandle;
|
|
ntdlllib: thandle;
|
|
|
|
CRDebugging: TCriticalSection;
|
|
|
|
|
|
function startdebuggerifneeded: boolean; overload;
|
|
function startdebuggerifneeded(ask:boolean): boolean; overload;
|
|
function DebugActiveProcessStopProstitute(x: dword): boolean;
|
|
|
|
implementation
|
|
|
|
uses debuggertypedefinitions, debugeventhandler, MainUnit,frmFloatingPointPanelUnit,
|
|
Memorybrowserformunit,disassembler,frmTracerUnit,foundcodeunit,kerneldebugger,
|
|
advancedoptionsunit,formChangedAddresses,frmstacktraceunit,frmThreadlistunit,
|
|
formdebugstringsunit,formsettingsunit,processwindowunit,plugin,processhandlerunit(*,frmCreatedProcessListUnit*);
|
|
|
|
|
|
resourcestring
|
|
rsPleaseTargetAnotherProcess = 'Please target another process';
|
|
rsYouMustFirstOpenAProcess = 'You must first open a process';
|
|
rsThisWillAttachTheDebuggerOfCheatEngineToTheCurrent = 'This will attach the debugger of Cheat Engine to the current process.';
|
|
rsDoNotCloseCE = 'If you close Cheat Engine while the game is running, the game will close too. Are you sure you want to do this?';
|
|
rsContinue = 'Continue?';
|
|
rsDebugError = 'I couldn''t attach the debugger to this process! You could try to open the process using the processpicker and try that! If that also doesn''t work check if '
|
|
+'you have debugging rights.';
|
|
|
|
function DebugBreakProstitute(x: Thandle):boolean;
|
|
begin
|
|
result:=false;
|
|
end;
|
|
|
|
function DebugSetProcessKillOnExitProtitute(x: boolean):boolean;
|
|
begin
|
|
result:=false;
|
|
end;
|
|
|
|
function DebugActiveProcessStopProstitute(x: dword): boolean;
|
|
begin
|
|
result:=false;
|
|
end;
|
|
|
|
function startdebuggerifneeded(ask:boolean): boolean; overload;
|
|
var mes: string;
|
|
reS:boolean;
|
|
i: integer;
|
|
begin
|
|
result:=false;
|
|
if processid=GetCurrentProcessId then raise exception.create(rsPleaseTargetAnotherProcess);
|
|
|
|
|
|
if processhandle=0 then raise exception.create(rsYouMustFirstOpenAProcess);
|
|
|
|
if (debuggerthread=nil) then
|
|
begin
|
|
if @DebugActiveProcessStop=@DebugActiveProcessStopProstitute then
|
|
mes:=rsThisWillAttachTheDebuggerOfCheatEngineToTheCurrent+' '+rsDoNotCloseCE
|
|
else
|
|
mes:=rsThisWillAttachTheDebuggerOfCheatEngineToTheCurrent+' '+rsContinue;
|
|
|
|
if ask then
|
|
res:=Messagedlg(mes,mtConfirmation,[mbYes, mbNo],0)=mrYes
|
|
else
|
|
res:=true;
|
|
|
|
if res then
|
|
begin
|
|
|
|
//start the debugger on the current process
|
|
//check for a debugger
|
|
try
|
|
Debuggerthread:=TDebuggerThread.MyCreate2(processid);
|
|
except
|
|
raise exception.Create(rsDebugError);
|
|
end;
|
|
|
|
result:=true;
|
|
exit;
|
|
end
|
|
else
|
|
begin
|
|
result:=false;
|
|
exit;
|
|
end;
|
|
end;
|
|
result:=true;
|
|
|
|
end;
|
|
|
|
function startdebuggerifneeded: boolean; overload;
|
|
begin
|
|
result:=startdebuggerifneeded(true);
|
|
end;
|
|
|
|
|
|
initialization
|
|
CRDebugging:=TCriticalSection.Create;
|
|
|
|
krn := LoadLibrary('Kernel32.dll');
|
|
if krn <> 0 then
|
|
begin
|
|
|
|
@DebugBreakProcess := GetProcAddress(krn, 'DebugBreakProcess');
|
|
@DebugSetProcessKillOnExit :=GetProcAddress(krn,'DebugSetProcessKillOnExit');
|
|
@DebugActiveProcessStop :=GetProcAddress(krn,'DebugActiveProcessStop');
|
|
@IsDebuggerPresent:=GetProcAddress(krn,'IsDebuggerPresent');
|
|
|
|
if @DebugBreakProcess=nil then
|
|
@DebugBreakProcess:=@DebugBreakProstitute;
|
|
|
|
if @DebugSetProcessKillOnExit=nil then
|
|
@DebugSetProcessKillOnExit:=@DebugSetProcessKillOnExitProtitute;
|
|
|
|
if @DebugActiveProcessStop=nil then
|
|
@DebugActiveProcessStop:=@DebugActiveProcessStopProstitute;
|
|
|
|
end;
|
|
|
|
ntdlllib:=LoadLibrary('ntdll.dll');
|
|
if ntdlllib<>0 then
|
|
begin
|
|
DbgUIDebugActiveProcess:=getprocaddress(ntdlllib,'DbgUiDebugActiveProcess');
|
|
DbgBreakPointLocation:=ptrUint(getprocaddress(ntdlllib,'DbgBreakPoint'));
|
|
|
|
NtQueryInformationProcess:=nil;
|
|
NtQueryInformationProcess:=GetProcAddress(ntdlllib,'NtQueryInformationProcess');
|
|
|
|
NtQueryInformationThread:=nil;
|
|
NtQueryInformationThread:=GetProcAddress(ntdlllib,'NtQueryInformationThread');
|
|
|
|
ntsuspendprocess:=nil;
|
|
ntsuspendprocess:=GetProcAddress(ntdlllib,'NtSuspendProcess');
|
|
ntresumeprocess:=GetProcAddress(ntdlllib,'NtResumeProcess');
|
|
freelibrary(ntdlllib);
|
|
end;
|
|
|
|
|
|
finalization
|
|
if CRDebugging<>nil then
|
|
CRDebugging.Free;
|
|
|
|
end.
|