«

C#植物大战僵尸修改阳光

hujiato 发布于 阅读:118 编程


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program
{
    // 导入Windows API函数,用于进程内存操作
    [DllImport("kernel32.dll")]
    private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [DllImport("kernel32.dll")]
    private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesRead);

    [DllImport("kernel32.dll")]
    private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesWritten);

    [DllImport("kernel32.dll")]
    private static extern bool CloseHandle(IntPtr hObject);
    // 进程访问权限常量
    const int PROCESS_VM_READ = 0x0010;       // 允许读取进程内存
    const int PROCESS_VM_WRITE = 0x0020;      // 允许写入进程内存
    const int PROCESS_VM_OPERATION = 0x0008;  // 允许在进程的地址空间中进行操作
    static void Main()
    {
        try
        {
            // 查找植物大战僵尸游戏进程
            Process[] processes = Process.GetProcessesByName("PlantsVsZombies");
            if (processes.Length == 0)
            {
                Console.WriteLine("未找到植物大战僵尸游戏进程,请先启动游戏!");
                Console.ReadKey();
                return;
            }
            // 获取游戏进程句柄,用于后续的内存操作
            Process gameProcess = processes[0];
            IntPtr processHandle = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, gameProcess.Id);
            Console.WriteLine("processHandle:" + processHandle);
            if (processHandle == IntPtr.Zero)
            {
                Console.WriteLine("无法获取游戏进程的访问权限!可能需要管理员权限。");
                Console.ReadKey();
                return;
            }

            // 阳光值的基址(游戏内存中的固定起始地址)
            // 注意:此地址可能因游戏版本不同而变化
            IntPtr baseAddress = (IntPtr)0x00755EAC;
            Console.WriteLine("baseAddress:" + baseAddress);

            // 阳光值的多级指针偏移
            // 游戏中的实际数据地址 = 基址 + 偏移1 + 偏移2
            int[] offsets = { 0x868, 0x5578 };

            // 用于存储读取的内存数据和计算的地址
            IntPtr pointerAddress = IntPtr.Zero;
            byte[] buffer = new byte[4];  // 4字节用于存储整数类型的阳光值
            int bytesRead;

            // 第一步:读取一级指针
            // 从基址读取内存中的值,得到第一个中间地址
            if (!ReadProcessMemory(processHandle, baseAddress, buffer, 4, out bytesRead))
            {
                Console.WriteLine("读取一级指针失败!可能游戏版本不兼容。");
                CloseHandle(processHandle);
                Console.ReadKey();
                return;
            }

            // 计算下一级指针地址:基址值 + 第一个偏移量
            pointerAddress = (IntPtr)(BitConverter.ToInt32(buffer, 0) + offsets[0]);

            // 第二步:读取二级指针
            // 从中间地址读取内存中的值,得到阳光值的实际存储地址
            if (!ReadProcessMemory(processHandle, pointerAddress, buffer, 4, out bytesRead))
            {
                Console.WriteLine("读取二级指针失败!可能游戏版本不兼容。");
                CloseHandle(processHandle);
                Console.ReadKey();
                return;
            }

            // 计算阳光值的最终地址:中间地址值 + 第二个偏移量
            pointerAddress = (IntPtr)(BitConverter.ToInt32(buffer, 0) + offsets[1]);

            // 读取当前阳光值
            if (!ReadProcessMemory(processHandle, pointerAddress, buffer, 4, out bytesRead))
            {
                Console.WriteLine("读取阳光值失败!可能游戏版本不兼容。");
                CloseHandle(processHandle);
                Console.ReadKey();
                return;
            }

            // 将字节数据转换为整数
            int currentSun = BitConverter.ToInt32(buffer, 0);
            Console.WriteLine($"当前阳光值: {currentSun}");

            // 获取用户输入的新阳光值
            Console.Write("请输入新的阳光值(0-9999): ");
            if (!int.TryParse(Console.ReadLine(), out int newSun) || newSun < 0 || newSun > 9999)
            {
                Console.WriteLine("请输入有效的阳光值(0-9999)!");
                CloseHandle(processHandle);
                Console.ReadKey();
                return;
            }
            // 将新阳光值转换为字节数组
            byte[] newSunBytes = BitConverter.GetBytes(newSun);
            int bytesWritten;

            // 写入新的阳光值到游戏内存
            if (!WriteProcessMemory(processHandle, pointerAddress, newSunBytes, 4, out bytesWritten))
            {
                Console.WriteLine("修改阳光值失败!可能需要管理员权限或游戏版本不兼容。");
                CloseHandle(processHandle);
                Console.ReadKey();
                return;
            }

            Console.WriteLine($"阳光值已成功修改为: {newSun}");
            Console.WriteLine("请返回游戏查看效果。按任意键退出...");

            // 关闭进程句柄,释放资源
            CloseHandle(processHandle);
            Console.ReadKey();
        }

        catch (Exception ex)
        {
            Console.WriteLine($"发生错误: {ex.Message}");
            Console.ReadKey();
        }
    }
    }

文章目录