⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 undochanges.pas

📁 冒险岛吸怪源码UCE的制作材料 用于冒险岛游戏的外挂
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit UndoChanges;

interface

uses windows,SysUtils,classes,dialogs,controls,cefuncproc,newkernelhandler,syncobjs;

const undoversion=1;

type TUndoChangesThread=class(TThread)
  private
    procedure ShutdownProtection;
    procedure ShowModification;
    procedure HideModification;
    function  CheckForChanges:boolean;
  public
    procedure execute; override;

end;

type tregiondata=record
  dllnr: byte;
  address: dword;
  size: dword;
end;
type bytearray=array of byte;

function CheckForChanges:boolean;

var undothread:TUndoChangesThread;
    firstrun:boolean;

implementation
uses mainunit,formsettingsunit;

var checkedokonce: boolean;
    protectionloaded: boolean;
    loadmem: TCriticalSection;


    OldKernelDLLBase,NewKernelDLLBase: DWORD; //needed to make offset adjustments if somehow the addresses got changed. (0% chance this happens, except a windows update, but lets do it anyhow)
    OldNTDLLBase,NewNTDLLBase: DWORD;
    Olduser32dllbase,newuser32dllbase:DWORD;

    KernelDllRegions: array of TRegiondata;
    Ntdllregions: array of tregiondata;
    user32DLLregions: array of tregiondata;

    KernelMemory: array of bytearray;
    ntdllmemory:  array of bytearray;
    user32memory: array of bytearray;

    OpenProcessPos:dword;
    DebugActiveProcessPos:dword;
    SuspendThreadPos:dword;
    ResumeThreadPos:dword;
    ReadProcessMemoryPos:dword;
    WriteProcessMemoryPos:dword;
    NtOpenProcessPos:dword;
    SetWindowsHookExAPos:dword;

function InitMem:boolean;
var savedata: tfilestream;
    x: dword;
    i:integer;
begin
  try
    LoadMem.enter;
    try
      if firstrun then //load the original memory
      begin
        NewUser32DLLBase:=dword(LoadLibrary('user32.dll'));
        NewKernelDLLBase:=dword(LoadLibrary('Kernel32.dll'));
        NewNtDLLBase:=dword(LoadLibrary('ntdll.dll'));

        Freelibrary(NewKernelDLLBase); //decrease the reference pointer. (always a good habbit, but not really needed)
        FreeLibrary(NewNtdllbase);
        FreeLibrary(NewNtDLLBase);

        savedata:=tfilestream.Create(cheatenginedir+'CEProtect.dat',fmOpenRead);
        try
          savedata.ReadBuffer(x,4);
          if x<>undoversion then
          begin
            formsettings.cbUndoMemoryChanges.checked:=false;
            raise exception.Create('The ceprotect.dat file was created with a different version of Cheat Engine. Re-enable the undo memory changes option in CE to recreate the CEProtect.dat file');
          end;

          savedata.ReadBuffer(OldKernelDLLBase,4);
          savedata.ReadBuffer(OldNTDLLBase,4);
          savedata.ReadBuffer(OldUser32DLLBase,4);

          savedata.ReadBuffer(x,4);
          setlength(kerneldllregions,x);
          savedata.ReadBuffer(kerneldllregions[0],x*sizeof(tregiondata));

          setlength(kernelmemory,x);
          for i:=0 to x-1 do
          begin
            setlength(kernelmemory[i],kerneldllregions[i].size);
            savedata.ReadBuffer(kernelmemory[i][0],kerneldllregions[i].size);
          end;

          savedata.ReadBuffer(x,4);
          setlength(ntdllregions,x);
          savedata.ReadBuffer(ntdllregions[0],x*sizeof(tregiondata));

          setlength(ntdllmemory,x);
          for i:=0 to x-1 do
          begin
            setlength(ntdllmemory[i],ntdllregions[i].size);
            savedata.ReadBuffer(ntdllmemory[i][0],ntdllregions[i].size);
          end;

          savedata.ReadBuffer(x,4);
          setlength(user32dllregions,x);
          savedata.ReadBuffer(user32dllregions[0],x*sizeof(tregiondata));

          setlength(user32memory,x);
          for i:=0 to x-1 do
          begin
            setlength(user32memory[i],user32dllregions[i].size);
            savedata.ReadBuffer(user32memory[i][0],user32dllregions[i].size);
          end;


          savedata.ReadBuffer(OpenProcessPos,4);
          savedata.ReadBuffer(DebugActiveProcessPos,4);
          savedata.ReadBuffer(SuspendThreadPos,4);
          savedata.ReadBuffer(ResumeThreadPos,4);
          savedata.ReadBuffer(ReadProcessMemoryPos,4);
          savedata.ReadBuffer(WriteProcessMemoryPos,4);
          savedata.ReadBuffer(NtOpenProcessPos,4);
          savedata.Readbuffer(SetWindowsHookExAPos,4);
        finally
          savedata.free;
        end;

        firstrun:=false;
      end;

    finally
      LoadMem.leave;
    end;


    //if it managed to get to here I gues nothing went wrong
    protectionloaded:=true;
  except

  end;

  result:=protectionloaded;
end;

function UndoMemoryChanges: boolean;
var i: integer;
    x,y,ar,buf: dword;
    p: thandle;
    t: byte;
begin
  result:=true;

  //kernel
  for i:=0 to length(kerneldllregions)-1 do
  begin
    x:=kerneldllregions[i].address;

    if formsettings.cbForceUndo.checked then
    begin
      //open cheat engine using the kernel mode driver
      p:=KernelOpenProcess(process_all_access,false,getcurrentprocessid);

      x:=kerneldllregions[i].address;

      while x<kerneldllregions[i].address+kerneldllregions[i].size do
      begin
        try
          MakeWritable(x,4096,true);
          //this page should be writable now, so lets write to it

          CopyMemory(pointer(x),@kernelmemory[i][x-kerneldllregions[i].address],4096)
        except
          //error? ehrm, thats a bug and should never occur
          inc(x,4096);
          continue;
        end;

        inc(x,4096);
      end;


      closehandle(p);
    end
    else
    begin
      //normal virtualprotect method     (wont work on newer nprotect games)
      x:=kerneldllregions[i].address;

      VirtualProtect(pointer(x),kerneldllregions[i].size,page_execute_readwrite,ar);
      try
        CopyMemory(pointer(x),@kernelmemory[i][0],kerneldllregions[i].size);
      except
        result:=false;

      end;
    end;
  end;

  //ntdll
  for i:=0 to length(ntdllregions)-1 do
  begin
    x:=ntdllregions[i].address;

    if formsettings.cbForceUndo.checked then
    begin
      //open cheat engine using the nt mode driver
      p:=KernelOpenProcess(process_all_access,false,getcurrentprocessid);

      x:=ntdllregions[i].address;

      while x<ntdllregions[i].address+ntdllregions[i].size do
      begin
        try
          //read a byte from this page (so it's paged)
          if pbyte(x)^=$cc then sleep(0);

          //now make that address writable
          y:=((x div $1000) *4)+$c0000000;
          if KernelReadProcessMemory(p,pointer(y),@buf,4,ar) then
          begin
            //make it writable without copy-on-write. Copy-on0write should already have taken place when it got modified in the first place. (and if it isn't this'll fix ALL the processes)
            buf:=(buf or $2);
            KernelWriteProcessMemory(p,pointer(y),@buf,4,ar);
          end;

          //this page should be writable now, so lets write to it

          CopyMemory(pointer(x),@ntdllmemory[i][x-ntdllregions[i].address],4096)
        except
          //error? ehrm, thats a bug and should never occur
          inc(x,4096);
          continue;
        end;

        inc(x,4096);
      end;


      closehandle(p);
    end
    else
    begin
      //normal virtualprotect method     (wont work on newer nprotect games)
      x:=ntdllregions[i].address;

      VirtualProtect(pointer(x),ntdllregions[i].size,page_execute_readwrite,ar);
      try
        CopyMemory(pointer(x),@ntdllmemory[i][0],ntdllregions[i].size);
      except
        result:=false;

      end;
    end;
  end;


  //user32
  for i:=0 to length(user32dllregions)-1 do
  begin
    x:=(newuser32dllbase-Olduser32dllbase)+user32dllregions[i].address;

    if formsettings.cbForceUndo.checked then
    begin
      //open cheat engine using the user32 mode driver
      p:=kernelOpenProcess(process_all_access,false,getcurrentprocessid);

      x:=(newuser32dllbase-Olduser32dllbase)+user32dllregions[i].address;

      while x<((newuser32dllbase-Olduser32dllbase)+user32dllregions[i].address)+user32dllregions[i].size do
      begin
        try
          //read a byte from this page (so it's paged)
          if pbyte(x)^=$cc then sleep(0);

          //now make that address writable
          y:=((x div $1000) *4)+$c0000000;
          if kernelReadProcessMemory(p,pointer(y),@buf,4,ar) then
          begin
            //make it writable without copy-on-write. Copy-on0write should already have taken place when it got modified in the first place. (and if it isn't this'll fix ALL the processes)
            buf:=(buf or $2);
            kernelWriteProcessMemory(p,pointer(y),@buf,4,ar);
          end;

          //this page should be writable now, so lets write to it

          CopyMemory(pointer(x),@user32memory[i][x-user32dllregions[i].address],4096)
        except
          //error? ehrm, thats a bug and should never occur
          inc(x,4096);
          continue;

⌨️ 快捷键说明

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