• C# 外挂


    最近闲来无事发现周围的朋友都在玩《植物大战僵尸》的游戏!于是动了制作这游戏工具的念头!虽然在网上同类工具很多 但是用C#写的我几乎看不到!所以我想用C#写一个!
      首先用CE或者OD或者其他反汇编工具找出游戏的内存基址!
      游戏内存基址:base = 0x006A9EC0
      游戏阳光地址:[base+0x768]+0x5560
      游戏金钱地址:[base+0x82C]+0x28
      游戏关卡地址:[base+0x82C]+0x24 //关卡如:A-B 实际值为:(A-1)×10+B
    至于如何获取这些地址不在我们这论坛研究的范围中!
    对了我是用工具vs2008编写的!
    新建窗体:

    using System;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace PlantsVsZombiesTool
    {
        /// <summary>
        /// 
        /// </summary>
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
               
            }
    
            //启动无线阳光
            private void btnGet_Click(object sender, EventArgs e)
            {
                if (Helper.GetPidByProcessName(processName) == 0)
                {
                    MessageBox.Show("哥们启用之前游戏总该运行吧!");
                    return;
                }
                if (btnGet.Text == "启用-阳光无限")
                {
                    timer1.Enabled = true;
                    btnGet.Text = "关闭-阳光无限";
                }
                else
                {
                    timer1.Enabled = false;
                    btnGet.Text = "启用-阳光无限";
                } 
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
    
                if (Helper.GetPidByProcessName(processName) == 0)
                {
                    timer1.Enabled = false;
                    btnGet.Text = "启用-阳光无限";
                }
                int address = ReadMemoryValue(baseAddress);             //读取基址(该地址不会改变)
                address = address + 0x768;                              //获取2级地址
                address = ReadMemoryValue(address);
                address = address + 0x5560;                             //获取存放阳光数值的地址
                WriteMemory(address, 0x1869F);                          //写入数据到地址(0x1869F表示99999)
                timer1.Interval = 1000;
            }
    
            //启动无线金钱
            private void btnMoney_Click(object sender, EventArgs e)
            {
    
                if (Helper.GetPidByProcessName(processName) == 0)
                {
                    MessageBox.Show("哥们启用之前游戏总该运行吧!");
                    return;
                }
                if (btnMoney.Text == "启用-金钱无限")
                {
                    timer2.Enabled = true;
                    btnMoney.Text = "关闭-金钱无限";
                }
                else
                {
                    timer2.Enabled = false;
                    btnMoney.Text = "启用-金钱无限";
                } 
            }
    
            private void timer2_Tick(object sender, EventArgs e)
            {
                if (Helper.GetPidByProcessName(processName) == 0)
                {
                    timer2.Enabled = false;
                    btnMoney.Text = "启用-金钱无限";
                }
                int address = ReadMemoryValue(baseAddress);             //读取基址(该地址不会改变)
                address = address + 0x82C;                              //获取2级地址
                address = ReadMemoryValue(address);
                address = address + 0x28;                               //得到金钱地址
                WriteMemory(address, 0x1869F);                          //写入数据到地址(0x1869F表示99999)
                timer2.Interval = 1000;
            }
    
            private void btnGo_Click(object sender, EventArgs e)
            {
                if (Helper.GetPidByProcessName(processName) == 0)
                {
                    MessageBox.Show("哥们启用之前游戏总该运行吧!");
                    return;
                }
                int address = ReadMemoryValue(baseAddress);             //读取基址(该地址不会改变)
                address = address + 0x82C;                              //获取2级地址
                address = ReadMemoryValue(address);
                address = address + 0x24;
                int lev = 1;
                try
                {
                    lev = int.Parse(txtLev.Text.Trim());
                }
                catch 
                {
                    MessageBox.Show("输入的关卡格式不真确!默认设置为1");
                }
    
                WriteMemory(address, lev);
                
            }
    
            //读取制定内存中的值
            public int ReadMemoryValue(int baseAdd)
            {
                return Helper.ReadMemoryValue(baseAdd, processName);  
            }
    
            //将值写入指定内存中
            public void WriteMemory(int baseAdd, int value)
            {
                Helper.WriteMemoryValue(baseAdd, processName, value);
            }
    
            private int baseAddress = 0x006A9EC0;           //游戏内存基址
            private string processName = "PlantsVsZombies"; //游戏进程名字
        }
    }

    下面这个类是整个工具的核心

    using System;
    using System.Text;
    
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace PlantsVsZombiesTool
    {
        
        public abstract class Helper
        {
            [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
            public static extern bool ReadProcessMemory
                (
                    IntPtr hProcess,
                    IntPtr lpBaseAddress,
                    IntPtr lpBuffer,
                    int nSize,
                    IntPtr lpNumberOfBytesRead
                );
    
            [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
            public static extern IntPtr OpenProcess
                (
                    int dwDesiredAccess, 
                    bool bInheritHandle, 
                    int dwProcessId
                );
    
            [DllImport("kernel32.dll")]
            private static extern void CloseHandle
                (
                    IntPtr hObject
                );
    
            //写内存
            [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
            public static extern bool WriteProcessMemory
                (
                    IntPtr hProcess, 
                    IntPtr lpBaseAddress, 
                    int[] lpBuffer, 
                    int nSize, 
                    IntPtr lpNumberOfBytesWritten
                );
    
            //获取窗体的进程标识ID
            public static int GetPid(string windowTitle)
            {
                int rs = 0;
                Process[] arrayProcess = Process.GetProcesses();
                foreach (Process p in arrayProcess)
                {
                    if (p.MainWindowTitle.IndexOf(windowTitle) != -1)
                    {
                        rs = p.Id;
                        break;
                    }
                }
    
                return rs;
            }
    
            //根据进程名获取PID
            public static int GetPidByProcessName(string processName)
            {
                Process[] arrayProcess = Process.GetProcessesByName(processName);
    
                foreach (Process p in arrayProcess)
                {
                    return p.Id;
                }
                return 0;
            }
    
            //根据窗体标题查找窗口句柄(支持模糊匹配)
            public static IntPtr FindWindow(string title)
            {
                Process[] ps = Process.GetProcesses();
                foreach (Process p in ps)
                {
                    if (p.MainWindowTitle.IndexOf(title) != -1)
                    {
                        return p.MainWindowHandle;
                    }
                }
                return IntPtr.Zero;
            }
    
            //读取内存中的值
            public static int ReadMemoryValue(int baseAddress,string processName)
            {
                try
                {
                    byte[] buffer = new byte[4];
                    IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
                    IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
                    ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
                    CloseHandle(hProcess);
                    return Marshal.ReadInt32(byteAddress);
                }
                catch 
                {
                    return 0;
                }
            }
    
            //将值写入指定内存地址中
            public static void WriteMemoryValue(int baseAddress, string processName, int value)
            {
                IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
                WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero);
                CloseHandle(hProcess);
            }
        }
    }

     

  • 相关阅读:
    #2051:Bitset(进制转化)
    #2054:A == B ?(水题坑人)
    #2045:不容易系列之三LELE的RPG难题(dp递推)
    #2037:今年暑假不AC
    #2036:改革春风吹满地
    OJ中的语言选项里G++ 与 C++的区别
    如何在CSDN上如何快速转载博客
    Python之路(第八篇)Python内置函数、zip()、max()、min()
    Python编程笔记(第一篇)Python基础语法
    Python之路(第七篇)Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数
  • 原文地址:https://www.cnblogs.com/crazyxu/p/2677543.html
Copyright © 2020-2023  润新知