这里一开始用了Pinvoke.net,后来发现它的WriteProcessMemory
接口和win32APi里的WriteProcessMemory 不太一样。就抄了一个其他的。
internal partial class CheatCore
{
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hProcess);
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001FFFFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
public static byte[] ReadMemory(IntPtr processHandle, int address, int numOfBytes, out int bytesRead)
{
//IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);
byte[] buffer = new byte[numOfBytes];
ReadProcessMemory(processHandle, new IntPtr(address), buffer, numOfBytes, out bytesRead);
return buffer;
}
public static bool WriteMemoryInt(IntPtr processHandle, int address, int value, out int bytesWritten)
{
//IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);
byte[] val = BitConverter.GetBytes(value);
bool worked = WriteProcessMemory(processHandle, new IntPtr(address), val, (UInt32)val.Length, out bytesWritten);
//CloseHandle(hProc);
return worked;
}
}
internal partial class CheatCore
{
public static CheatCore Inst = new CheatCore();
public const string ExeName = "PlantsVsZombies";
public IntPtr ProcessHandle { get; private set; } = IntPtr.Zero;
private static int plantInfoArrayBaseAddr = 0x69F2B0;
private static int platInfoClassSize = 36; //bytes
private static int sunCostOffset = 0x10;
private static int cdOffset = 0x14;
private static int plantCount = 48;
public void Init()
{
Process? process = Process.GetProcessesByName(ExeName).FirstOrDefault();
if(process == null)
{
MessageBox.Show($"cannot find process {ExeName}");
Environment.Exit(0);
return;
}
ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, process.Id);
}
public void SetCd0()
{
SetCardField(cdOffset, 0);
}
public void SetSunCost0()
{
SetCardField(sunCostOffset, 0);
}
public void SetCardField(int fieldOffset, int val)
{
if(ProcessHandle.Equals(IntPtr.Zero))
{
MessageBox.Show("not initialized");
return;
}
unsafe
{
for (int i = 0; i < plantCount; ++i)
{
var plantInfoAddress = plantInfoArrayBaseAddr + platInfoClassSize * i;
var fieldAddr = (plantInfoAddress + fieldOffset);
var worked = WriteMemoryInt(ProcessHandle, fieldAddr, val, out var bytesWritten);
if(worked == false)
{
int errCode = Marshal.GetLastWin32Error();
MessageBox.Show($"往{(int)fieldAddr:X}写入{val}失败,errCode={errCode}");
return;
}
}
}
}
}
效果链接 https://www.bilibili.com/video/BV1Cv4y147Ku/
标签:IntPtr,辅助,int,private,static,编写,wpf,public,out From: https://www.cnblogs.com/dewxin/p/17110077.html