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); {$endif} {$ifdef cpu64} const CONTEXT_EXTENDED_REGISTERS = 0; // CONTEXT_XSTATE = (CONTEXT_AMD64 or $00100040); CONTEXT_XSTATE = (CONTEXT_AMD64 or $00000040); 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; 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 {$ifdef cpu32} type M128A = record Low: ULONGLONG; High: LONGLONG; end; {$endif} 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: TExtendedRegisters; 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.