C#内存操作

简介: 原文:[转]C#内存操作最近闲来无事发现周围的朋友都在玩《植物大战僵尸》的游戏!于是动了制作这游戏工具的念头!虽然在网上同类工具很多 但是用C#写的我几乎看不到!所以我想用C#写一个!  首先用CE或者OD或者其他反汇编工具找出游戏的内存基址!  游戏内存基址:base = 0x006A9EC0 ...
原文: [转]C#内存操作

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


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

C# 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); } } }
目录
相关文章
|
8月前
|
存储 Java C#
C# 中的值类型与引用类型:内存大小解析
C# 中的值类型与引用类型:内存大小解析
106 2
|
4月前
|
C# 开发工具 Windows
C# 获取Windows系统信息以及CPU、内存和磁盘使用情况
C# 获取Windows系统信息以及CPU、内存和磁盘使用情况
110 0
|
9月前
|
存储 C#
C# | 内存池
内存池可以复用已申请的内存空间,它在程序启动时预先分配一定数量的内存块,当你需要使用内存时,则会从内存池中分配一块空闲内存,也就是说并不是每次都会向系统申请一块新的内存空间。 同理,当你使用完一块内存空间后,并不是直接释放内存,而是将其归还到内存池中。内存池就是通过这样一借一还的方式避免了频繁地分配和释放内存,减少了内存碎片和系统开销,提高了程序的性能。
90 0
|
9月前
|
存储 Java C#
C# | 使用Memory<T>高效地读写内存数据
Memory<T>是什么? 它是一种可变大小、可读写的内存块,可以安全地暴露给用户代码进行操作。 为什么要使用Memory<T>? 使用它有许多好处。最主要的是善用它可以提高代码的性能。因为Memory<T>是可变的,所以我们可以直接在内存中操作数据,而不需要进行额外的拷贝操作。 使用Memory<T>还可以减少垃圾回收的压力,因为我们不需要创建新的对象来存储数据。 Memory<T>还可以与Span<T>和ReadOnlySpan<T>类型一起使用,这些类型可以方便地对数据进行访问和操作。
163 0
|
存储 Java C#
C# 垃圾回收机制(GC) 的概述 资源清理 内存管理
C# 垃圾回收机制(GC) 的概述 资源清理 内存管理
|
存储 C#
C# “值类型“和“引用类型“在内存的分配
C# “值类型“和“引用类型“在内存的分配
|
测试技术 C#
C#不通过byte[],直接对内存映射文件复制内存
C#不通过byte[],直接对内存映射文件复制内存
|
SQL 关系型数据库 API
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(三)
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(三)
|
SQL 存储 安全
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(二)
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化