原文:[转]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

  1. using System;
  2. using System.Drawing;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. namespace PlantsVsZombiesTool
  6. {
  7. /// <summary>
  8. ///
  9. /// </summary>
  10. public partial class Form1 : Form
  11. {
  12. public Form1()
  13. {
  14. InitializeComponent();
  15. }
  16. private void Form1_Load(object sender, EventArgs e)
  17. {
  18. }
  19. //启动无线阳光
  20. private void btnGet_Click(object sender, EventArgs e)
  21. {
  22. if (Helper.GetPidByProcessName(processName) == )
  23. {
  24. MessageBox.Show("哥们启用之前游戏总该运行吧!");
  25. return;
  26. }
  27. if (btnGet.Text == "启用-阳光无限")
  28. {
  29. timer1.Enabled = true;
  30. btnGet.Text = "关闭-阳光无限";
  31. }
  32. else
  33. {
  34. timer1.Enabled = false;
  35. btnGet.Text = "启用-阳光无限";
  36. }
  37. }
  38. private void timer1_Tick(object sender, EventArgs e)
  39. {
  40. if (Helper.GetPidByProcessName(processName) == )
  41. {
  42. timer1.Enabled = false;
  43. btnGet.Text = "启用-阳光无限";
  44. }
  45. int address = ReadMemoryValue(baseAddress); //读取基址(该地址不会改变)
  46. address = address + 0x768; //获取2级地址
  47. address = ReadMemoryValue(address);
  48. address = address + 0x5560; //获取存放阳光数值的地址
  49. WriteMemory(address, 0x1869F); //写入数据到地址(0x1869F表示99999)
  50. timer1.Interval = ;
  51. }
  52. //启动无线金钱
  53. private void btnMoney_Click(object sender, EventArgs e)
  54. {
  55. if (Helper.GetPidByProcessName(processName) == )
  56. {
  57. MessageBox.Show("哥们启用之前游戏总该运行吧!");
  58. return;
  59. }
  60. if (btnMoney.Text == "启用-金钱无限")
  61. {
  62. timer2.Enabled = true;
  63. btnMoney.Text = "关闭-金钱无限";
  64. }
  65. else
  66. {
  67. timer2.Enabled = false;
  68. btnMoney.Text = "启用-金钱无限";
  69. }
  70. }
  71. private void timer2_Tick(object sender, EventArgs e)
  72. {
  73. if (Helper.GetPidByProcessName(processName) == )
  74. {
  75. timer2.Enabled = false;
  76. btnMoney.Text = "启用-金钱无限";
  77. }
  78. int address = ReadMemoryValue(baseAddress); //读取基址(该地址不会改变)
  79. address = address + 0x82C; //获取2级地址
  80. address = ReadMemoryValue(address);
  81. address = address + 0x28; //得到金钱地址
  82. WriteMemory(address, 0x1869F); //写入数据到地址(0x1869F表示99999)
  83. timer2.Interval = ;
  84. }
  85. private void btnGo_Click(object sender, EventArgs e)
  86. {
  87. if (Helper.GetPidByProcessName(processName) == )
  88. {
  89. MessageBox.Show("哥们启用之前游戏总该运行吧!");
  90. return;
  91. }
  92. int address = ReadMemoryValue(baseAddress); //读取基址(该地址不会改变)
  93. address = address + 0x82C; //获取2级地址
  94. address = ReadMemoryValue(address);
  95. address = address + 0x24;
  96. int lev = ;
  97. try
  98. {
  99. lev = int.Parse(txtLev.Text.Trim());
  100. }
  101. catch
  102. {
  103. MessageBox.Show("输入的关卡格式不真确!默认设置为1");
  104. }
  105. WriteMemory(address, lev);
  106. }
  107. //读取制定内存中的值
  108. public int ReadMemoryValue(int baseAdd)
  109. {
  110. return Helper.ReadMemoryValue(baseAdd, processName);
  111. }
  112. //将值写入指定内存中
  113. public void WriteMemory(int baseAdd, int value)
  114. {
  115. Helper.WriteMemoryValue(baseAdd, processName, value);
  116. }
  117. private int baseAddress = 0x006A9EC0; //游戏内存基址
  118. private string processName = "PlantsVsZombies"; //游戏进程名字
  119. }
  120. }
  121.  

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

C# code

  1. using System;
  2. using System.Text;
  3. using System.Diagnostics;
  4. using System.Runtime.InteropServices;
  5. namespace PlantsVsZombiesTool
  6. {
  7. public abstract class Helper
  8. {
  9. [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
  10. public static extern bool ReadProcessMemory
  11. (
  12. IntPtr hProcess,
  13. IntPtr lpBaseAddress,
  14. IntPtr lpBuffer,
  15. int nSize,
  16. IntPtr lpNumberOfBytesRead
  17. );
  18. [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
  19. public static extern IntPtr OpenProcess
  20. (
  21. int dwDesiredAccess,
  22. bool bInheritHandle,
  23. int dwProcessId
  24. );
  25. [DllImport("kernel32.dll")]
  26. private static extern void CloseHandle
  27. (
  28. IntPtr hObject
  29. );
  30. //写内存
  31. [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
  32. public static extern bool WriteProcessMemory
  33. (
  34. IntPtr hProcess,
  35. IntPtr lpBaseAddress,
  36. int[] lpBuffer,
  37. int nSize,
  38. IntPtr lpNumberOfBytesWritten
  39. );
  40. //获取窗体的进程标识ID
  41. public static int GetPid(string windowTitle)
  42. {
  43. int rs = ;
  44. Process[] arrayProcess = Process.GetProcesses();
  45. foreach (Process p in arrayProcess)
  46. {
  47. if (p.MainWindowTitle.IndexOf(windowTitle) != -)
  48. {
  49. rs = p.Id;
  50. break;
  51. }
  52. }
  53. return rs;
  54. }
  55. //根据进程名获取PID
  56. public static int GetPidByProcessName(string processName)
  57. {
  58. Process[] arrayProcess = Process.GetProcessesByName(processName);
  59. foreach (Process p in arrayProcess)
  60. {
  61. return p.Id;
  62. }
  63. return ;
  64. }
  65. //根据窗体标题查找窗口句柄(支持模糊匹配)
  66. public static IntPtr FindWindow(string title)
  67. {
  68. Process[] ps = Process.GetProcesses();
  69. foreach (Process p in ps)
  70. {
  71. if (p.MainWindowTitle.IndexOf(title) != -)
  72. {
  73. return p.MainWindowHandle;
  74. }
  75. }
  76. return IntPtr.Zero;
  77. }
  78. //读取内存中的值
  79. public static int ReadMemoryValue(int baseAddress,string processName)
  80. {
  81. try
  82. {
  83. byte[] buffer = new byte[];
  84. IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, ); //获取缓冲区地址
  85. IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
  86. ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, , IntPtr.Zero); //将制定内存中的值读入缓冲区
  87. CloseHandle(hProcess);
  88. return Marshal.ReadInt32(byteAddress);
  89. }
  90. catch
  91. {
  92. return ;
  93. }
  94. }
  95. //将值写入指定内存地址中
  96. public static void WriteMemoryValue(int baseAddress, string processName, int value)
  97. {
  98. IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
  99. WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, , IntPtr.Zero);
  100. CloseHandle(hProcess);
  101. }
  102. }
  103. }
  104.  

C#内存操作的更多相关文章

  1. java 21-11 数据输入、输出流和内存操作流

    IO数据流: 可以读写基本数据类型的数据 数据输入流:DataInputStream DataInputStream(InputStream in)   数据输出流:DataOutputStream ...

  2. 【转】《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误

    原文地址:http://blog.csdn.net/slvher/article/details/9150597 对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构 ...

  3. c++ void,内存操作函数

    void的含义 void的字面意思是“无类型”, void * 则为“无类型指针”, void * 可以指向任何类型的数据 void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变 ...

  4. java基础知识回顾之javaIO类--内存操作流ByteArrayInputStream和ByteArrayOutputSteam(操作字节数组)

    直接看代码: package cn.itcast.io.p6.bytestream; import java.io.ByteArrayInputStream; import java.io.ByteA ...

  5. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  6. 【C++基础】内存操作 getMemory改错

    内存操作的考察点:①指针 ②变量生存期及作用范围 ③动态内存申请和释放 笔试题************************************************************* ...

  7. 《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误

    对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构成的模块跑起来后才出现内存崩溃,是很让人痛苦的.因为崩溃的位置在时间和空间上,通常是在距真正的错误源一段距离之后才 ...

  8. Java基础知识强化之IO流笔记58:内存操作流

    1. 内存操作流: 用来操作处理临时存储的信息的. (1)操作字节数组: ByteArrayInputStream ByteArrayOutputStream 代码示例: package cn.itc ...

  9. C语言嵌入式系统编程修炼之三:内存操作

    数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力.在嵌入式系统的实际调试中,多借助C语言指针所具 ...

  10. Marshal 类的内存操作的一般功能

    Marshal类 提供了一个方法集,这些方法用于分配非托管内存.复制非托管内存块.将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法. 命名空间:System.Runtim ...

随机推荐

  1. Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to “*****”

    Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment ...

  2. 常用工具类,文件和内存的大小获取,shell脚本的执行

    /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Versi ...

  3. 使用pymysql连接MySql数据库

    MySQLdb安装失败了,直接使用pymysql,安装了pymysql. 并学习了使用使用pymysql创建数据库和表,并插入数据. __author__ = 'Administrator' impo ...

  4. Hadoop伪分布式搭建步骤

    说明: 搭建环境是VMware10下用的是Linux CENTOS 32位,Hadoop:hadoop-2.4.1  JAVA :jdk7 32位:本文是本人在网络上收集的HADOOP系列视频所附带的 ...

  5. system.exit(0) vs system.exit(1)

    2.解析 查看java.lang.System的源代码,我们可以找到System.exit(status)这个方法的说明,代码如下: /** * Terminates the currently ru ...

  6. KeybMap 键盘映射工具更新至 V1.5(修订)

    KeybMap 更新至 V1.5,主要是增加了对一些多媒体键定义修改功能,也可以将任意一键定义为打开指定的程序. 3月9日略做修订. http://www.mympc.org/down/1/2005- ...

  7. QT:用QSet储存自定义结构体的问题——QSet和STL的set是有本质区别的,QSet是基于哈希算法的,要求提供自定义==和qHash函数

    前几天要用QSet作为储存一个自定义的结构体(就像下面这个程序一样),结果死活不成功... 后来还跑到论坛上问人了,丢脸丢大了... 事先说明:以下这个例子是错误的 #include <QtCo ...

  8. [Leetcode][Python]45: Jump Game II

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 45: Jump Game IIhttps://oj.leetcode.com ...

  9. tsm ANS0326E问题处理

    备份tsm备份oracle 报错 ANS0326E This node has exceeded its maximum number of mount points. 查看所有节点详细信息 q no ...

  10. 3、使用Lucene实现千度搜索

    1.新建Web项目 新建一个Web项目,我命名为SearchEngine,然后导入Java包: 除了上篇博客中的Jar包外,我还引入了 IKAnalyzer2012_FF.jar 包和struts2的 ...