`

[转]C#内存操作

    博客分类:
  • 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);
        }
    }
}

 

分享到:
评论

相关推荐

    C# 操作内存 C# 操作内存

    ### 三、内存操作的关键方法 #### 1. `GetPidByProcessName` 用于获取指定进程名称对应的进程ID。 #### 2. `ReadMemoryValue` 读取指定内存地址的数据。 #### 3. `WriteMemory` 将数据写入指定内存地址。 ### 四、...

    c#内存检测工具-----

    C#内存检测工具是开发过程中不可或缺的辅助软件,主要用于诊断和优化C#应用程序的内存使用情况。在.NET框架下,C#程序的内存管理主要由垃圾收集器(Garbage Collector, GC)负责,但理解并控制内存使用仍然是开发者...

    c# 内存共享操作,可以创建、读取、写入内存共享区

    c# 内存共享操作,可以创建、读取、写入内存共享区,

    c#编写的内存读取修改器

    这个项目对于学习C#内存操作和进程通信有很高的价值,同时也可以帮助开发者理解程序执行的底层机制。在游戏开发、性能优化、调试等方面,这样的工具也能发挥重要作用。 通过以上分析,我们可以看出C#编写的内存...

    c++转C#工具

    标签"C++转C#"进一步明确了讨论的主题,它是关于两种编程语言之间的互操作性,可能涉及到.NET互操作性(如P/Invoke或CLR托管C++),或者是更纯粹的代码转换。 压缩包内的文件: 1. "CPlus to CSharp Converter Help...

    C#内存修改器源码2012918

    总的来说,C#内存修改器源码的研读和实践,对于提升程序员对进程管理、内存操作、数据类型转换等方面的理解和技能大有裨益。无论是出于学术研究还是实际开发需求,理解并掌握这种工具的实现都是很有价值的。然而,...

    C# 内存修改器 (源码)

    2. **内存操作**:内存修改器的核心功能是读取和修改进程内存中的数据。在C#中,这通常通过`System.Diagnostics.Process`类和`IntPtr`类型来实现。`Process`类用于获取进程信息和创建进程句柄,`IntPtr`则用于指针...

    C++转C#的自动工具

    它的强项在于性能、低级别内存管理和灵活性,常用于游戏开发、操作系统和嵌入式系统等对性能要求高的领域。 而C#(读作“C sharp”)是微软开发的一种面向对象的、现代的、类型安全的编程语言,主要用于Windows平台...

    C#内存修改器(仿CE)

    好吧 我承认这东西效率真不咋地 也别喷我的代码 我承认我的代码写的也不咋地 ...还有就是 这程序 可能存在许多潜在的bug 比如内存溢出 不过我能知道的或者知道怎么解决的问题 我已近解决了 总之 这代码仅供参考

    C#内存修改器最新源码

    下面我们将深入探讨C#内存修改器的相关知识点。 首先,我们要了解C#的基础。C#是微软公司推出的一种面向对象的编程语言,它具有类型安全、垃圾回收等特点,广泛应用于Windows桌面应用、游戏开发和Web服务等领域。在...

    C# 内存修改 ……

    5. 性能优化:在某些性能敏感的场景下,直接内存操作可以提升程序效率。例如,减少不必要的对象创建和销毁,或者使用unsafe代码进行位操作。 6. 安全性与风险:直接修改内存可能会破坏数据一致性,导致程序崩溃或者...

    c#游戏内存修改示例代码

    `UnmanagedExports`则用于导出C#中的函数供其他非托管(如C++)代码调用,这样可以在C#代码中实现内存操作后,通过C++动态链接库(DLL)与游戏进程进行交互。 在"PlantsVsZombiesTool"这个示例中,可能包含了以下关键...

    C#内存管理变化.pdf

    ### C#内存管理变化 #### 一、C++的手动回收机制 在C++中,内存管理主要依赖于程序员手动地使用`new`和`delete`操作符来分配和释放内存。这种机制给予程序员极大的灵活性和控制力,让他们能够决定何时销毁对象并...

    c++ 转换c# 工具

    C++和C#虽然都是面向对象的语言,但在许多方面存在显著差异,如C++支持指针操作,而C#更倾向于安全的引用;C++有预处理器宏,C#则使用特性(Attributes);此外,C#的垃圾回收机制与C++的内存管理方式也大相径庭。 ...

    操作系统课程设计 c#版(cpu,内存,磁盘)

    在这个“操作系统课程设计 c#版(cpu,内存,磁盘)”中,我们将探讨如何使用C#编程语言来模拟操作系统的几个关键组件:CPU调度、内存管理、磁盘管理和I/O管理。以下是对这些主题的详细说明: 1. **CPU管理**: - ...

    C# Winform windows运行内存释放

    本项目“C# Winform Windows运行内存释放”旨在解决计算机运行过程中内存占用过高导致的性能问题。通过编写这样的小程序,我们可以帮助用户管理他们的系统资源,提高计算机的响应速度和整体性能。 在Windows操作...

    C#操作共享内存读写工程

    在这个"C#操作共享内存读写工程"中,我们将探讨如何利用C#语言来实现这一功能。共享内存在多线程或多进程环境下尤其有用,因为它避免了传统IPC方法(如管道、套接字或消息队列)的数据复制开销。 首先,我们需要...

    C#实现共享内存通讯交互

    首先,我们要了解C#中的内存管理主要是通过.NET框架的垃圾回收机制来完成的,它并不直接支持原生的共享内存操作。但是,我们可以通过P/Invoke技术调用Windows API来实现这一功能。Windows API中的`CreateFileMapping...

    c#共享内存实例源码 CSharp ShareMemory

    C#共享内存的实例,附源码和工程文件。 网上有C#的共享内存类,不过功能太简单了。 故,对此进行了改进。通过利用共享内存的一部分空间来存储当前内存中存储的数据信息(count和length),完成了对内存读写功能的...

    C# 共享内存 存储

    C# 共享内存 存储 C# 共享内存 存储 C# 共享内存 存储

Global site tag (gtag.js) - Google Analytics