cheat-engine/Cheat Engine/CEDebugger.pas
cheatengine@gmail.com 0f35a52416 move the processid and handle from cefuncproc to processhandlerunit
move the processlist function from cefuncproc to it's own unit
start work on the jni library for java
2014-09-08 12:00:14 +00:00

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.