cheat-engine/Cheat Engine/NewKernelHandler.pas

2507 lines
77 KiB
ObjectPascal
Executable File

unit NewKernelHandler;
{$MODE Delphi}
interface
{$ifdef darwin}
uses SysUtils, MacOSAll, MacOSXPosix, macport, macportdefines;
{$else}
uses jwawindows, windows,LCLIntf,sysutils, dialogs, classes, controls,
{$ifndef STANDALONECH}dbk32functions, vmxfunctions,debug, multicpuexecution,globals,{$endif} contnrs, Clipbrd;
{$endif}
const dbkdll='DBK32.dll';
{$ifdef windows}
const
VQE_PAGEDONLY=1;
VQE_DIRTYONLY=2;
VQE_NOSHARED=4 ;
type
PPROCESSENTRY32 = ^PROCESSENTRY32;
tagPROCESSENTRY32 = record
dwSize: DWORD;
cntUsage: DWORD;
th32ProcessID: DWORD; // this process
th32DefaultHeapID: ULONG_PTR;
th32ModuleID: DWORD; // associated exe
cntThreads: DWORD;
th32ParentProcessID: DWORD; // this process's parent process
pcPriClassBase: LONG; // Base priority of process's threads
dwFlags: DWORD;
szExeFile: array [0..MAX_PATH - 1] of Char; // Path
end;
PROCESSENTRY32 = tagPROCESSENTRY32;
LPPROCESSENTRY32 = ^PROCESSENTRY32;
TProcessEntry32 = PROCESSENTRY32;
PMODULEENTRY32 = ^MODULEENTRY32;
tagMODULEENTRY32 = record
dwSize: DWORD;
th32ModuleID: DWORD; // This module
th32ProcessID: DWORD; // owning process
GlblcntUsage: DWORD; // Global usage count on the module
ProccntUsage: DWORD; // Module usage count in th32ProcessID's context
modBaseAddr: LPBYTE; // Base address of module in th32ProcessID's context
modBaseSize: DWORD; // Size in bytes of module starting at modBaseAddr
hModule: HMODULE; // The hModule of this module in th32ProcessID's context
szModule: array [0..MAX_MODULE_NAME32] of Char;
szExePath: array [0..MAX_PATH - 1] of Char;
end;
MODULEENTRY32 = tagMODULEENTRY32;
LPMODULEENTRY32 = ^MODULEENTRY32;
TModuleEntry32 = MODULEENTRY32;
{$ifdef cpu32}
const
CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 or $00000020);
type
M128A = record
Low: ULONGLONG;
High: LONGLONG;
end;
_M128A = M128A;
TM128A = M128A;
PM128A = TM128A;
{$endif}
type
XMM_SAVE_AREA32 = record
ControlWord: WORD;
StatusWord: WORD;
TagWord: BYTE;
Reserved1: BYTE;
ErrorOpcode: WORD;
ErrorOffset: DWORD;
ErrorSelector: WORD;
Reserved2: WORD;
DataOffset: DWORD;
DataSelector: WORD;
Reserved3: WORD;
MxCsr: DWORD;
MxCsr_Mask: DWORD;
FloatRegisters: array[0..7] of M128A;
XmmRegisters: array[0..15] of M128A;
Reserved4: array[0..95] of BYTE;
end;
_XMM_SAVE_AREA32 = XMM_SAVE_AREA32;
TXmmSaveArea = XMM_SAVE_AREA32;
PXmmSaveArea = ^TXmmSaveArea;
{$ifdef cpu64}
const
CONTEXT_EXTENDED_REGISTERS = 0;
// CONTEXT_XSTATE = (CONTEXT_AMD64 or $00100040);
CONTEXT_XSTATE = (CONTEXT_AMD64 or $00000040);
const
LEGACY_SAVE_AREA_LENGTH = sizeof(XMM_SAVE_AREA32);
type
CONTEXT = packed record
//
// Register parameter home addresses.
//
// N.B. These fields are for convience - they could be used to extend the
// context record in the future.
//
P1Home: DWORD64;
P2Home: DWORD64;
P3Home: DWORD64;
P4Home: DWORD64;
P5Home: DWORD64;
P6Home: DWORD64;
//
// Control flags.
//
ContextFlags: DWORD;
MxCsr: DWORD;
//
// Segment Registers and processor flags.
//
SegCs: WORD;
SegDs: WORD;
SegEs: WORD;
SegFs: WORD;
SegGs: WORD;
SegSs: WORD;
EFlags: DWORD;
//
// Debug registers
//
Dr0: DWORD64;
Dr1: DWORD64;
Dr2: DWORD64;
Dr3: DWORD64;
Dr6: DWORD64;
Dr7: DWORD64;
//
// Integer registers.
//
Rax: DWORD64;
Rcx: DWORD64;
Rdx: DWORD64;
Rbx: DWORD64;
Rsp: DWORD64;
Rbp: DWORD64;
Rsi: DWORD64;
Rdi: DWORD64;
R8: DWORD64;
R9: DWORD64;
R10: DWORD64;
R11: DWORD64;
R12: DWORD64;
R13: DWORD64;
R14: DWORD64;
R15: DWORD64;
//
// Program counter.
//
Rip: DWORD64;
//
// Floating point state.
//
FltSave: XMM_SAVE_AREA32; // MWE: only translated the FltSave part of the union
(*
union {
XMM_SAVE_AREA32 FltSave;
struct {
M128A Header[2];
M128A Legacy[8];
M128A Xmm0;
M128A Xmm1;
M128A Xmm2;
M128A Xmm3;
M128A Xmm4;
M128A Xmm5;
M128A Xmm6;
M128A Xmm7;
M128A Xmm8;
M128A Xmm9;
M128A Xmm10;
M128A Xmm11;
M128A Xmm12;
M128A Xmm13;
M128A Xmm14;
M128A Xmm15;
};
};
*)
//
// Vector registers.
//
VectorRegister: array[0..25] of m128a;
VectorControl: DWORD64;
//
// Special debug control registers.
//
DebugControl: DWORD64;
LastBranchToRip: DWORD64;
LastBranchFromRip: DWORD64;
LastExceptionToRip: DWORD64;
LastExceptionFromRip: DWORD64;
end;
TCONTEXT=CONTEXT;
PCONTEXT=^TCONTEXT;
_CONTEXT=CONTEXT;
{$endif}
{$endif}
type
TARMCONTEXT=packed record
R0: DWORD;
R1: DWORD;
R2: DWORD;
R3: DWORD;
R4: DWORD;
R5: DWORD;
R6: DWORD;
R7: DWORD;
R8: DWORD;
R9: DWORD;
R10: DWORD;
FP: DWORD; //R11
IP: DWORD; //R12
SP: DWORD; //R13
LR: DWORD; //R14
PC: DWORD; //R15
CPSR: DWORD;
ORIG_R0: DWORD;
fpu: array [0..31] of uint64;
fpureg: dword;
end;
PARMCONTEXT=^TARMCONTEXT;
TARM64CONTEXT_REGISTERS=packed record
case boolean of
true: (
X0: QWORD;
X1: QWORD;
X2: QWORD;
X3: QWORD;
X4: QWORD;
X5: QWORD;
X6: QWORD;
X7: QWORD;
X8: QWORD;
X9: QWORD;
X10: QWORD;
X11: QWORD;
X12: QWORD;
X13: QWORD;
X14: QWORD;
X15: QWORD;
X16: QWORD;
X17: QWORD;
X18: QWORD;
X19: QWORD;
X20: QWORD;
X21: QWORD;
X22: QWORD;
X23: QWORD;
X24: QWORD;
X25: QWORD;
X26: QWORD;
X27: QWORD;
X28: QWORD;
X29: QWORD;
X30: QWORD; );
false: (
X: Array [0..30] of QWORD;
);
end;
{$ifndef darwin} //defined in macport.pas
TARM64CONTEXT=record
regs: TARM64CONTEXT_REGISTERS;
SP: QWORD;
PC: QWORD;
PSTATE: QWORD;
fp: record
vregs: array [0..31] of m128a; // __uint128_t vregs[32];
fpsr: UINT32; // __u32 fpsr;
fpcr: UINT32; // __u32 fpcr;
reserved: array [0..1] of UINT32; // __u32 __reserved[2];
end;
end;
PARM64CONTEXT=^TARM64CONTEXT;
{$endif}
{$ifdef windows}
type
//credits to jedi code library for filling in the "extended registers"
TJclMMContentType = (mt8Bytes, mt4Words, mt2DWords, mt1QWord, mt2Singles, mt1Double);
TJclMMRegister = packed record
case TJclMMContentType of
mt8Bytes:
(Bytes: array [0..7] of Byte;);
mt4Words:
(Words: array [0..3] of Word;);
mt2DWords:
(DWords: array [0..1] of Cardinal;);
mt1QWord:
(QWords: Int64;);
mt2Singles:
(Singles: array [0..1] of Single;);
mt1Double:
(Doubles: double;);
end;
TJclFPUContentType = (ftExtended, ftMM);
TJclFPUData = packed record
case TJclFPUContentType of
ftExtended:
(FloatValue: Extended;);
ftMM:
(MMRegister: TJclMMRegister;
Reserved: Word;);
end;
TJclFPURegister = packed record
Data: TJclFPUData;
Reserved: array [0..5] of Byte;
end;
TJclFPURegisters = array [0..7] of TJclFPURegister;
TJclXMMContentType = (xt16Bytes, xt8Words, xt4DWords, xt2QWords, xt4Singles, xt2Doubles);
TJclXMMRegister = packed record
case TJclXMMContentType of
xt16Bytes:
(Bytes: array [0..15] of Byte;);
xt8Words:
(Words: array [0..7] of Word;);
xt4DWords:
(DWords: array [0..3] of Cardinal;);
xt2QWords:
(QWords: array [0..1] of Int64;);
xt4Singles:
(Singles: array [0..3] of Single;);
xt2Doubles:
(Doubles: array [0..1] of Double;);
end;
TJclProcessorSize = (ps32Bits, ps64Bits);
TJclXMMRegisters = packed record
case TJclProcessorSize of
ps32Bits:
(LegacyXMM: array [0..7] of TJclXMMRegister;
LegacyReserved: array [0..127] of Byte;);
ps64Bits:
(LongXMM: array [0..15] of TJclXMMRegister;);
end;
TextendedRegisters = packed record //fxsave
//extended registers
FCW: Word; // bytes from 0 to 1
FSW: Word; // bytes from 2 to 3
FTW: Byte; // byte 4
Reserved1: Byte; // byte 5
FOP: Word; // bytes from 6 to 7
FpuIp: Cardinal; // bytes from 8 to 11
CS: Word; // bytes from 12 to 13
Reserved2: Word; // bytes from 14 to 15
FpuDp: Cardinal; // bytes from 16 to 19
DS: Word; // bytes from 20 to 21
Reserved3: Word; // bytes from 22 to 23
MXCSR: Cardinal; // bytes from 24 to 27
MXCSRMask: Cardinal; // bytes from 28 to 31
FPURegisters: TJclFPURegisters; // bytes from 32 to 159
XMMRegisters: TJclXMMRegisters; // bytes from 160 to 415
Reserved4: array [416..511] of Byte; // bytes from 416 to 511
end;
type
{$ifdef cpu64}
_CONTEXT32 = packed record
{$else}
_CONTEXT = packed record
{$endif}
ContextFlags: DWORD;
Dr0: DWORD;
Dr1: DWORD;
Dr2: DWORD;
Dr3: DWORD;
Dr6: DWORD;
Dr7: DWORD;
FloatSave: TFloatingSaveArea;
SegGs: DWORD;
SegFs: DWORD;
SegEs: DWORD;
SegDs: DWORD;
Edi: DWORD;
Esi: DWORD;
Ebx: DWORD;
Edx: DWORD;
Ecx: DWORD;
Eax: DWORD;
Ebp: DWORD;
Eip: DWORD;
SegCs: DWORD;
EFlags: DWORD;
Esp: DWORD;
SegSs: DWORD;
ext: TXmmSaveArea;
end;
{$ifdef cpu64}
CONTEXT32=_CONTEXT32;
TContext32=CONTEXT32;
PContext32 = ^TContext32;
{$else}
CONTEXT=_CONTEXT;
CONTEXT32=_CONTEXT;
PCONTEXT32=^CONTEXT32;
TContext=CONTEXT;
PContext = ^TContext;
{$endif}
type TDebuggerstate=packed record
threadid: uint64;
causedbydbvm: uint64;
eflags : uint64;
eax : uint64;
ebx : uint64;
ecx : uint64;
edx : uint64;
esi : uint64;
edi : uint64;
ebp : uint64;
esp : uint64;
eip : uint64;
r8 : uint64;
r9 : uint64;
r10 : uint64;
r11 : uint64;
r12 : uint64;
r13 : uint64;
r14 : uint64;
r15 : uint64;
cs : uint64;
ds : uint64;
es : uint64;
fs : uint64;
gs : uint64;
ss : uint64;
dr0 : uint64;
dr1 : uint64;
dr2 : uint64;
dr3 : uint64;
dr6 : uint64;
dr7 : uint64;
fxstate: TextendedRegisters;
LBR_Count: uint64;
LBR: array [0..15] of UINT64;
end;
type PDebuggerstate=^TDebuggerstate;
{$endif}
type TBreakType=(bt_OnInstruction=0,bt_OnWrites=1, bt_OnIOAccess=2, bt_OnReadsAndWrites=3);
type TBreakLength=(bl_1byte=0, bl_2byte=1, bl_8byte=2{Only when in 64-bit}, bl_4byte=3);
{$ifdef windows}
type TEnumDeviceDrivers=function(lpImageBase: LPLPVOID; cb: DWORD; var lpcbNeeded: DWORD): BOOL; stdcall;
type TGetDeviceDriverBaseNameA=function(ImageBase: LPVOID; lpBaseName: LPSTR; nSize: DWORD): DWORD; stdcall;
type TGetDeviceDriverFileName=function(ImageBase: LPVOID; lpFilename: LPTSTR; nSize: DWORD): DWORD; stdcall;
type TGetLargePageMinimum=function: SIZE_T; stdcall;
type TWriteProcessMemory64=function(hProcess: THandle; BaseAddress: UINT64; lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesWritten: ptruint): BOOL; stdcall;
type TReadProcessMemory64=function(hProcess: THandle; lpBaseAddress: UINT64; lpBuffer: pointer; nSize: size_t; var lpNumberOfBytesRead: PTRUINT): BOOL; stdcall;
{$endif}
type TReadProcessMemory=function(hProcess: THandle; lpBaseAddress, lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesRead: PTRUINT): BOOL; stdcall;
type TWriteProcessMemory=function(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesWritten: PTRUINT): BOOL; stdcall;
type TGetThreadContext=function(hThread: THandle; var lpContext: TContext): BOOL; stdcall;
type TSetThreadContext=function(hThread: THandle; const lpContext: TContext): BOOL; stdcall;
type TOpenProcess=function(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;
{$ifdef windows}
type TWow64GetThreadContext=function(hThread: THandle; var lpContext: CONTEXT32): BOOL; stdcall;
type TWow64SetThreadContext=function(hThread: THandle; const lpContext: CONTEXT32): BOOL; stdcall;
{$ifdef cpu64}
type TGetThreadSelectorEntry=function(hThread: THandle; dwSelector: DWORD; var lpSelectorEntry: TLDTEntry): BOOL; stdcall;
{$endif}
type TSuspendThread=function(hThread: THandle): DWORD; stdcall;
type TResumeThread=function(hThread: THandle): DWORD; stdcall;
type TCreateToolhelp32Snapshot=function(dwFlags, th32ProcessID: DWORD): THandle; stdcall;
type TProcess32First=function(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; stdcall;
type TProcess32Next=function(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; stdcall;
type TThread32First=function (hSnapshot: THandle; var lpte: TThreadEntry32): BOOL; stdcall;
type TThread32Next=function (hSnapshot: THandle; var lpte: TThreadENtry32): BOOL; stdcall;
type TModule32First=function (hSnapshot: THandle; var lpme: TModuleEntry32): BOOL; stdcall;
type TModule32Next=function (hSnapshot: THandle; var lpme: TModuleEntry32): BOOL; stdcall;
type THeap32ListFirst=function (hSnapshot: THandle; var lphl: THeapList32): BOOL; stdcall;
type THeap32ListNext=function (hSnapshot: THandle; var lphl: THeapList32): BOOL; stdcall;
type TIsWow64Process=function (processhandle: THandle; var isWow: BOOL): BOOL; stdcall;
type TWaitForDebugEvent=function(var lpDebugEvent: TDebugEvent; dwMilliseconds: DWORD): BOOL; stdcall;
type TContinueDebugEvent=function(dwProcessId, dwThreadId, dwContinueStatus: DWORD): BOOL; stdcall;
type TDebugActiveProcess=function(dwProcessId: DWORD): BOOL; stdcall;
type TVirtualFreeEx=function(hProcess: HANDLE; lpAddress: LPVOID; dwSize: SIZE_T; dwFreeType: DWORD): BOOL; stdcall;
type TVirtualProtect=function(lpAddress: Pointer; dwSize, flNewProtect: DWORD; var OldProtect: DWORD): BOOL; stdcall;
type TVirtualProtectEx=function(hProcess: THandle; lpAddress: Pointer; dwSize, flNewProtect: DWORD; var OldProtect: DWORD): BOOL; stdcall;
{$endif}
type TVirtualQueryEx=function(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
{$ifdef windows}
type TVirtualAllocEx=function(hProcess: THandle; lpAddress: Pointer; dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
type TCreateRemoteThread=function(hProcess: THandle; lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall;
type TOpenThread=function(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwThreadId:DWORD):THANDLE; stdcall;
type TGetPEProcess=function(ProcessID:DWORD):UINT64; stdcall;
type TGetPEThread=function(Threadid: dword):UINT64; stdcall;
type TGetDebugportOffset=function:DWORD; stdcall;
type TGetThreadsProcessOffset=function: dword; stdcall;
type TGetThreadListEntryOffset=function: dword; stdcall;
type TGetPhysicalAddress=function(hProcess:THandle;lpBaseAddress:pointer;var Address:qword): BOOL; stdcall;
type TGetCR4=function:ptrUint; stdcall;
type TGetCR3=function(hProcess:THANDLE;var CR3: QWORD):BOOL; stdcall;
type TSetCR3=function(hProcess:THANDLE;CR3: ptrUint):BOOL; stdcall;
type TGetCR0=function:ptrUint; stdcall;
type TGetSDT=function:ptrUint; stdcall;
type TGetSDTShadow=function:ptrUint; stdcall;
type TCreateRemoteAPC=function(threadid: dword; lpStartAddress: pointer): THandle; stdcall;
//type TStopDebugging=function: BOOL; stdcall;
//type TStopRegisterChange=function(regnr:integer):BOOL; stdcall;
//type TSetGlobalDebugState=function(state: boolean): BOOL; stdcall;
//type TsetAlternateDebugMethod=function(var int1apihook:dword; var OriginalInt1handler:dword):BOOL; stdcall;
//type TgetAlternateDebugMethod=function:BOOL; stdcall;
//type TChangeRegOnBP=function(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 TDebugProcess=function(processid:dword;address:DWORD;size: byte;debugtype:byte):BOOL; stdcall;
//type TRetrieveDebugData=function(Buffer: pointer):integer; stdcall;
type TGetProcessNameFromID=function(processid:dword; buffer:pchar;buffersize:dword):integer; stdcall;
type TGetProcessNameFromPEProcess=function(peprocess:uint64; buffer:pchar;buffersize:dword):integer; stdcall;
type TStartProcessWatch=function:BOOL;stdcall;
type TWaitForProcessListData=function(processpointer:pointer;threadpointer:pointer;timeout:dword):dword; stdcall;
type TIsValidHandle=function(hProcess:THandle):BOOL; stdcall;
type TGetIDTCurrentThread=function:dword; stdcall;
type TGetIDTs=function(idtstore: pointer; maxidts: integer):integer; stdcall;
type TMakeWritable=function(Address,Size:dword;copyonwrite:boolean): boolean; stdcall;
type TGetLoadedState=function : BOOLEAN; stdcall;
type TDBKSuspendThread=function(ThreadID:dword):boolean; stdcall;
type TDBKResumeThread=function(ThreadID:dword):boolean; stdcall;
type TDBKSuspendProcess=function(ProcessID:dword):boolean; stdcall;
type TDBKResumeProcess=function(ProcessID:dword):boolean; stdcall;
type TKernelAlloc=function(size: dword):pointer; stdcall;
type TKernelAlloc64=function(size: dword):UINT64; stdcall;
type TGetKProcAddress=function(s: pwidechar):pointer; stdcall;
type TGetKProcAddress64=function(s: pwidechar):UINT64; stdcall;
type TGetSDTEntry=function (nr: integer; address: PDWORD; paramcount: PBYTE):boolean; stdcall;
type TGetSSDTEntry=function (nr: integer; address: PDWORD; paramcount: PBYTE):boolean; stdcall;
type TGetGDT=function(var limit: word):dword; stdcall;
type TisDriverLoaded=function(SigningIsTheCause: PBOOL): BOOL; stdcall;
type TLaunchDBVM=procedure(cpuid: integer); stdcall;
type TDBKDebug_ContinueDebugEvent=function(handled: BOOL): boolean; stdcall;
type TDBKDebug_WaitForDebugEvent=function(timeout: dword): boolean; stdcall;
type TDBKDebug_GetDebuggerState=function(state: PDebuggerstate): boolean; stdcall;
type TDBKDebug_SetDebuggerState=function(state: PDebuggerstate): boolean; stdcall;
type TDBKDebug_SetGlobalDebugState=function(state: BOOL): BOOL; stdcall;
type TDBKDebug_SetAbilityToStepKernelCode=function(state: boolean):BOOL; stdcall;
type TDBKDebug_StartDebugging=function(processid:dword):BOOL; stdcall;
type TDBKDebug_StopDebugging=function:BOOL; stdcall;
type TDBKDebug_GD_SetBreakpoint=function(active: BOOL; debugregspot: integer; Address: ptruint; breakType: TBreakType; breakLength: TbreakLength): BOOL; stdcall;
//-----------------------------------DBVM-------------------------------------//
type Tdbvm_version=function: dword; stdcall;
type Tdbvm_changeselectors=function(cs,ss,ds,es,fs,gs: dword): DWORD; stdcall;
type Tdbvm_restore_interrupts=function: DWORD; stdcall;
type Tdbvm_block_interrupts=function: DWORD; stdcall;
type Tdbvm_raise_privilege=function: DWORD; stdcall;
type Tdbvm_read_physical_memory=function(PhysicalAddress: UINT64; destination: pointer; size: integer): dword; stdcall;
type Tdbvm_write_physical_memory=function(PhysicalAddress: UINT64; source: pointer; size: integer): dword; stdcall;
type TVirtualQueryEx_StartCache=function(hProcess: THandle; flags: DWORD): boolean;
type TVirtualQueryEx_EndCache=procedure(hProcess: THandle);
procedure DONTUseDBKQueryMemoryRegion;
procedure DONTUseDBKReadWriteMemory;
procedure DONTUseDBKOpenProcess;
procedure UseDBKQueryMemoryRegion;
procedure UseDBKReadWriteMemory;
procedure UseDBKOpenProcess;
{$endif}
procedure DBKFileAsMemory(fn:string; baseaddress: ptruint=0); overload;
procedure DBKFileAsMemory; overload;
{$ifdef windows}
function VirtualQueryExPhysical(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
procedure DBKPhysicalMemory;
procedure DBKPhysicalMemoryDBVM;
procedure DBKProcessMemory;
procedure LoadDBK32; stdcall;
procedure OutputDebugString(msg: string);
procedure NeedsDBVM(Reason: string='');
{$endif}
function loaddbvmifneeded(reason:string=''): BOOL; stdcall;
function isRunningDBVM: boolean;
function isDBVMCapable: boolean;
function hasEPTSupport: boolean;
{$ifdef windows}
function isIntel: boolean;
function isAMD: boolean;
{$endif}
function Is64bitOS: boolean;
function Is64BitProcess(processhandle: THandle): boolean;
//I could of course have made it a parameter thing, but I'm lazy
function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: PTRUINT): BOOL; stdcall;
function ReadProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesRead: PTRUINT): BOOL; stdcall;
function VirtualQueryEx(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
{$ifdef windows}
function VirtualToPhysicalCR3(cr3: QWORD; VirtualAddress: QWORD; var PhysicalAddress: QWORD): boolean;
function ReadProcessMemoryCR3(cr3: QWORD; lpBaseAddress, lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesRead: PTRUINT): BOOL; stdcall;
function WriteProcessMemoryCR3(cr3: QWORD; lpBaseAddress, lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: PTRUINT): BOOL; stdcall;
function VirtualQueryExCR3(cr3: QWORD; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
function GetPageInfoCR3(cr3: QWORD; VirtualAddress: ptruint; out lpBuffer: TMemoryBasicInformation): boolean;
function GetNextReadablePageCR3(cr3: QWORD; VirtualAddress: ptruint; out ReadableVirtualAddress: ptruint): boolean;
{$endif}
var
{$ifdef windows}
EnumDeviceDrivers :TEnumDeviceDrivers;
GetDeviceDriverBaseNameA:TGetDeviceDriverBaseNameA;
GetDeviceDriverFileName :TGetDeviceDriverFileName;
{$endif}
{$ifdef windows}
ReadProcessMemory64 :TReadProcessMemory64;
{$endif}
ReadProcessMemoryActual :TReadProcessMemory;
WriteProcessMemoryActual :TWriteProcessMemory;
defaultRPM: pointer;
defaultWPM: pointer;
//WriteProcessMemory64 :TWriteProcessMemory64;
GetThreadContext :TGetThreadContext;
SetThreadContext :TSetThreadContext;
OpenProcess :TOpenProcess;
{$ifdef windows}
Wow64GetThreadContext :TWow64GetThreadContext;
Wow64SetThreadContext :TWow64SetThreadContext;
{$ifdef cpu64}
GetThreadSelectorEntry: TGetThreadSelectorEntry;
{$endif}
SuspendThread :TSuspendThread;
ResumeThread :TResumeThread;
CreateToolhelp32Snapshot: TCreateToolhelp32Snapshot;
Process32First :TProcess32First;
Process32Next :TProcess32Next;
Thread32First :TThread32First;
Thread32Next :TThread32Next;
Module32First :TModule32First;
Module32Next :TModule32Next;
Heap32ListFirst :THeap32ListFirst;
Heap32ListNext :THeap32ListNext;
IsWow64Process :TIsWow64Process;
WaitForDebugEvent :TWaitForDebugEvent;
ContinueDebugEvent :TContinueDebugEvent;
DebugActiveProcess :TDebugActiveProcess;
GetLargePageMinimum :TGetLargePageMinimum;
VirtualProtect :TVirtualProtect;
VirtualProtectEx :TVirtualProtectEx;
{$endif}
VirtualQueryExActual :TVirtualQueryEx;
{$ifdef windows}
VirtualAllocEx :TVirtualAllocEx;
VirtualFreeEx :TVirtualFreeEx;
CreateRemoteThread :TCreateRemoteThread;
OpenThread :TOpenThread;
// GetPEProcess :TGetPEProcess;
// GetPEThread :TGetPEThread;
GetThreadsProcessOffset:TGetThreadsProcessOffset;
GetThreadListEntryOffset:TGetThreadListEntryOffset;
GetDebugportOffset :TGetDebugportOffset;
GetPhysicalAddress :TGetPhysicalAddress;
GetCR4 :TGetCR4;
GetCR3 :TGetCR3;
//SetCR3 :TSetCR3;
GetCR0 :TGetCR0;
GetSDT :TGetSDT;
GetSDTShadow :TGetSDTShadow;
// setAlternateDebugMethod: TsetAlternateDebugMethod;
// getAlternateDebugMethod: TgetAlternateDebugMethod;
// SetGlobalDebugState :TSetGlobalDebugState;
// DebugProcess :TDebugProcess;
// ChangeRegOnBP :TChangeRegOnBP;
// RetrieveDebugData :TRetrieveDebugData;
// StopDebugging :TStopDebugging;
// StopRegisterChange :TStopRegisterChange;
StartProcessWatch :TStartProcessWatch;
WaitForProcessListData:TWaitForProcessListData;
GetProcessNameFromID :TGetProcessNameFromID;
GetProcessNameFromPEProcess:TGetProcessNameFromPEProcess;
//KernelOpenProcess :TOpenProcess;
// KernelReadProcessMemory :TReadProcessMemory;
// KernelReadProcessMemory64 :TReadProcessMemory64;
// KernelWriteProcessMemory:TWriteProcessMemory;
// KernelVirtualAllocEx :TVirtualAllocEx;
IsValidHandle :TIsValidHandle;
GetIDTCurrentThread :TGetIDTCurrentThread;
GetIDTs :TGetIDTs;
MakeWritable :TMakeWritable;
GetLoadedState :TGetLoadedState;
DBKSuspendThread :TDBKSuspendThread;
DBKResumeThread :TDBKResumeThread;
DBKSuspendProcess :TDBKSuspendProcess;
DBKResumeProcess :TDBKResumeProcess;
KernelAlloc :TKernelAlloc;
KernelAlloc64 :TKernelAlloc64;
GetKProcAddress :TGetKProcAddress;
GetKProcAddress64 :TGetKProcAddress64;
GetSDTEntry :TGetSDTEntry;
GetSSDTEntry :TGetSSDTEntry;
isDriverLoaded :TisDriverLoaded;
LaunchDBVM :TLaunchDBVM;
ReadPhysicalMemory :TReadProcessMemory;
WritePhysicalMemory :TWriteProcessMemory;
CreateRemoteAPC :TCreateRemoteAPC;
GetGDT :TGetGDT;
DBKDebug_ContinueDebugEvent : TDBKDebug_ContinueDebugEvent;
DBKDebug_WaitForDebugEvent : TDBKDebug_WaitForDebugEvent;
DBKDebug_GetDebuggerState : TDBKDebug_GetDebuggerState;
DBKDebug_SetDebuggerState : TDBKDebug_SetDebuggerState;
DBKDebug_SetGlobalDebugState: TDBKDebug_SetGlobalDebugState;
DBKDebug_SetAbilityToStepKernelCode: TDBKDebug_SetAbilityToStepKernelCode;
DBKDebug_StartDebugging : TDBKDebug_StartDebugging;
DBKDebug_StopDebugging : TDBKDebug_StopDebugging;
DBKDebug_GD_SetBreakpoint : TDBKDebug_GD_SetBreakpoint;
closeHandle : function (hObject:HANDLE):WINBOOL; stdcall;
GetLogicalProcessorInformation: function(Buffer: PSYSTEM_LOGICAL_PROCESSOR_INFORMATION; ReturnedLength: PDWORD): BOOL; stdcall;
PrintWindow : function (hwnd: HWND; hdcBlt: HDC; nFlags: UINT): BOOL; stdcall;
ChangeWindowMessageFilter : function (msg: Cardinal; Action: Dword): BOOL; stdcall;
VirtualQueryEx_StartCache: TVirtualQueryEx_StartCache;
VirtualQueryEx_EndCache: TVirtualQueryEx_EndCache;
GetRegionInfo: function (hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD; var mapsline: string): DWORD; stdcall;
SetProcessDEPPolicy: function(dwFlags: DWORD): BOOL; stdcall;
GetProcessDEPPolicy: function(h: HANDLE; dwFlags: PDWORD; permanent: PBOOL):BOOL; stdcall;
GetProcessId: function(h: HANDLE): PTRUINT; stdcall;
{ just include vmxfunctions
//dbvm ce000000+
dbvm_changeselectors :Tdbvm_changeselectors;
dbvm_block_interrupts :Tdbvm_block_interrupts;
dbvm_restore_interrupts :Tdbvm_restore_interrupts;
dbvm_raise_privilege :Tdbvm_raise_privilege;
//dbvm ce000004+
dbvm_read_physical_memory: Tdbvm_read_physical_memory;
dbvm_write_physical_memory: Tdbvm_write_physical_memory; }
{$endif}
var
{$ifdef windows}
WindowsKernel: Thandle;
NTDLLHandle: THandle;
{$endif}
//DarkByteKernel: Thandle;
DBKLoaded: boolean;
Usephysical: boolean;
UseFileAsMemory: boolean;
usephysicaldbvm: boolean;
usedbkquery:boolean;
DBKReadWrite: boolean;
DenyList:boolean;
DenyListGlobal: boolean;
ModuleListSize: integer;
ModuleList: pointer;
MAXPHYADDR: byte; //number of bits a physical address can be made up of
MAXPHYADDRMASK: QWORD=QWORD($fffffffff); //mask to AND with a physical address to strip invalid bits
MAXPHYADDRMASKPB: QWORD=QWORD($ffffff000); //same as MAXPHYADDRMASK but also aligns it to a page boundary
MAXPHYADDRMASKPBBIG: QWORD=QWORD($fffe00000);
MAXLINEARADDR: byte;//number of bits in a virtual address. All bits after it have to match
MAXLINEARADDRTEST: QWORD;
MAXLINEARADDRMASK: QWORD;
implementation
{$ifndef JNI}
{$ifndef STANDALONECH}
uses
{$ifdef cemain}
plugin,
dbvmPhysicalMemoryHandler, //'' for physical mem
{$endif}
Filehandler, //so I can let readprocessmemory point to ReadProcessMemoryFile in filehandler
autoassembler, frmEditHistoryUnit, frmautoinjectunit, cpuidUnit, MemoryBrowserFormUnit;
{$endif}
{$endif}
resourcestring
rsToUseThisFunctionYouWillNeedToRunDBVM = 'To use this function you will need to run DBVM. There is a high chance running DBVM can crash your system and make '
+'you lose your data(So don''t forget to save first). Do you want to run DBVM?';
rsDidNotLoadDBVM = 'I don''t know what you did, you didn''t crash, but you also didn''t load DBVM';
rsPleaseRebootAndPressF8BeforeWindowsBoots = 'Please reboot and press f8 before windows boots. Then enable unsigned drivers. Alternatively, you could buy yourself a business '
+'class certificate and sign the driver yourself (or try debug signing)';
rsTheDriverNeedsToBeLoadedToBeAbleToUseThisFunction = 'The driver needs to be loaded to be able to use this function.';
rsYourCpuMustBeAbleToRunDbvmToUseThisFunction = 'Your cpu must be able to run dbvm to use this function';
rsCouldnTBeOpened = '%s couldn''t be opened';
rsDBVMIsNotLoadedThisFeatureIsNotUsable = 'DBVM is not loaded. This feature is not usable';
{$ifndef JNI}
function verifyAddress(a: qword): boolean; inline;
begin
result:=false;
if (a and MAXLINEARADDRTEST)>0 then
begin
//bits MAXLINEARADDR to 64 need to be 1
result:=(a and MAXLINEARADDRMASK) = MAXLINEARADDRMASK;
end
else
begin
//bits MAXLINEARADDR to 64 need to be 0
result:=(a and MAXLINEARADDRMASK) = 0;
end;
end;
{$ifdef windows}
function pageEntryToProtection(entry: qword): dword;
var r,w,x: boolean;
begin
r:=(entry and 1)=1; //present
w:=(entry and 2)=2; //writable
x:=not ((entry and (qword(1) shl 63))=(qword(1) shl 63)); //no execute
if not r then exit(PAGE_NOACCESS);
if w then
begin
if x then
exit(PAGE_EXECUTE_READWRITE)
else
exit(PAGE_READWRITE);
end
else
begin
if x then
exit(PAGE_EXECUTE_READ)
else
exit(PAGE_READONLY);
end;
end;
function GetNextReadablePageCR3(cr3: QWORD; VirtualAddress: ptruint; out ReadableVirtualAddress: ptruint): boolean;
var
pml4index: integer;
pagedirptrindex: integer;
pagedirindex: integer;
pagetableindex: integer;
offset: integer;
pml4entry: QWORD;
pagedirptrentry: QWORD;
pagedirentry: qword;
pagetableentry: qword;
pml4page: array [0..512] of qword;
pagedirptrpage: array [0..512] of qword;
pagedirpage: array [0..512] of qword;
pagetablepage: array [0..512] of qword;
x: PTRUINT;
found: boolean=false;
begin
cr3:=cr3 and MAXPHYADDRMASKPB;
result:=false;
pml4index:=(VirtualAddress shr 39) and $1ff;
pagedirptrindex:=(VirtualAddress shr 30) and $1ff;
pagedirindex:=(VirtualAddress shr 21) and $1ff;
pagetableindex:=(VirtualAddress shr 12) and $1ff;
if ReadPhysicalMemory(0,pointer(cr3),@pml4page,4096,x) then
begin
while pml4index<512 do
begin
if (pml4page[pml4index] and 1)=1 then
begin
x:=pml4page[pml4index] and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(x),@pagedirptrpage,4096,x) then
begin
while pagedirptrindex<512 do
begin
if (pagedirptrpage[pagedirptrindex] and 1)=1 then
begin
x:=pagedirptrpage[pagedirptrindex] and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(x),@pagedirpage,4096,x) then
begin
while pagedirindex<512 do
begin
if (pagedirpage[pagedirindex] and 1)=1 then
begin
//present
if (pagedirpage[pagedirindex] and (1 shl 7))=(1 shl 7) then
begin
if (pml4index and (1<<8))=(1<<8) then
pml4index:=pml4index or ((qword($ffffffffffffffff) shl 8));
ReadableVirtualAddress:=(QWORD(pagedirindex) shl 21)+(QWORD(pagedirptrindex) shl 30)+(QWORD(pml4index) shl 39);
exit(true);
end
else
begin
//normal pagedir , go through the pagetables
x:=pagedirpage[pagedirindex] and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(x),@pagetablepage,4096,x) then
while pagetableindex<512 do
begin
if (pagetablepage[pagetableindex] and 1)=1 then
begin
if (pml4index and (1<<8))=(1<<8) then
pml4index:=pml4index or ((qword($ffffffffffffffff) shl 8));
ReadableVirtualAddress:=(QWORD(pagetableindex) shl 12)+(QWORD(pagedirindex) shl 21)+(QWORD(pagedirptrindex) shl 30)+(QWORD(pml4index) shl 39);
exit(true);
end;
inc(pagetableindex);
end;
end;
end;
pagetableindex:=0;
inc(pagedirindex);
end;
end;
end;
pagedirindex:=0;
pagetableindex:=0;
inc(pagedirptrindex);
end;
end; //rpm of pml4page[pml4index]
end;
//still here, nothing found, next pml4 index
pagedirptrindex:=0;
pagedirindex:=0;
pagetableindex:=0;
inc(pml4index);
end; //rpm
end;
//end of pml4 index, fail
end;
function GetPageInfoCR3(cr3: QWORD; VirtualAddress: ptruint; out lpBuffer: TMemoryBasicInformation): boolean;
var
pml4index: integer;
pagedirptrindex: integer;
pagedirindex: integer;
pagetableindex: integer;
offset: integer;
pml4entry: QWORD;
pagedirptrentry: QWORD;
pagedirentry: qword;
pagetableentry: qword;
x: PTRUINT;
begin
cr3:=cr3 and MAXPHYADDRMASKPB;
lpbuffer.BaseAddress:=pointer(VirtualAddress and $fffffffffffff000);
result:=false;
pml4index:=(VirtualAddress shr 39) and $1ff;
pagedirptrindex:=(VirtualAddress shr 30) and $1ff;
pagedirindex:=(VirtualAddress shr 21) and $1ff;
pagetableindex:=(VirtualAddress shr 12) and $1ff;
offset:=VirtualAddress and $fff;
if ReadPhysicalMemory(0,pointer(cr3+pml4index*8),@pml4entry,8,x) then
begin
if (pml4entry and 1)=1 then
begin
pml4entry:=pml4entry and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(pml4entry+pagedirptrindex*8),@pagedirptrentry,8,x) then
begin
if (pagedirptrentry and 1)=1 then
begin
pagedirptrentry:=pagedirptrentry and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(pagedirptrentry+pagedirindex*8),@pagedirentry,8,x) then
begin
if (pagedirentry and 1)=1 then
begin
if (pagedirentry and (1 shl 7))>0 then //PS==1
begin
lpbuffer.AllocationBase:=pointer(VirtualAddress and $ffffffffffe00000);
lpbuffer.AllocationProtect:=PAGE_EXECUTE_READWRITE;
lpbuffer.Protect:=pageEntryToProtection(pagedirentry);
lpbuffer.RegionSize:=$200000-(lpbuffer.BaseAddress-lpbuffer.AllocationBase);
lpbuffer.state:=MEM_COMMIT;
lpbuffer._Type:=MEM_PRIVATE;
exit(true);
end
else
begin
//has pagetable
pagedirentry:=pagedirentry and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(pagedirentry+pagetableindex*8),@pagetableentry,8,x) then
begin
if (pagetableentry and 1)=1 then
begin
lpbuffer.AllocationBase:=pointer(VirtualAddress and $fffffffffffff000);
lpbuffer.AllocationProtect:=PAGE_EXECUTE_READWRITE;
lpbuffer.Protect:=pageEntryToProtection(pagetableentry);
lpbuffer.RegionSize:=4096;
lpbuffer.state:=MEM_COMMIT;
lpbuffer._Type:=MEM_PRIVATE;
exit(true);
end;
end;
end;
end;
end;
end;
end;
end;
end;
end;
function VirtualToPhysicalCR3(cr3: QWORD; VirtualAddress: QWORD; var PhysicalAddress: QWORD): boolean;
var
pml4index: integer;
pagedirptrindex: integer;
pagedirindex: integer;
pagetableindex: integer;
offset: integer;
pml4entry: QWORD;
pagedirptrentry: QWORD;
pagedirentry: qword;
pagetableentry: qword;
x: PTRUINT;
begin
cr3:=cr3 and MAXPHYADDRMASKPB;
result:=false;
pml4index:=(VirtualAddress shr 39) and $1ff;
pagedirptrindex:=(VirtualAddress shr 30) and $1ff;
pagedirindex:=(VirtualAddress shr 21) and $1ff;
pagetableindex:=(VirtualAddress shr 12) and $1ff;
offset:=VirtualAddress and $fff;
if ReadPhysicalMemory(0,pointer(cr3+pml4index*8),@pml4entry,8,x) then
begin
if (pml4entry and 1)=1 then
begin
pml4entry:=pml4entry and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(pml4entry+pagedirptrindex*8),@pagedirptrentry,8,x) then
begin
if (pagedirptrentry and 1)=1 then
begin
pagedirptrentry:=pagedirptrentry and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(pagedirptrentry+pagedirindex*8),@pagedirentry,8,x) then
begin
if (pagedirentry and 1)=1 then
begin
if (pagedirentry and (1 shl 7))>0 then //PS==1
begin
PhysicalAddress:=(pagedirentry and MAXPHYADDRMASKPB) + (VirtualAddress and $1fffff);
exit(true);
end
else
begin
//has pagetable
pagedirentry:=pagedirentry and MAXPHYADDRMASKPB;
if ReadPhysicalMemory(0,pointer(pagedirentry+pagetableindex*8),@pagetableentry,8,x) then
begin
if (pagetableentry and 1)=1 then
begin
PhysicalAddress:=(pagetableentry and MAXPHYADDRMASKPB)+Offset;
exit(true);
end;
end;
end;
end;
end;
end;
end;
end;
end;
end;
function VirtualQueryExCR3(cr3: QWORD; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
var
currentmbi: TMEMORYBASICINFORMATION;
nextreadable: ptruint;
p: ptruint;
begin
if not verifyAddress(qword(lpAddress)) then
exit(0);
result:=0;
lpbuffer.BaseAddress:=pointer(ptruint(lpAddress) and $fffffffffffff000);
if GetPageInfoCR3(cr3,qword(lpAddress), lpBuffer) then
begin
p:=ptruint(lpBuffer.BaseAddress)+lpBuffer.RegionSize;
while lpBuffer.RegionSize<$20000000 do
begin
if GetPageInfoCR3(cr3,p,currentmbi) then
begin
if currentmbi.Protect=lpBuffer.Protect then
begin
p:=ptruint(currentmbi.BaseAddress)+currentmbi.RegionSize;
lpBuffer.RegionSize:=p-ptruint(lpBuffer.BaseAddress);
end
else
exit(dwLength); //different protection
end
else
exit(dwlength); //unreadable
end;
lpBuffer.RegionSize:=p-ptruint(lpBuffer.BaseAddress);
end
else
begin
//unreadable
if GetNextReadablePageCR3(cr3, ptruint(lpaddress), nextReadable) then
begin
lpBuffer.AllocationBase:=lpbuffer.BaseAddress;
lpBuffer.RegionSize:=nextReadable-ptruint(lpBuffer.BaseAddress);
lpbuffer.Protect:=PAGE_NOACCESS;
lpbuffer.state:=MEM_FREE;
lpbuffer._Type:=0;
exit(dwlength);
end
end;
end;
function ReadProcessMemoryCR3(cr3: QWORD; lpBaseAddress, lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesRead: PTRUINT): BOOL; stdcall;
var
currentAddress: qword;
PA: qword;
i: integer;
x: PtrUInt;
blocksize: integer;
begin
if not verifyAddress(qword(lpBaseAddress)) then
begin
lpNumberOfBytesRead:=0;
exit(false);
end;
cr3:=cr3 and MAXPHYADDRMASKPB;
result:=false;
if nsize=0 then exit(false);
lpNumberOfBytesRead:=0;
currentAddress:=qword(lpBaseAddress);
//aligned memory from here on
while nsize>0 do
begin
blocksize:=min(nsize, $1000-(currentAddress and $fff));
if not VirtualToPhysicalCR3(cr3, currentaddress, PA) then exit;
if not ReadPhysicalMemory(0, pointer(PA), lpBuffer, blocksize,x) then exit;
lpNumberOfBytesRead:=lpNumberOfBytesRead+x;
inc(currentAddress, x);
lpBuffer:=pointer(qword(lpbuffer)+x);
dec(nsize,x);
end;
result:=true;
end;
function WriteProcessMemoryCR3(cr3: QWORD; lpBaseAddress, lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: PTRUINT): BOOL; stdcall;
var
currentAddress: qword;
PA: qword;
i: integer;
x: PtrUInt;
blocksize: integer;
begin
if not verifyAddress(qword(lpBaseAddress)) then
begin
lpNumberOfBytesWritten:=0;
exit(false);
end;
cr3:=cr3 and MAXPHYADDRMASKPB;
result:=false;
if nsize=0 then exit(false);
lpNumberOfBytesWritten:=0;
currentAddress:=qword(lpBaseAddress);
//aligned memory from here on
while nsize>0 do
begin
blocksize:=min(nsize, $1000-(currentAddress and $fff));
if not VirtualToPhysicalCR3(cr3, currentaddress, PA) then exit;
if not WritePhysicalMemory(0, pointer(PA), lpBuffer, blocksize,x) then exit;
lpNumberOfBytesWritten:=lpNumberOfBytesWritten+x;
inc(currentAddress, x);
lpBuffer:=pointer(qword(lpbuffer)+x);
dec(nsize,x);
end;
result:=true;
end;
{$endif}
function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: PTRUINT): BOOL; stdcall;
var
{$ifndef STANDALONECH}
wle: TWriteLogEntry;
{$endif}
x: PTRUINT;
cr3: ptruint;
begin
{$ifndef darwin}
if not verifyAddress(qword(lpBaseAddress)) then
begin
lpNumberOfBytesWritten:=0;
exit(false);
end;
{$endif}
result:=false;
{$ifndef STANDALONECH}
wle:=nil;
if logWrites then
begin
if nsize<64*1024*1024 then
begin
wle:=TWriteLogEntry.Create;
wle.address:=ptruint(lpBaseAddress);
getmem(wle.originalbytes, nsize);
ReadProcessMemory(hProcess, lpBaseaddress,wle.originalbytes, nsize, x);
wle.originalsize:=x;
end;
end;
{$endif}
{$ifdef windows}
{$ifdef cpu64}
if (((qword(lpBaseAddress) and (qword(1) shl 63))<>0) and //kernelmode access
(@WriteProcessMemoryActual=defaultWPM) and
isRunningDBVM) //but DBVM is loaded
or
DBVMWatchBPActive
then
begin
if dbk32functions.GetCR3(hProcess, cr3) then //todo: maybe just a getkernelcr3
result:=WriteProcessMemoryCR3(cr3, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
end
else
{$endif}
{$endif}
result:=WriteProcessMemoryActual(hProcess, lpBaseAddress, lpbuffer, nSize, lpNumberOfBytesWritten);
{$ifndef STANDALONECH}
if result and logwrites and (wle<>nil) then
begin
getmem(wle.newbytes, lpNumberOfBytesWritten);
ReadProcessMemory(hProcess, lpBaseaddress,wle.newbytes, lpNumberOfBytesWritten, x);
wle.newsize:=x;
addWriteLogEntryToList(wle);
end;
{$endif}
end;
function ReadProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesRead: PTRUINT): BOOL; stdcall;
var cr3: ptruint;
begin
{$ifndef darwin}
if not verifyAddress(qword(lpBaseAddress)) then
begin
lpNumberOfBytesRead:=0;
exit(false);
end;
{$endif}
{$ifdef windows}
{$ifdef cpu64}
if (((qword(lpBaseAddress) and (qword(1) shl 63))<>0) and //kernelmode access
(defaultRPM=@ReadProcessMemoryActual) and
isRunningDBVM) //but DBVM is loaded
or
DBVMWatchBPActive
then
begin
if dbk32functions.GetCR3(hProcess, cr3) then
exit(ReadProcessMemoryCR3(cr3, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead));
end;
{$endif}
{$endif}
result:=ReadProcessMemoryActual(hProcess,lpBaseAddress, lpBuffer, nsize, lpNumberOfBytesRead);
end;
function VirtualQueryEx(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
var cr3: ptruint;
begin
{$ifdef windows}
{$ifdef cpu64}
if forceCR3VirtualQueryEx then
begin
if dbk32functions.GetCR3(hProcess, cr3) then
exit(VirtualQueryExCR3(cr3, lpAddress, lpBuffer, dwLength));
end;
{$endif}
{$endif}
result:=VirtualQueryExActual(hProcess,lpAddress, lpBuffer, dwLength);
end;
function VirtualQueryEx_StartCache_stub(hProcess: THandle; flags: dword): boolean;
begin
result:=false; //don't use it in windows
end;
procedure VirtualQueryEx_EndCache_stub(hProcess: THandle);
begin
end;
{$endif}
function Is64bitOS: boolean;
{$ifndef CPU64 }
var iswow64: BOOL;
{$endif}
begin
{$ifndef CPU64 }
result:=false;
{$ifdef windows}
if assigned(IsWow64Process) then
begin
iswow64:=false;
if IsWow64Process(GetCurrentProcess,iswow64) and iswow64 then
result:=true;
end;
{$endif}
{$else}
result:=true; //only a 64-bit os can run 64-bit apps
{$endif}
end;
function Is64BitProcess(processhandle: THandle): boolean;
var iswow64: BOOL;
begin
{$ifdef darwin}
outputdebugstring('newkernelhandler.is64bitprocess');
exit(macport.is64bit(processhandle));
{$endif}
{$ifdef windows}
result:=true;
if Is64bitOS then
begin
iswow64:=false;
if IsWow64Process(processhandle,iswow64) then
begin
if iswow64 then
result:=false; //running in 32-bit mode
end
else
result:=false; //IsWo64Process failed, happens on OS'es that don't have this api implemented
end else result:=false; //32-bit can't run 64
{$else}
{$ifdef cpu64}
result:=true;
{$else}
result:=false;
{$endif}
{$endif}
end;
{$ifdef windows}
procedure NeedsDBVM(reason: string='');
var r: string;
begin
{$ifndef JNI}
if (not isRunningDBVM) then
begin
r:=reason;
if r='' then
r:=rsToUseThisFunctionYouWillNeedToRunDBVM;
if isDBVMCapable and (MessageDlg(r, mtWarning, [mbyes, mbno], 0)=mryes) then
begin
LaunchDBVM(-1);
if not isRunningDBVM then raise exception.Create(rsDidNotLoadDBVM);
end;
if not isRunningDBVM then
raise exception.create(rsDBVMIsNotLoadedThisFeatureIsNotUsable);
end;
{$endif}
end;
{$endif}
function loaddbvmifneeded(reason: string=''): BOOL; stdcall;
var
signed: BOOL;
r: string;
begin
{$if defined(windows) and not defined(STANDALONECH)}
result:=isRunningDBVM;
if result then exit;
r:=reason;
if r='' then r:=rsToUseThisFunctionYouWillNeedToRunDBVM;
{$ifndef JNI}
loaddbk32;
if assigned(isDriverLoaded) then
begin
result:=false;
if is64bitos and (not isRunningDBVM) then
begin
if isDBVMCapable then
begin
signed:=false;
if isDriverLoaded(@signed) then
begin
if (MainThreadID=GetCurrentThreadId) and (MessageDlg(r, mtWarning, [mbyes, mbno], 0)<>mryes) then
exit;
LaunchDBVM(-1);
if not isRunningDBVM then raise exception.Create(rsDidNotLoadDBVM);
result:=true;
if (MainThreadID=GetCurrentThreadId) then
MemoryBrowser.Kerneltools1.enabled:=true;
end else
begin
//the driver isn't loaded
if signed then
raise exception.Create(rsPleaseRebootAndPressF8BeforeWindowsBoots)
else
raise exception.Create(rsTheDriverNeedsToBeLoadedToBeAbleToUseThisFunction);
end;
end else raise exception.Create(rsYourCpuMustBeAbleToRunDbvmToUseThisFunction);
end
else result:=true;
end;
{$endif}
{$else}
result:=false;
{$endif}
end;
function isRunningDBVM: boolean;
begin
{$if defined(windows) and not defined(STANDALONECH)}
result:=dbvm_version>0;
{$else}
result:=false;
{$endif}
end;
{$ifdef CPUX86_64}
{$define MAYUSEDBVM}
{$endif}
{$ifdef CPUi386}
{$define MAYUSEDBVM}
{$endif}
{$ifndef MAYUSEDBVM}
function isIntel: boolean;
begin
result:=false;
end;
function isAMD: boolean;
begin
result:=false;
end;
function isDBVMCapable: boolean;
begin
result:=false;
end;
function hasEPTSupport: boolean;
begin
result:=false;
end;
{$else}
function isIntel: boolean;
var a,b,c,d: dword;
begin
asm
push {$ifdef cpu64}rax{$else}eax{$endif}
push {$ifdef cpu64}rbx{$else}ebx{$endif}
push {$ifdef cpu64}rcx{$else}ecx{$endif}
push {$ifdef cpu64}rdx{$else}edx{$endif}
mov eax,0
cpuid
mov a,eax
mov b,ebx
mov c,ecx
mov d,edx
pop {$ifdef cpu64}rdx{$else}edx{$endif}
pop {$ifdef cpu64}rcx{$else}ecx{$endif}
pop {$ifdef cpu64}rbx{$else}ebx{$endif}
pop {$ifdef cpu64}rax{$else}eax{$endif}
end;
//GenuineIntel check
result:=(b=$756e6547) and (d=$49656e69) and (c=$6c65746e);
end;
function isAMD: boolean;
var a,b,c,d: dword;
begin
asm
push {$ifdef cpu64}rax{$else}eax{$endif}
push {$ifdef cpu64}rbx{$else}ebx{$endif}
push {$ifdef cpu64}rcx{$else}ecx{$endif}
push {$ifdef cpu64}rdx{$else}edx{$endif}
mov eax,0
cpuid
mov a,eax
mov b,ebx
mov c,ecx
mov d,edx
pop {$ifdef cpu64}rdx{$else}edx{$endif}
pop {$ifdef cpu64}rcx{$else}ecx{$endif}
pop {$ifdef cpu64}rbx{$else}ebx{$endif}
pop {$ifdef cpu64}rax{$else}eax{$endif}
end;
result:=(b=$68747541) and (d=$69746e65) and (c=$444d4163);
end;
function isDBVMCapable: boolean;
var a,b,c,d: dword;
begin
result:=false;
{$IFDEF windows}
if not isRunningDBVM then
begin
if isIntel then
begin
asm
push {$ifdef cpu64}rax{$else}eax{$endif}
push {$ifdef cpu64}rbx{$else}ebx{$endif}
push {$ifdef cpu64}rcx{$else}ecx{$endif}
push {$ifdef cpu64}rdx{$else}edx{$endif}
mov eax,1
cpuid
mov a,eax
mov b,ebx
mov c,ecx
mov d,edx
pop {$ifdef cpu64}rdx{$else}edx{$endif}
pop {$ifdef cpu64}rcx{$else}ecx{$endif}
pop {$ifdef cpu64}rbx{$else}ebx{$endif}
pop {$ifdef cpu64}rax{$else}eax{$endif}
end;
if ((c shr 5) and 1)=1 then //check for the intel-vt flag
result:=true;
end
else
if isAMD then
begin
{$ifdef DBVMFORAMDISWORKING}
//check if it supports SVM
asm
push {$ifdef cpu64}rax{$else}eax{$endif}
push {$ifdef cpu64}rbx{$else}ebx{$endif}
push {$ifdef cpu64}rcx{$else}ecx{$endif}
push {$ifdef cpu64}rdx{$else}edx{$endif}
mov eax,$80000001
cpuid
mov a,eax
mov b,ebx
mov c,ecx
mov d,edx
pop {$ifdef cpu64}rdx{$else}edx{$endif}
pop {$ifdef cpu64}rcx{$else}ecx{$endif}
pop {$ifdef cpu64}rbx{$else}ebx{$endif}
pop {$ifdef cpu64}rax{$else}eax{$endif}
end;
if ((c shr 2) and 1)=1 then
result:=true; //SVM is possible
{$else}
result:=false;
{$endif}
end;
end else result:=true; //it's already running DBVM, of course it's supported
{$ENDIF}
end;
function hasEPTSupport: boolean;
const
IA32_VMX_BASIC_MSR=$480;
IA32_VMX_TRUE_PROCBASED_CTLS_MSR=$48e;
IA32_VMX_PROCBASED_CTLS_MSR=$482;
IA32_VMX_PROCBASED_CTLS2_MSR=$48b;
var procbased1flags: DWORD;
begin
{$if defined(windows) and not defined(STANDALONECH)}
try
result:=isDBVMCapable; //assume yes until proven otherwise
//check if it can use EPT tables in dbvm:
//first get the basic msr to see if TRUE procbasedctrls need to be used or old
if assigned(isDriverLoaded) and isDriverLoaded(nil) then
begin
if isintel then
begin
result:=false;
if (readMSR(IA32_VMX_BASIC_MSR) and (1 shl 55))<>0 then
procbased1flags:=readMSR(IA32_VMX_TRUE_PROCBASED_CTLS_MSR) shr 32
else
procbased1flags:=readMSR(IA32_VMX_PROCBASED_CTLS_MSR) shr 32;
//check if it has secondary procbased flags
if (procbased1flags and (1 shl 31))<>0 then
begin
//yes, check if EPT can be set to 1
if ((readMSR(IA32_VMX_PROCBASED_CTLS2_MSR) shr 32) and (1 shl 1))<>0 then
result:=true;
end;
end
else
if isamd then
result:=true;
end;
except
//readMSR will error out if ran inside a virtual machine
result:=false;
end;
//else
// result:=result and isRunningDBVM;
{$else}
result:=false;
{$endif}
end;
{$endif}
{$ifdef windows}
procedure LoadDBK32; stdcall;
begin
{$if defined(windows) and not defined(STANDALONECH)}
if not DBKLoaded then
begin
outputdebugstring('LoadDBK32');
DBK32Initialize;
DBKLoaded:=(dbk32functions.hdevice<>0) and (dbk32functions.hdevice<>INVALID_HANDLE_VALUE);
//DarkByteKernel:= LoadLibrary(dbkdll);
// if DarkByteKernel=0 then exit; //raise exception.Create('Failed to open DBK32.dll');
//the driver is loaded (I hope)
//KernelVirtualAllocEx:=@dbk32functions.VAE; //GetProcAddress(darkbytekernel,'VAE');
// KernelOpenProcess:=@dbk32functions.OP; //GetProcAddress(darkbytekernel,'OP');
// KernelReadProcessMemory:=@dbk32functions.RPM; //GetProcAddresS(darkbytekernel,'RPM');
// KernelReadProcessMemory64:=@dbk32functions.RPM64; //GetProcAddresS(darkbytekernel,'RPM64');
// KernelWriteProcessMemory:=@dbk32functions.WPM; //GetProcAddress(darkbytekernel,'WPM');
// ReadProcessMemory64:=@dbk32functions.RPM64; //GetProcAddress(DarkByteKernel,'RPM64');
// WriteProcessMemory64:=@dbk32functions.WPM64; //GetProcAddress(DarkByteKernel,'WPM64');
// GetPEProcess:=@dbk32functions.GetPEProcess; //GetProcAddress(DarkByteKernel,'GetPEProcess');
// GetPEThread:=@dbk32functions.GetPEThread; //GetProcAddress(DarkByteKernel,'GetPEThread');
GetThreadsProcessOffset:=@dbk32functions.GetThreadsProcessOffset; //GetProcAddress(DarkByteKernel,'GetThreadsProcessOffset');
GetThreadListEntryOffset:=@dbk32functions.GetThreadListEntryOffset; //GetProcAddress(DarkByteKernel,'GetThreadListEntryOffset');
GetDebugportOffset:=@dbk32functions.GetDebugportOffset; //GetProcAddresS(DarkByteKernel,'GetDebugportOffset');
GetCR4:=@dbk32functions.GetCR4; //GetProcAddress(DarkByteKernel,'GetCR4');
GetCR3:=@dbk32functions.GetCR3;
// SetCR3:=@dbk32functions.SetCR3;
GetCR0:=@dbk32functions.GetCR0;
GetSDT:=@dbk32functions.GetSDT;
GetSDTShadow:=@dbk32functions.GetSDTShadow;
// setAlternateDebugMethod:=@setAlternateDebugMethod;
// getAlternateDebugMethod:=@getAlternateDebugMethod;
// DebugProcess:=@DebugProcess;
// StopDebugging:=@StopDebugging;
// StopRegisterChange:=@StopRegisterChange;
// RetrieveDebugData:=@RetrieveDebugData;
// ChangeRegOnBP:=@ChangeRegOnBP;
StartProcessWatch:=@dbk32functions.StartProcessWatch;
WaitForProcessListData:=@dbk32functions.WaitForProcessListData;
GetProcessNameFromID:=@dbk32functions.GetProcessNameFromID;
GetProcessNameFromPEProcess:=@dbk32functions.GetProcessNameFromPEProcess;
GetIDTs:=@dbk32functions.GetIDTs;
GetIDTCurrentThread:=@dbk32functions.GetIDTCurrentThread;
GetGDT:=@dbk32functions.GetGDT;
MakeWritable:=@dbk32functions.MakeWritable;
GetLoadedState:=@dbk32functions.GetLoadedState;
DBKResumeThread:=@dbk32functions.DBKResumeThread;
DBKSuspendThread:=@dbk32functions.DBKSuspendThread;
DBKResumeProcess:=@dbk32functions.DBKResumeProcess;
DBKSuspendProcess:=@dbk32functions.DBKSuspendProcess;
KernelAlloc:=@dbk32functions.KernelAlloc;
KernelAlloc64:=@dbk32functions.KernelAlloc64;
GetKProcAddress:=@dbk32functions.GetKProcAddress;
GetKProcAddress64:=@dbk32functions.GetKProcAddress64;
GetSDTEntry:= @dbk32functions.GetSDTEntry;
GetSSDTEntry:=@dbk32functions.GetSSDTEntry;
LaunchDBVM:=@dbk32functions.LaunchDBVM;
CreateRemoteAPC:=@dbk32functions.CreateRemoteAPC;
// SetGlobalDebugState:=@SetGlobalDebugState;
DBKDebug_ContinueDebugEvent:=@debug.DBKDebug_ContinueDebugEvent;
DBKDebug_WaitForDebugEvent:=@debug.DBKDebug_WaitForDebugEvent;
DBKDebug_GetDebuggerState:=@debug.DBKDebug_GetDebuggerState;
DBKDebug_SetDebuggerState:=@debug.DBKDebug_SetDebuggerState;
DBKDebug_SetGlobalDebugState:=@debug.DBKDebug_SetGlobalDebugState;
DBKDebug_SetAbilityToStepKernelCode:=@debug.DBKDebug_SetAbilityToStepKernelCode;
DBKDebug_StartDebugging:=@debug.DBKDebug_StartDebugging;
DBKDebug_StopDebugging:=@debug.DBKDebug_StopDebugging;
DBKDebug_GD_SetBreakpoint:=@debug.DBKDebug_GD_SetBreakpoint;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(0);
{$endif}
MemoryBrowser.Kerneltools1.Enabled:=DBKLoaded or isRunningDBVM;
MemoryBrowser.miCR3Switcher.visible:=MemoryBrowser.Kerneltools1.Enabled;
end;
{$endif}
end;
{$endif}
procedure DBKFileAsMemory; overload;
{Changes the redirection of ReadProcessMemory, WriteProcessMemory and VirtualQueryEx to FileHandler.pas's ReadProcessMemoryFile, WriteProcessMemoryFile and VirtualQueryExFile }
begin
{$if defined(windows) and not defined(STANDALONECH)}
UseFileAsMemory:=true;
usephysical:=false;
Usephysicaldbvm:=false;
ReadProcessMemoryActual:=@ReadProcessMemoryFile;
WriteProcessMemoryActual:=@WriteProcessMemoryFile;
VirtualQueryExActual:=@VirtualQueryExFile;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(3);
{$endif}
{$endif}
end;
procedure DBKFileAsMemory(fn:string; baseaddress: ptruint=0); overload;
begin
{$if defined(windows) and not defined(STANDALONECH)}
filehandler.filename:=filename;
if filehandler.filedata<>nil then
freeandnil(filehandler.filedata);
filehandler.filedata:=tmemorystream.create;
filehandler.filedata.LoadFromFile(fn);
filehandler.filebaseaddress:=baseaddress;
DBKFileAsMemory;
{$endif}
end;
{$ifdef windows}
function VirtualQueryExPhysical(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
var buf:_MEMORYSTATUS;
begin
{$if defined(windows) and not defined(STANDALONECH)}
if dbk32functions.hdevice<>INVALID_HANDLE_VALUE then
begin
result:=dbk32functions.VirtualQueryExPhysical(hProcess, lpAddress, lpBuffer, dwLength);
end
else
begin
GlobalMemoryStatus(buf);
lpBuffer.BaseAddress:=pointer((ptrUint(lpAddress) div $1000)*$1000);
lpbuffer.AllocationBase:=lpbuffer.BaseAddress;
lpbuffer.AllocationProtect:=PAGE_EXECUTE_READWRITE;
lpbuffer.RegionSize:=buf.dwTotalPhys-ptrUint(lpBuffer.BaseAddress);
lpbuffer.RegionSize:=lpbuffer.RegionSize+($1000-lpbuffer.RegionSize mod $1000);
lpbuffer.State:=mem_commit;
lpbuffer.Protect:=PAGE_EXECUTE_READWRITE;
lpbuffer._Type:=MEM_PRIVATE;
if (ptrUint(lpAddress)>buf.dwTotalPhys) //bigger than the total ammount of memory
then
begin
zeromemory(@lpbuffer,dwlength);
result:=0
end
else
result:=dwlength;
end;
{$endif}
end;
procedure DBKPhysicalMemoryDBVM;
{Changes the redirection of ReadProcessMemory, WriteProcessMemory and VirtualQueryEx to dbvm's read/write physical memory}
begin
{$ifdef cemain}
UseFileAsMemory:=false;
usephysical:=false;
usephysicaldbvm:=true;
ReadProcessMemoryActual:=@ReadProcessMemoryPhys;
WriteProcessMemoryActual:=@WriteProcessMemoryPhys;
VirtualQueryExActual:=@VirtualQueryExPhys;
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(3);
{$endif}
end;
procedure DBKPhysicalMemory;
begin
{$if defined(windows) and not defined(STANDALONECH)}
LoadDBK32;
If DBKLoaded=false then exit;
UsePhysical:=true;
Usephysicaldbvm:=false;
if usefileasmemory then
begin
if filedata<>nil then
freeandnil(filedata);
end;
usefileasmemory:=false;
ReadProcessMemoryActual:=@ReadPhysicalMemory;
WriteProcessMemoryActual:=@WritePhysicalMemory;
VirtualQueryExActual:=@VirtualQueryExPhysical;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(4);
{$endif}
{$endif}
end;
procedure DBKProcessMemory;
begin
{$if defined(windows) and not defined(STANDALONECH)}
usephysical:=false;
Usephysicaldbvm:=false;
if dbkreadwrite then
UseDBKReadWriteMemory
else
dontUseDBKReadWriteMemory;
if usedbkquery then
Usedbkquerymemoryregion
else
dontusedbkquerymemoryregion;
if filedata<>nil then
freeandnil(filedata);
usefileasmemory:=false;
{$endif}
end;
procedure DontUseDBKQueryMemoryRegion;
{Changes the redirection of VirtualQueryEx back to the windows API virtualQueryEx}
begin
{$if defined(windows) and not defined(STANDALONECH)}
VirtualQueryExActual:=GetProcAddress(WindowsKernel,'VirtualQueryEx');
usedbkquery:=false;
if usephysicaldbvm then DbkPhysicalMemoryDBVM;
if usephysical then DbkPhysicalMemory;
if usefileasmemory then dbkfileasmemory;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(5);
{$endif}
{$endif}
end;
procedure UseDBKQueryMemoryRegion;
{Changes the redirection of VirtualQueryEx to the DBK32 equivalent}
begin
{$if defined(windows) and not defined(STANDALONECH)}
LoadDBK32;
If DBKLoaded=false then exit;
UseDBKOpenProcess;
VirtualQueryExActual:=@VQE;
usedbkquery:=true;
if usephysical then DbkPhysicalMemory;
if usephysicaldbvm then DBKPhysicalMemoryDBVM;
if usefileasmemory then dbkfileasmemory;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(6);
{$endif}
{$endif}
end;
procedure DontUseDBKReadWriteMemory;
{Changes the redirection of ReadProcessMemory and WriteProcessMemory back to the windows API ReadProcessMemory and WriteProcessMemory }
begin
{$if defined(windows) and not defined(STANDALONECH)}
DBKReadWrite:=false;
ReadProcessMemoryActual:=GetProcAddress(WindowsKernel,'ReadProcessMemory');
WriteProcessMemoryActual:=GetProcAddress(WindowsKernel,'WriteProcessMemory');
VirtualAllocEx:=GetProcAddress(WindowsKernel,'VirtualAllocEx');
if usephysical then DbkPhysicalMemory;
if usephysicaldbvm then DBKPhysicalMemoryDBVM;
if usefileasmemory then dbkfileasmemory;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(7);
{$endif}
{$endif}
end;
procedure UseDBKReadWriteMemory;
{Changes the redirection of ReadProcessMemory, WriteProcessMemory and VirtualQueryEx to the DBK32 equiv: RPM, WPM and VAE }
var
nthookscript: Tstringlist;
func: pointer;
old: pointer;
olds: string;
begin
{$if defined(windows) and not defined(STANDALONECH)}
LoadDBK32;
If DBKLoaded=false then exit;
UseDBKOpenProcess;
ReadProcessMemoryActual:=@RPM;
WriteProcessMemoryActual:=@WPM;
VirtualAllocEx:=@VAE;
DBKReadWrite:=true;
if usephysical then DbkPhysicalMemory;
if usephysicaldbvm then DBKPhysicalMemoryDBVM;
if usefileasmemory then dbkfileasmemory;
{$ifdef cemain}
if pluginhandler<>nil then
pluginhandler.handlechangedpointers(8);
{$endif}
{$endif}
{$ifdef privatebuild}
if not assigned(OldNtQueryInformationProcess) then
begin
nthookscript:=tstringlist.create;
func:=GetProcAddress(NTDLLHandle,'NtQueryInformationProcess');
generateAPIHookScript(nthookscript,IntToHex(ptruint(func),8),IntToHex(ptruint(@dbk_NtQueryInformationProcess),8),inttohex(ptruint(@@oldNtQueryInformationProcess),8),'0',true);
autoassemble(nthookscript, false, true, false, true);
nthookscript.clear;
func:=GetProcAddress(NTDLLHandle,'NtReadVirtualMemory');
generateAPIHookScript(nthookscript,IntToHex(ptruint(func),8),IntToHex(ptruint(@dbk_NtReadVirtualMemory),8),inttohex(ptruint(@@oldNtReadVirtualMemory),8),'0',true);
autoassemble(nthookscript, false, true, false, true);
nthookscript.free;
end;
{$endif}
end;
procedure DontUseDBKOpenProcess;
{Changes the redirection of OpenProcess and VirtualAllocEx back to the windows API OpenProcess and VirtualAllocEx }
begin
{$if defined(windows) and not defined(STANDALONECH)}
OpenProcess:=GetProcAddress(WindowsKernel,'OpenProcess');
OpenThread:=GetProcAddress(WindowsKernel,'OpenThread');
{$ifdef cemain}
pluginhandler.handlechangedpointers(9);
{$endif}
{$endif}
end;
procedure UseDBKOpenProcess;
var
nthookscript: Tstringlist;
zwc: pointer;
func: pointer;
begin
{$if defined(windows) and not defined(STANDALONECH)}
LoadDBK32;
If DBKLoaded=false then exit;
OpenProcess:=@OP; //gives back the real handle, or if it fails it gives back a value only valid for the dll
OpenThread:=@OT;
{$ifdef privatebuild}
nthookscript:=tstringlist.create;
if not assigned(oldNtOpenProcess) then
begin
nthookscript.clear;
func:=GetProcAddress(NTDLLHandle,'NtOpenProcess');
generateAPIHookScript(nthookscript,IntToHex(ptruint(func),8),IntToHex(ptruint(@NOP),8),IntToHex(ptruint(@@oldNtOpenProcess),8),'0',true);
autoassemble(nthookscript, false, true, false, true);
end;
//nthookscript.add('NtOpenProcess:');
//nthookscript.add('jmp '+IntToHex(ptruint(@NOP),8));
//autoassemble(nthookscript, false, true, false, true);
if not assigned(oldZwClose) then
begin
nthookscript.clear;
func:=GetProcAddress(NTDLLHandle,'NtClose');
generateAPIHookScript(nthookscript,IntToHex(ptruint(func),8),IntToHex(ptruint(@ZC),8),IntToHex(ptruint(@@oldZwClose),8),'0',true);
autoassemble(nthookscript, false, true, false, true);
end;
nthookscript.free;
{$endif} //bypass
{$ifdef cemain}
pluginhandler.handlechangedpointers(10);
{$endif}
{$endif} //windows
end;
function GetLargePageMinimumStub: SIZE_T; stdcall;
begin
result:=0;
end;
procedure OutputDebugString(msg: string);
begin
{$ifdef windows}
windows.outputdebugstring(pchar(msg));
{$endif}
{$ifdef android}
log(msg);
{$endif}
end;
{$endif}
{$ifndef STANDALONECH}
procedure initMaxPhysMask;
var cpuidr: TCPUIDResult;
iswow: BOOL;
begin
cpuidr:=CPUID($80000008,0);
MAXPHYADDR:=cpuidr.eax and $ff;
MAXPHYADDRMASK:=qword($ffffffffffffffff);
MAXPHYADDRMASK:=MAXPHYADDRMASK shr MAXPHYADDR;
MAXPHYADDRMASK:=not (MAXPHYADDRMASK shl MAXPHYADDR);
MAXPHYADDRMASKPB:=MAXPHYADDRMASK and qword($fffffffffffff000);
MAXLINEARADDR:=(cpuidr.eax shr 8) and $ff;
MAXLINEARADDRMASK:=qword($ffffffffffffffff);
MAXLINEARADDRMASK:=MAXLINEARADDRMASK shr MAXLINEARADDR;
MAXLINEARADDRMASK:=MAXLINEARADDRMASK shl MAXLINEARADDR;
MAXLINEARADDRTEST:=qword(1) shl (MAXLINEARADDR-1);
outputdebugstring(format('cpuid $80000008=%x, %x, %x, %x',[cpuidr.eax, cpuidr.ebx, cpuidr.ecx, cpuidr.edx]));
{$ifdef cpu64}
MAXPHYADDRMASKPBBIG:=MAXPHYADDRMASK and qword($ffffffffffe00000);
{$else}
MAXPHYADDRMASKPBBIG:=MAXPHYADDRMASK and qword($ffffffffffc00000);
if assigned(IsWow64Process) then
begin
if IsWow64Process(GetCurrentProcess,iswow) then
begin
if iswow then
MAXPHYADDRMASKPBBIG:=MAXPHYADDRMASK and qword($ffffffffffe00000);
end;
end;
{$endif}
end;
{$endif}
{$ifdef windows}
procedure getLBROffset;
var x: TDebuggerState;
begin
OutputDebugString('Offset of LBR_Count='+inttostr(ptruint(@x.LBR_Count)-ptruint(@x)));
OutputDebugString('sizeof fxstate = '+inttostr(sizeof(x.fxstate)));
end;
function NoGetLogicalProcessorInformation(Buffer: PSYSTEM_LOGICAL_PROCESSOR_INFORMATION; ReturnedLength: PDWORD): BOOL; stdcall;
begin
ReturnedLength^:=0;
result:=false;
end;
{$ifdef windows}
function GetRegionInfo_Windows(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD; var mapsline: string): DWORD; stdcall;
var
i: integer;
mappedfilename: pchar;
begin
result:=VirtualQueryEx(hProcess, lpAddress, lpBuffer, dwLength);
if (result=sizeof(lpbuffer)) then
begin
getmem(mappedfilename,256);
i:=GetMappedFileName(hProcess,lpBuffer.BaseAddress, mappedfilename, 255);
mappedfilename[i]:=#0;
mapsline:=mappedfilename;
freememandnil(mappedfilename);
end;
end;
{$endif}
function GetRegionInfo_Stub(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD; var mapsline: string): DWORD; stdcall;
begin
result:=VirtualQueryEx(hProcess, lpAddress, lpBuffer, dwLength);
mapsline:='';
end;
var
psa: thandle;
u32: thandle;
resourcestring
rsfucked='Something is really messed up on your computer! You don''t seem to have a kernel!!!!';
{$endif}
initialization
{$if defined(windows) and not defined(STANDALONECH)}
DBKLoaded:=false;
usephysical:=false;
Usephysicaldbvm:=false;
usefileasmemory:=false;
usedbkquery:=false;
DenyList:=true;
DenyListGlobal:= false;
ModuleListSize:= 0;
ModuleList:= nil;
Denylist:= false;
//globaldenylist:= false;
VirtualQueryEx_StartCache:=VirtualQueryEx_StartCache_stub;
VirtualQueryEx_EndCache:=VirtualQueryEx_EndCache_stub;
WindowsKernel:=LoadLibrary('Kernel32.dll'); //there is no kernel33.dll
if WindowsKernel=0 then Raise Exception.create(rsFucked);
NTDLLHandle:=LoadLibrary('ntdll.dll');
//by default point to these exports:
ReadProcessMemoryActual:=GetProcAddress(WindowsKernel,'ReadProcessMemory');
WriteProcessMemoryActual:=GetProcAddress(WindowsKernel,'WriteProcessMemory');
defaultRPM:=@ReadProcessMemoryActual;
defaultWPM:=@WriteProcessMemoryActual;
OpenProcess:=GetProcAddress(WindowsKernel,'OpenProcess');
VirtualQueryExActual:=GetProcAddress(WindowsKernel,'VirtualQueryEx');
VirtualAllocEx:=GetProcAddress(WindowsKernel,'VirtualAllocEx');
VirtualFreeEx:=GetProcAddress(WindowsKernel,'VirtualFreeEx');
GetThreadContext:=GetProcAddress(WindowsKernel,'GetThreadContext');
SetThreadContext:=GetProcAddress(WindowsKernel,'SetThreadContext');
Wow64GetThreadContext:=GetProcAddress(WindowsKernel,'Wow64GetThreadContext');
Wow64SetThreadContext:=GetProcAddress(WindowsKernel,'Wow64SetThreadContext');
{$ifdef cpu64}
GetThreadSelectorEntry:=GetProcAddress(WindowsKernel,'Wow64GetThreadSelectorEntry');
{$endif}
SuspendThread:=GetProcAddress(WindowsKernel,'SuspendThread');
ResumeThread:=GetProcAddress(WindowsKernel,'ResumeThread');
WaitForDebugEvent:=GetProcAddress(WindowsKernel,'WaitForDebugEvent');
ContinueDebugEvent:=GetProcAddress(WindowsKernel,'ContinueDebugEvent');
DebugActiveProcess:=GetProcAddress(WindowsKernel,'DebugActiveProcess');
VirtualProtect:=GetProcAddress(WindowsKernel,'VirtualProtect');
VirtualProtectEx:=GetProcAddress(WindowsKernel,'VirtualProtectEx');
CreateRemoteThread:=GetProcAddress(WindowsKernel,'CreateRemoteThread');
OpenThread:=GetProcAddress(WindowsKernel,'OpenThread');
CreateToolhelp32Snapshot:=GetProcAddress(WindowsKernel, 'CreateToolhelp32Snapshot');
Process32First:= GetProcAddress(WindowsKernel, 'Process32First');
Process32Next:= GetProcAddress(WindowsKernel, 'Process32Next');
Thread32First:= GetProcAddress(WindowsKernel, 'Thread32First');
Thread32Next:= GetProcAddress(WindowsKernel, 'Thread32Next');
Module32First:= GetProcAddress(WindowsKernel, 'Module32First');
Module32Next:= GetProcAddress(WindowsKernel, 'Module32Next');
Heap32ListFirst:= GetProcAddress(WindowsKernel, 'Heap32ListFirst');
Heap32ListNext:= GetProcAddress(WindowsKernel, 'Heap32ListNext');
IsWow64Process:= GetProcAddress(WindowsKernel, 'IsWow64Process');
CloseHandle:=GetProcAddress(Windowskernel, 'CloseHandle');
GetLogicalProcessorInformation:=GetProcAddress(Windowskernel, 'GetLogicalProcessorInformation');
if not assigned(GetLogicalProcessorInformation) then
GetLogicalProcessorInformation:=@NoGetLogicalProcessorInformation;
GetLargePageMinimum:=GetProcAddress(WindowsKernel, 'GetLargePageMinimum');
if not assigned(GetLargePageMinimum) then
GetLargePageMinimum:=@GetLargePageMinimumStub;
SetProcessDEPPolicy:=GetProcAddress(WindowsKernel, 'SetProcessDEPPolicy');
GetProcessDEPPolicy:=GetProcAddress(WindowsKernel, 'GetProcessDEPPolicy');
GetProcessId:=GetProcAddress(WindowsKernel, 'GetProcessId');
psa:=loadlibrary('Psapi.dll');
EnumDeviceDrivers:=GetProcAddress(psa,'EnumDeviceDrivers');
GetDevicedriverBaseNameA:=GetProcAddress(psa,'GetDeviceDriverBaseNameA');
u32:=loadlibrary('user32.dll');
PrintWindow:=GetProcAddress(u32,'PrintWindow');
ChangeWindowMessageFilter:=GetProcAddress(u32,'ChangeWindowMessageFilter');
ReadPhysicalMemory:=@dbk32functions.ReadPhysicalMemory;
WritePhysicalMemory:=@dbk32functions.WritePhysicalMemory;
GetPhysicalAddress:=@dbk32functions.GetPhysicalAddress;
IsValidHandle:=@dbk32functions.IsValidHandle;
isDriverLoaded:=@dbk32functions.isDriverLoaded;
{$ifdef windows}
GetRegionInfo:=GetRegionInfo_Windows;
{$else}
GetRegionInfo:=GetRegionInfo_Stub;
{$endif}
getLBROffset;
{$endif}
{$ifndef STANDALONECH}
initMaxPhysMask;
{$endif}
{$ifdef darwin}
ReadProcessMemoryActual:=@macport.ReadProcessMemory;
WriteProcessMemoryActual:=@macport.WriteProcessMemory;
SetThreadContext:=@macport.SetThreadContext;
GetThreadContext:=@macport.GetThreadContext;
VirtualQueryExActual:=@macport.Virtualqueryex;
OpenProcess:=@macport.OpenProcess;
{$else}
{
OutputDebugString('TARM64CONTEXT:');
OutputDebugString(format('regs at %p',[@PARM64CONTEXT(0).regs]));
OutputDebugString(format('SP at %p',[@PARM64CONTEXT(0).SP]));
OutputDebugString(format('PC at %p',[@PARM64CONTEXT(0).PC]));
OutputDebugString(format('PSTATE at %p',[@PARM64CONTEXT(0).PSTATE]));
OutputDebugString(format('fp at %p',[@PARM64CONTEXT(0).fp]));
OutputDebugString(format('vregs[0] at %p',[@PARM64CONTEXT(0).fp.vregs[0]]));
OutputDebugString(format('vregs[1] at %p',[@PARM64CONTEXT(0).fp.vregs[1]]));
OutputDebugString(format('vregs[2] at %p',[@PARM64CONTEXT(0).fp.vregs[2]]));
OutputDebugString(format('vregs[30] at %p',[@PARM64CONTEXT(0).fp.vregs[30]]));
OutputDebugString(format('vregs[31] at %p',[@PARM64CONTEXT(0).fp.vregs[31]]));
OutputDebugString(format('fpsr at %p',[@PARM64CONTEXT(0).fp.fpsr]));
OutputDebugString(format('fpcr at %p',[@PARM64CONTEXT(0).fp.fpcr]));
OutputDebugString(format('reserved[0] at %p',[@PARM64CONTEXT(0).fp.reserved[0]]));
OutputDebugString(format('reserved[1] at %p',[@PARM64CONTEXT(0).fp.reserved[1]]));
}
{$endif}
finalization
end.