zoukankan      html  css  js  c++  java
  • C#内存操作

    原文地址:http://devilhand.iteye.com/blog/810779

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


    新建窗体(WinForm):

    View Code
    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"; //游戏进程名字
        }
    }

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

    View Code
    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);
            }
        }
    }

     

  • 相关阅读:
    HDU 2236 无题Ⅱ
    Golden Tiger Claw(二分图)
    HDU 5969 最大的位或 (思维,贪心)
    HDU 3686 Traffic Real Time Query System (图论)
    SCOI 2016 萌萌哒
    Spring Boot支持控制台Banner定制
    构建第一个Spring Boot程序
    Spring Boot重要模块
    Java fastjson JSON和String互相转换
    BCompare 4 Windows激活方法【试用期30天重置】
  • 原文地址:https://www.cnblogs.com/3Tai/p/2878608.html
Copyright © 2011-2022 走看看