unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, TLhelp32,
  Vcl.AppEvnts;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    CheckBox1: TCheckBox;
    Button3: TButton;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    ApplicationEvents1: TApplicationEvents;
    procedure CheckBox1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure CheckBox3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TZoombie = class

  private
    Fexename: string;
    Fpid, FProcessHandle, Pbase: Integer;
    Fbase: Pointer;
    FCatch: Boolean;
    function CheckProcessExist(const AFileName: string): Boolean;
    function GetSunNum: Integer;
    function GetPIDfromName(Name: String): Integer;
  public
    constructor Create(base: Integer); //基质初始化类
    procedure SetSun(newvalue: Integer); //设置阳光
    procedure NocoolDown; //设置无冷却
    function Catch: Boolean; //加载游戏
    procedure AllKill(auto: Boolean);//开启一击必杀[目前支持戴帽子和不带帽子的 其他僵尸没遇到]
    property Catched: Boolean read FCatch;  //是否已经加载
    property SunNum: Integer read GetSunNum;  //当前阳光
  end;

var
  Form1: TForm1;
  ZoomBie: TZoombie;
  maxsun, nocool: Boolean;

implementation

{$R *.dfm}

function TZoombie.CheckProcessExist(const AFileName: string): Boolean;
var
  // 用于获得进程列表
  hSnapshot: THandle;
  // 用于查找进程
  lppe: TProcessEntry32;
  // 用于判断进程遍历是否完成
  Found: Boolean;
begin
  Result := False;
  // 获得系统进程列表
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  // 在调用Process32FirstAPI之前,需要初始化lppe记录的大小
  lppe.dwSize := SizeOf(TProcessEntry32);
  // 将进程列表的第一个进程信息读入ppe记录中
  Found := Process32First(hSnapshot, lppe);
  while Found do
  begin
    if ((UpperCase(ExtractFileName(lppe.szExeFile)) = UpperCase(AFileName)) or
      (UpperCase(lppe.szExeFile) = UpperCase(AFileName))) then
    begin
      Result := True;
    end;
    // 将进程列表的下一个进程信息读入lppe记录中
    Found := Process32Next(hSnapshot, lppe);
  end;
end;

function TZoombie.Catch: Boolean;
begin
  var
    tp: NativeUint;
  if CheckProcessExist(Fexename) then
  begin
    Fpid := GetPIDfromName(Fexename);
    FProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, Fpid);
    ReadProcessMemory(FProcessHandle, Pointer(Fbase), @Pbase,
      SizeOf(Pbase), tp);
    FCatch := True;
    exit(True);
  end;

  FCatch := False;
  Result := False;
end;

constructor TZoombie.Create(base: Integer);
begin
  Fbase := Pointer(base);
  Fexename := 'PlantsVsZombies.exe';
end;

function TZoombie.GetPIDfromName(Name: String): Integer;
var
  h: THandle;
  f: Boolean;
  lppe: TProcessEntry32;
begin
  h := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  lppe.dwSize := SizeOf(lppe);
  f := Process32First(h, lppe);
  while Integer(f) <> 0 do
  begin
    if lppe.szExeFile = Name then
    begin
      Result := lppe.th32ProcessID;
      break;
    end;
    f := Process32Next(h, lppe);
  end;
end;

function TZoombie.GetSunNum: Integer;
begin
  var
    Step1, Step2, tp: NativeUint;
  ReadProcessMemory(FProcessHandle, Pointer(Pbase + $768), @Step1,
    SizeOf(Step1), tp);
  ReadProcessMemory(FProcessHandle, Pointer(Step1 + $5560), @Result,
    SizeOf(Result), tp);
end;

procedure TZoombie.AllKill(auto: Boolean);
begin
  var
    new, tp: Integer;
  if auto then
  begin
    new := 2425421609; // 普通僵尸一击死亡
    WriteProcessMemory(FProcessHandle, Pointer($53130F), @new, 4,
      NativeUint(tp));
    new := 3287730473; // 僵尸帽子一击死亡
    WriteProcessMemory(FProcessHandle, Pointer($531044), @new, 4,
      NativeUint(tp));
  end
  else
  begin
    new := 539261995; // 普通僵尸正常
    WriteProcessMemory(FProcessHandle, Pointer($53130F), @new, 4,
      NativeUint(tp));
    new := 3287728425; // 僵尸帽子正常
    WriteProcessMemory(FProcessHandle, Pointer($531044), @new, 4,
      NativeUint(tp));
  end;
end;

procedure TZoombie.SetSun(newvalue: Integer);
begin
  var
    Step1, Step2, tp: NativeUint;
  ReadProcessMemory(FProcessHandle, Pointer(Pbase + $768), @Step1,
    SizeOf(Step1), tp);
  ReadProcessMemory(FProcessHandle, Pointer(Step1 + $5560), @Step2,
    SizeOf(Step2), tp);
  WriteProcessMemory(FProcessHandle, Pointer(Step1 + $5560), @newvalue, 4, tp);
end;

procedure TZoombie.NocoolDown;
begin
  var
    Step1, Step2, tp: NativeUint;
  ReadProcessMemory(FProcessHandle, Pointer(Pbase + $768), @Step1,
    SizeOf(Step1), tp);
  ReadProcessMemory(FProcessHandle, Pointer(Step1 + $144), @Step2,
    SizeOf(Step2), tp);
  var
  new := 8000;

  for var i := 0 to 5 do
  begin
    WriteProcessMemory(FProcessHandle, Pointer(Step2 + $4C + i * $50),
      @new, 4, tp);
  end;

end;

procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
  if ZoomBie.Catched then
  begin
    Label1.Caption := Format('当前阳光:%d', [ZoomBie.SunNum]);
    if maxsun then
      ZoomBie.SetSun(9999);

    if nocool then
      ZoomBie.NocoolDown;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  if ZoomBie.Catch then
  begin
    Caption := '加载游戏成功'
  end
  else
  begin
    Caption := '加载游戏失败';
  end;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  ZoomBie.AllKill(CheckBox1.Checked);
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  if CheckBox2.Checked then
  begin
    maxsun := True;
  end
  else
  begin
    maxsun := False;
  end;
end;

procedure TForm1.CheckBox3Click(Sender: TObject);
begin
  if CheckBox3.Checked then
  begin
    nocool := True;
  end
  else
  begin
    nocool := False;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ZoomBie := TZoombie.Create($6AA00C);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ZoomBie.Free;
end;

end.
最后修改:2022 年 12 月 05 日
如果觉得我的文章对你有用,请随意赞赏