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



本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/03/26/1697053.html,如需转载请自行联系原作者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值