dbk32functions.pas.svn-base

来自「这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望」· SVN-BASE 代码 · 共 2,166 行 · 第 1/5 页

SVN-BASE
2,166
字号
unit DBK32functions;

interface

uses windows,sysutils,winsvc,psapi,classes,types,registry;

//xp sp2
//ThreadsProcess=220
//ThreadListEntry=22c



const currentversion=2000011;

const FILE_ANY_ACCESS=0;
const FILE_SPECIAL_ACCESS=FILE_ANY_ACCESS;
const FILE_READ_ACCESS=$0001;
const FILE_WRITE_ACCESS=$0002;
const FILE_RW_ACCESS=FILE_READ_ACCESS or FILE_WRITE_ACCESS;

const METHOD_BUFFERED=    0;
const METHOD_IN_DIRECT=   1;
const METHOD_OUT_DIRECT=  2;
const METHOD_NEITHER=     3;
const FILE_DEVICE_UNKNOWN=$00000022;
const IOCTL_UNKNOWN_BASE=FILE_DEVICE_UNKNOWN;


const IOCTL_CE_READMEMORY             = (IOCTL_UNKNOWN_BASE shl 16) or ($0800 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_WRITEMEMORY            = (IOCTL_UNKNOWN_BASE shl 16) or ($0801 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_OPENPROCESS    		  	=	(IOCTL_UNKNOWN_BASE shl 16) or ($0802 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_QUERY_VIRTUAL_MEMORY  	=	(IOCTL_UNKNOWN_BASE shl 16) or ($0803 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_TEST							      = (IOCTL_UNKNOWN_BASE shl 16) or ($0804 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETPEPROCESS				    = (IOCTL_UNKNOWN_BASE shl 16) or ($0805 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_READPHYSICALMEMORY		  = (IOCTL_UNKNOWN_BASE shl 16) or ($0806 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_WRITEPHYSICALMEMORY	  = (IOCTL_UNKNOWN_BASE shl 16) or ($0807 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETPHYSICALADDRESS		  = (IOCTL_UNKNOWN_BASE shl 16) or ($0808 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_PROTECTME					    = (IOCTL_UNKNOWN_BASE shl 16) or ($0809 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETCR3 					      = (IOCTL_UNKNOWN_BASE shl 16) or ($080a shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_SETCR3 					      = (IOCTL_UNKNOWN_BASE shl 16) or ($080b shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETSDT 					      = (IOCTL_UNKNOWN_BASE shl 16) or ($080c shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_INITIALIZE     		    = (IOCTL_UNKNOWN_BASE shl 16) or ($080d shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_DONTPROTECTME			    = (IOCTL_UNKNOWN_BASE shl 16) or ($080e shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETIDT 					  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($080f shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_HOOKINTS 					    = (IOCTL_UNKNOWN_BASE shl 16) or ($0810 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_DEBUGPROCESS 			    = (IOCTL_UNKNOWN_BASE shl 16) or ($0811 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_RETRIEVEDEBUGDATA		  = (IOCTL_UNKNOWN_BASE shl 16) or ($0812 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_STARTPROCESSWATCH  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($0813 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETPROCESSEVENTS		    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0814 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETTHREADEVENTS			  = (IOCTL_UNKNOWN_BASE shl 16) or ($0815 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETVERSION				      =	(IOCTL_UNKNOWN_BASE shl 16) or ($0816 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETCR4 					      = (IOCTL_UNKNOWN_BASE shl 16) or ($0817 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_OPENTHREAD	    	   	  = (IOCTL_UNKNOWN_BASE shl 16) or ($0818 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_MAKEWRITABLE			      =	(IOCTL_UNKNOWN_BASE shl 16) or ($0819 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_DEBUGPROCESS_CHANGEREG	=	(IOCTL_UNKNOWN_BASE shl 16) or ($081a shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_STOPDEBUGGING				  = (IOCTL_UNKNOWN_BASE shl 16) or ($081b shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const	IOCTL_CE_STOP_DEBUGPROCESS_CHANGEREG =	(IOCTL_UNKNOWN_BASE shl 16) or ($081c shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const	IOCTL_CE_USEALTERNATEMETHOD		  =	(IOCTL_UNKNOWN_BASE shl 16) or ($081d shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const	IOCTL_CE_ISUSINGALTERNATEMETHOD =	(IOCTL_UNKNOWN_BASE shl 16) or ($081e shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const	IOCTL_CE_ALLOCATEMEM				    =	(IOCTL_UNKNOWN_BASE shl 16) or ($081f shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_CREATEAPC					    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0820 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETPETHREAD				    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0821 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);

const IOCTL_CE_SUSPENDTHREAD			    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0822 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_RESUMETHREAD				    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0823 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_SUSPENDPROCESS			    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0824 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_RESUMEPROCESS			    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0825 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);

const IOCTL_CE_ALLOCATEMEM_NONPAGED   =	(IOCTL_UNKNOWN_BASE shl 16) or ($0826 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETPROCADDRESS			    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0827 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_SETSDTADDRESS 			    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0828 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETSDTADDRESS 			    =	(IOCTL_UNKNOWN_BASE shl 16) or ($0829 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);

const IOCTL_CE_GETGDT 					  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($082a shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_SETCR4 					  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($082b shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_VMXCONFIG				  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($082d shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_GETCR0 					  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($082e shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_MAKEKERNELCOPY		  	  = (IOCTL_UNKNOWN_BASE shl 16) or ($082f shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);
const IOCTL_CE_SETGLOBALDEBUGSTATE 	  = (IOCTL_UNKNOWN_BASE shl 16) or ($0830 shl 2) or (METHOD_BUFFERED ) or (FILE_RW_ACCESS shl 14);




type TDeviceIoControl=function(hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; var lpBytesReturned: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

type thandlelist=record
  processhandle: thandle;
  processid: dword;
  validhandle: boolean;
end;

type TClient_ID=record
  processid: thandle;
  threadid: thandle;
end;
type PClient_ID=^TClient_ID;

type THookIDTThread=class(tthread)
  public
    cpunr: byte;
    done: boolean;
    succeeded: boolean;
    procedure execute; override;
end;

type THookIDTConstantly=class(tthread)
  public
    procedure execute; override;
end;

var cpuidt: array of dword;
type TGetIDTThread=class(tthread)
  public
    cpunr: byte;
    done: boolean;
    procedure execute; override;
  end;

var hdevice: thandle; //handle to my the device driver
    handlelist: array of thandlelist;
    driverloc: string;
    iamprotected:boolean;
    SDTShadow: DWORD;
    debugport,processname: dword;

    ThreadsProcess,ThreadListEntry:dword;

    processeventname, threadeventname: string;
    processevent,threadevent:thandle;

    ownprocess: thandle=0; //needed for simple kernelmemory access
    Successfullyloaded:boolean;

    usealternatedebugmethod: boolean;



function CTL_CODE(DeviceType, Func, Method, Access : integer) : integer;
function IsValidHandle(hProcess:THandle):BOOL; stdcall;
Function {OpenProcess}OP(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwProcessId:DWORD):THANDLE; stdcall;
Function {OpenThread}OT(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwThreadId:DWORD):THANDLE; stdcall;
function {ReadProcessMemory}RPM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
function {WriteProcessMemory}WPM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
function {VirtualQueryEx}VQE(hProcess: THandle; address: pointer; var mbi: _MEMORY_BASIC_INFORMATION; bufsize: DWORD):dword; stdcall;
Function {NtOpenProcess}NOP(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
Function {NtOpenThread}NtOT(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
Function {VirtualAllocEx}VAE(hProcess: THandle; lpAddress: Pointer; dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
Function CreateRemoteAPC(threadid: dword; lpStartAddress: TFNAPCProc): THandle; stdcall;


Function GetPEProcess(ProcessID: dword):dword; stdcall;
Function GetPEThread(Threadid: dword):dword; stdcall;
function GetDebugportOffset: DWORD; stdcall;
function GetProcessnameOffset: dword; stdcall;
function GetThreadsProcessOffset: dword; stdcall;
function GetThreadListEntryOffset: dword; stdcall;

function ReadPhysicalMemory(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
function WritePhysicalMemory(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
function GetPhysicalAddress(hProcess:THandle;lpBaseAddress:pointer;var Address:int64): BOOL; stdcall;

function ProtectMe(ProtectedProcessID: dword; denylist,globaldenylist:BOOL;list:pchar; listsize:dword):BOOL; stdcall; //or should I give it a array of processid's?
function UnprotectMe:bool; stdcall;
function MakeKernelCopy(Base: dword; size: dword): bool; stdcall;

function GetCR4:DWORD; stdcall;
function GetCR3(hProcess:THANDLE;var CR3:DWORD):BOOL; stdcall;
function SetCR3(hProcess:THANDLE;CR3: DWORD):BOOL; stdcall;
function GetCR0:DWORD; stdcall;
function GetSDT:DWORD; stdcall;
function GetSDTShadow:DWORD; stdcall;
function setAlternateDebugMethod(var int1apihook:dword; var OriginalInt1handler:dword):BOOL; stdcall;
function getAlternateDebugMethod:BOOL; stdcall;
function DebugProcess(processid:dword;address:DWORD;size: byte;debugtype:byte):BOOL; stdcall;
function SetGlobalDebugState(state: boolean): BOOL; stdcall;
function StopDebugging:BOOL; stdcall;
function StopRegisterChange(regnr:integer):BOOL; stdcall;
function RetrieveDebugData(Buffer: pointer):integer; stdcall;
function ChangeRegOnBP(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;
function StartProcessWatch:BOOL;stdcall;
function WaitForProcessListData(processpointer:pointer;threadpointer:pointer;timeout:dword):dword; stdcall;
function GetProcessNameFromPEProcess(peprocess:dword; buffer:pchar;buffersize:dword):integer; stdcall;
function GetProcessNameFromID(processid:dword; buffer:pointer;buffersize:dword):integer; stdcall;
function MakeWritable(Address,Size:dword;copyonwrite:boolean): boolean; stdcall;
function RewriteKernel32:boolean; stdcall;
function RestoreKernel32:boolean; stdcall;

function InitializeDriver(Address,size:dword):BOOL; stdcall;
function GetWin32KAddress(var address:DWORD;var size:dworD):boolean;
function GetDriverVersion: dword;

function GetIDTCurrentThread:dword; stdcall;
function GetIDTs(idtstore: pointer; maxidts: integer):integer; stdcall;

function GetLoadedState: BOOLEAN; stdcall;

function test: boolean; stdcall;
procedure useIOCTL(use: boolean); stdcall;

function DBKSuspendThread(ThreadID:dword):boolean; stdcall;
function DBKResumeThread(ThreadID:dword):boolean; stdcall;
function DBKSuspendProcess(ProcessID:dword):boolean; stdcall;
function DBKResumeProcess(ProcessID:dword):boolean; stdcall;

function KernelAlloc(size: dword):pointer; stdcall;
function GetKProcAddress(s: pwidechar):pointer; stdcall;

function GetSDTEntry(nr: integer; address: PDWORD; paramcount: PBYTE):boolean; stdcall;
function SetSDTEntry(nr: integer; address: DWORD; paramcount: BYTE):boolean; stdcall;
function GetSSDTEntry(nr: integer; address: PDWORD; paramcount: PBYTE):boolean; stdcall;
function SetSSDTEntry(nr: integer; address: DWORD; paramcount: BYTE):boolean; stdcall;

function GetGDT(limit: pword):dword; stdcall;

var hooker: THookIDTConstantly;
    kernel32dll: thandle;
    ioctl: boolean;

implementation

uses vmxfunctions;



procedure FSC;
asm
  mov edx,esp
  sysenter
end;

function GetLoadedState: BOOLEAN; stdcall;
begin
  result:=(hdevice<>INVALID_HANDLE_VALUE) and Successfullyloaded;
end;

procedure useIOCTL(use: boolean); stdcall;
begin
  ioctl:=use;
end;

function Test:boolean; stdcall;
{$W+}
procedure test_noioctl(p1:integer; p2: integer); stdcall;
asm
  pop ebp //used parameters so the stupid compiler added a push ebp
  mov eax,$2000
  call fsc
  ret 8
end;
{$W-}

var cc,br: dword;
    threadid: dword;
begin
  result:=true;
  if ioctl then
  begin
    cc:=IOCTL_CE_TEST;
    result:=deviceiocontrol(hdevice,cc,@threadid,sizeof(threadid),nil,0,br,nil);
  end
  else
  begin
    test_noioctl(1,2);
  end;
end;


function GetGDT(limit: pword):dword; stdcall;
var cc,br: dword;
    gdtdescriptor: packed record
                     wLimit:word;
                     vector: dword;
                   end;
begin
  if hdevice<>INVALID_HANDLE_VALUE then
  begin
    cc:=IOCTL_CE_GETGDT;
    deviceiocontrol(hdevice,cc,nil,0,@gdtdescriptor,6,br,nil);
    result:=gdtdescriptor.vector;
    if (limit<>nil) then
      limit^:=gdtdescriptor.wlimit;
  end else result:=0;
end;

function GetIDTCurrentThread:dword;
var cc,br: dword;
    idtdescriptor: packed record
                     wLimit:word;
                     vector: dword;
                   end;
begin
  if hdevice<>INVALID_HANDLE_VALUE then
  begin
    cc:=IOCTL_CE_GETIDT;
    deviceiocontrol(hdevice,cc,nil,0,@idtdescriptor,6,br,nil);
    result:=idtdescriptor.vector;
  end else result:=0;
end;

procedure TGetIDTThread.execute;
begin
  try
    cpuidt[cpunr]:=getidtcurrentthread;
  finally
    done:=true;
  end;
end;

function GetIDTs(idtstore: pointer; maxidts: integer):integer; stdcall;
var ec: dword;
    i:integer;
    cpunr,PA,SA:Dword;
    cpunr2:byte;
begin
  //max idt's should be 32, but may be less if you('re a retard!) don't want to allocate the enormous ammount of 32*4=128 bytes
  setlength(cpuidt,0);
  result:=0; //0 idt's returned

  if hdevice<>INVALID_HANDLE_VALUE then
  begin
    GetProcessAffinityMask(getcurrentprocess,PA,SA);

    //first hook the interrupts if needed
    cpunr2:=0;
    cpunr:=1;
    while (cpunr<=PA) do
    begin
      if ((cpunr) and PA)>0 then
      begin
        setlength(cpuidt,length(cpuidt)+1);
        SetProcessAffinityMask(getcurrentprocess,cpunr);
        //create a new thread. (Gues on what cpu it will run at...)

        with TGetIDTThread.Create(true) do
        begin
          try
            cpunr:=cpunr2;
            resume;

            while not done do sleep(20); //the sleep should also cause a taskswitch but I'm not 100% sure
          finally
            free;
          end;
        end;

      end;
      if cpunr=$80000000 then break;
      inc(cpunr,cpunr);
      inc(cpunr2);//next cpu
    end;

    SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it

    if length(cpuidt)>maxidts then
      setlength(cpuidt,maxidts);
      
    for i:=0 to length(cpuidt)-1 do
      TCardinalDynArray(idtstore)[i]:=cpuidt[i];

    result:=length(cpuidt);
  end;

end;


procedure THookIDTThread.execute;
var cc,br: dword;
begin
  try
//    outputdebugstring('hooking IDT');
    cc:=IOCTL_CE_HOOKINTS;
    succeeded:=deviceiocontrol(hdevice,cc,@cpunr,1,@cpunr,0,br,nil);
  finally
    done:=true;
  end;
end;

procedure THookIDTConstantly.execute;
var input:TInput;
    br,cc: dword;
    i:integer;
    cpunr,PA,SA:Dword;
    cpunr2:byte;
begin
  freeonterminate:=true;
  if hdevice<>INVALID_HANDLE_VALUE then
  begin
    cc:=IOCTL_CE_HOOKINTS;

    while not terminated do
    begin
//      outputdebugstring('writing the idt');
      GetProcessAffinityMask(getcurrentprocess,PA,SA);

      cpunr2:=0;
      cpunr:=1;
      while (cpunr<=PA) do
      begin
        if ((cpunr) and PA)>0 then
        begin
          SetProcessAffinityMask(getcurrentprocess,cpunr);
          //create a new thread. (Gues on what cpu it will run at...)

          with THookIDTThread.Create(true) do
          begin
            try
              cpunr:=cpunr2;
              resume;

              while not done do sleep(10); //the sleep should also cause a taskswitch but I'm not 100% sure
            finally
              free;
            end;
          end;

        end;
        if cpunr=$80000000 then break;
        inc(cpunr,cpunr);
        inc(cpunr2);
      end;

      SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it

      if vmx_enabled then exit; //no rehook needed since idt changes don't matter
      
      sleep(5000); //wait a while before rewriting
    end;
  end;
end;


function GetProcessNameFromPEProcess(peprocess:dword; buffer:pchar;buffersize:dword):integer; stdcall;
var ar:dword;
    i:integer;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?