cheat-engine/Cheat Engine/debuggertypedefinitions.pas
2023-10-20 17:32:15 +02:00

347 lines
8.6 KiB
ObjectPascal
Executable file

unit debuggertypedefinitions;
{$mode delphi}
interface
uses
{$ifdef darwin}
macport,
{$endif}
{$ifdef windows}
Windows,
{$endif}
Classes, SysUtils,
cefuncproc, NewKernelHandler, commonTypeDefs;
type
TNewProcedureData = record
processid: dword;
processhandle: dword;
filehandle: dword;
EntryPoint: dword;
OriginalEntryByte: byte;
DotNet: boolean;
FirstBreak: boolean;
end;
type
TDebugRegisterType = (drtAny, drtExecute, drtWatch);
type
TContinueOption = (co_run=0, co_stepinto=1, co_stepover=2, co_runtill=3);
type
TBreakpointMethod = (bpmInt3=0, bpmDebugRegister=1, bpmException=2, bpmDBVM=3, bpmDBVMNative=4, bpmGDB=5);
type
TBreakOption = (bo_Break = 0, bo_ChangeRegister = 1, bo_FindCode = 2, bo_FindWhatCodeAccesses = 3, bo_BreakAndTrace=4, bo_OnBreakpoint=5, bo_ChangeRegisterEx = 6);
TBreakPointAction = TBreakOption;
type
TBreakpointTrigger = (bptExecute=0, bptAccess=1, bptWrite=2);
{$ifdef cpu32}
M128A= record
low,high: qword;
end;
{$endif}
TXMMFIELDS=array [0..3] of DWORD;
PXMMFIELDS=^TXMMFIELDS;
TRegisterModificationFloatList=bitpacked record
change_fp0: 0..1;
change_fp1: 0..1;
change_fp2: 0..1;
change_fp3: 0..1;
change_fp4: 0..1;
change_fp5: 0..1;
change_fp6: 0..1;
change_fp7: 0..1;
end;
PRegisterModificationFloatList=^TRegisterModificationFloatList;
TRegisterModificationXMMListSingleEntry=bitpacked record
change_part1: 0..1;
change_part2: 0..1;
change_part3: 0..1;
change_part4: 0..1;
end;
PRegisterModificationXMMListSingleEntry=^TRegisterModificationXMMListSingleEntry;
type
tregistermodificationBP32 = record
address: uint_ptr; //addres to break on
change_eax: BOOL;
change_ebx: BOOL;
change_ecx: BOOL;
change_edx: BOOL;
change_esi: BOOL;
change_edi: BOOL;
change_ebp: BOOL;
change_esp: BOOL;
change_eip: BOOL;
change_cf: BOOL;
change_pf: BOOL;
change_af: BOOL;
change_zf: BOOL;
change_sf: BOOL;
change_of: BOOL;
new_eax: dword;
new_ebx: dword;
new_ecx: dword;
new_edx: dword;
new_esi: dword;
new_edi: dword;
new_ebp: dword;
new_esp: dword;
new_eip: dword;
new_cf: BOOL;
new_pf: BOOL;
new_af: BOOL;
new_zf: BOOL;
new_sf: BOOL;
new_of: BOOL;
change_FP: BYTE; //binary, each bit is a new FP
new_FP0: double;
new_FP1: double;
new_FP2: double;
new_FP3: double;
new_FP4: double;
new_FP5: double;
new_FP6: double;
new_FP7: double;
change_XMM: DWORD; //binary, each nibble is an XMM register, and each bit of the nibble is a dword part of the xmm reg
new_XMM0: TXMMFIELDS;
new_XMM1: TXMMFIELDS;
new_XMM2: TXMMFIELDS;
new_XMM3: TXMMFIELDS;
new_XMM4: TXMMFIELDS;
new_XMM5: TXMMFIELDS;
new_XMM6: TXMMFIELDS;
new_XMM7: TXMMFIELDS;
usesDouble: BYTE; //each bit specifies an xmm field what weas edited using a double specifier
end;
type
PRegisterModificationBP32 = ^TRegisterModificationBP32;
type
tregistermodificationBP64 = record
address: uint_ptr; //addres to break on
change_eax: BOOL;
change_ebx: BOOL;
change_ecx: BOOL;
change_edx: BOOL;
change_esi: BOOL;
change_edi: BOOL;
change_ebp: BOOL;
change_esp: BOOL;
change_eip: BOOL;
change_r8: BOOL;
change_r9: BOOL;
change_r10: BOOL;
change_r11: BOOL;
change_r12: BOOL;
change_r13: BOOL;
change_r14: BOOL;
change_r15: BOOL;
change_cf: BOOL;
change_pf: BOOL;
change_af: BOOL;
change_zf: BOOL;
change_sf: BOOL;
change_of: BOOL;
new_eax: ptrUint;
new_ebx: ptrUint;
new_ecx: ptrUint;
new_edx: ptrUint;
new_esi: ptrUint;
new_edi: ptrUint;
new_ebp: ptrUint;
new_esp: ptrUint;
new_eip: ptrUint;
new_r8: ptrUint;
new_r9: ptrUint;
new_r10: ptrUint;
new_r11: ptrUint;
new_r12: ptrUint;
new_r13: ptrUint;
new_r14: ptrUint;
new_r15: ptrUint;
new_cf: BOOL;
new_pf: BOOL;
new_af: BOOL;
new_zf: BOOL;
new_sf: BOOL;
new_of: BOOL;
change_FP: BYTE; //binary, each bit is a new FP
new_FP0: M128A; //only need the 10 bytes
new_FP1: M128A;
new_FP2: M128A;
new_FP3: M128A;
new_FP4: M128A;
new_FP5: M128A;
new_FP6: M128A;
new_FP7: M128A;
change_XMM: QWORD; //binary, each nibble is an XMM register, and each bit of the nibble is a dword part of the xmm reg
new_XMM0: TXMMFIELDS;
new_XMM1: TXMMFIELDS;
new_XMM2: TXMMFIELDS;
new_XMM3: TXMMFIELDS;
new_XMM4: TXMMFIELDS;
new_XMM5: TXMMFIELDS;
new_XMM6: TXMMFIELDS;
new_XMM7: TXMMFIELDS;
new_XMM8: TXMMFIELDS;
new_XMM9: TXMMFIELDS;
new_XMM10: TXMMFIELDS;
new_XMM11: TXMMFIELDS;
new_XMM12: TXMMFIELDS;
new_XMM13: TXMMFIELDS;
new_XMM14: TXMMFIELDS;
new_XMM15: TXMMFIELDS;
//for gui purposes only:
usesDouble: WORD; //each bit specifies an xmm field what was edited using a double specifier
end;
type
PRegisterModificationBP64 = ^TRegisterModificationBP64;
{$ifdef CPU64}
type
TRegisterModificationBP = TRegisterModificationBP64;
type
PRegisterModificationBP = PRegisterModificationBP64;
{$else}
type
TRegisterModificationBP = TRegisterModificationBP32;
type
PRegisterModificationBP = PRegisterModificationBP32;
{$endif}
TRegisterModificationBPEx=record
address: ptruint;
mask: pointer; //same size as the context. Bit 1 means it gets changed, else unchanged
context: Pointer; //full context to set. Bits get set according to the bits in the contextmask (currentcontext.field=(currentcontext.field and (not mask.field)) or context.field
end;
PRegisterModificationBPEx = ^TRegisterModificationBPEx;
// TBreakpointList=TFPGList<PBreakpoint>;
function BreakPointTriggerIsWatchpoint(bpt: TBreakpointTrigger): boolean; inline;
function breakpointTriggerToString(bpt: TBreakpointTrigger): string;
function breakpointMethodToString(bpm: TBreakpointMethod): string;
function breakpointActionToString(bpa: TBreakpointAction): string;
//kernel debug
function SizeToBreakLength(size: integer): TBreakLength;
function BreakPointTriggerToBreakType(bpt: TBreakpointTrigger): TBreakType;
var int3byte: byte = $cc;
implementation
//this is a new one... (rebuild as usual)
resourcestring
rsOnExecute = 'On Execute';
rsOnWrite = 'On Write';
rsOnReadWrite = 'On Read/Write';
rsSoftwareBreakpoint = 'Software Breakpoint';
rsHardwareBreakpoint = 'Hardware Breakpoint';
rsExceptionBreakpoint = 'Exception Breakpoint';
rsDBVMBreakpoint = 'DBVM Breakpoint';
rsDBVMNativeBreakpoint = 'DBVM-Level Breakpoint';
rsBreak = 'Break';
rsChangeReg = 'Change reg';
rsFindCode = 'Find code';
rsFindCodeAccess = 'Find code access';
rsBreakAndTrace = 'Break and trace';
function SizeToBreakLength(size: integer): TBreakLength;
begin
case size of
1: result:=bl_1byte;
2: result:=bl_2byte;
4: result:=bl_4byte;
8: result:=bl_8byte;
else
result:=bl_1byte;
end;
end;
function BreakPointTriggerIsWatchpoint(bpt: TBreakpointTrigger): boolean; inline;
begin
result:=bpt in [bptAccess, bptWrite];
end;
function BreakPointTriggerToBreakType(bpt: TBreakpointTrigger): TBreakType;
begin
case bpt of
bptExecute: result:=bt_OnInstruction;
bptAccess: result:=bt_OnReadsAndWrites;
bptWrite: result:=bt_OnWrites;
else
result:=bt_OnInstruction;
end;
end;
function breakpointTriggerToString(bpt: TBreakpointTrigger): string;
begin
case bpt of
bptExecute: result:=rsOnExecute;
bptWrite: result:=rsOnWrite;
bptAccess: result:=rsOnReadWrite;
else
result:='Error';
end;
end;
function BreakpointMethodToString(bpm: TBreakpointMethod): string;
begin
case bpm of
bpmInt3: result:=rsSoftwareBreakpoint;
bpmDebugRegister: result:=rsHardwareBreakpoint;
bpmException: result:=rsExceptionBreakpoint;
bpmDBVM: result:=rsDBVMBreakpoint;
bpmDBVMNative: result:=rsDBVMNativeBreakpoint;
else
result:='Error';
end;
end;
function breakpointActionToString(bpa: TBreakpointAction): string;
begin
case bpa of
bo_Break: result:=rsBreak;
bo_ChangeRegister: result:=rsChangeReg;
bo_FindCode: result:=rsFindCode;
bo_FindWhatCodeAccesses: result:=rsFindCodeAccess;
bo_BreakAndTrace: result:=rsBreakAndTrace;
else
result:='Error';
end;
end;
end.