本示例以植物大战僵尸为例, 实现功能为 每1秒让阳光刷新为 9999.本示例使用的游戏版本为 [植物大战僵尸2010年度版], 使用的辅助查看内存地址的工具是  CE.

由于每次启动游戏, 游戏中阳光地址都是变的, 唯一不变的基址1, 我们要通过CE工具找到基址1的地址, 可以算出阳光的地址.

基址2的地址 = 基址1中的值 + 偏移1;

阳光的的地址 = 基址2中的值 + 偏移2;

以下为简单示例:  窗口界面一个按钮 和 一个定时器

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics; namespace ZhiWuDaZhanJiangShi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} #region API //从指定内存中读取字节集数据
[DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern bool ReadProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,IntPtr lpBuffer,int nSize,IntPtr lpNumberOfBytesRead); //从指定内存中写入字节集数据
[DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
public static extern bool WriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,int[] lpBuffer,int nSize, IntPtr lpNumberOfBytesWritten ); //打开一个已存在的进程对象,并返回进程的句柄
[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); #endregion #region 使用方法 //根据进程名获取PID
public static int GetPidByProcessName(string processName)
{
Process[] arrayProcess = Process.GetProcessesByName(processName);
foreach (Process p in arrayProcess)
{
return p.Id;
}
return ;
} //读取内存中的值
public static int ReadMemoryValue(int baseAddress, string processName)
{
try
{
byte[] buffer = new byte[];
//获取缓冲区地址
IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, );
//打开一个已存在的进程对象 0x1F0FFF 最高权限
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
//将制定内存中的值读入缓冲区
ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, , IntPtr.Zero);
//关闭操作
CloseHandle(hProcess);
//从非托管内存中读取一个 32 位带符号整数。
return Marshal.ReadInt32(byteAddress);
}
catch
{
return ;
}
} //将值写入指定内存地址中
public static void WriteMemoryValue(int baseAddress, string processName, int value)
{
try
{
//打开一个已存在的进程对象 0x1F0FFF 最高权限
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
//从指定内存中写入字节集数据
WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, , IntPtr.Zero);
//关闭操作
CloseHandle(hProcess);
}
catch { }
} #endregion //游戏内存基址
private int baseAddress = 0x0015E944;
//游戏进程名字
private string processName = "PlantsVsZombies"; //开启/关闭 功能 的按钮
private void button1_Click(object sender, EventArgs e)
{
if (GetPidByProcessName(processName) == )
{
MessageBox.Show("游戏没有运行!");
return;
}
if (button1.Text == "开启")
{
button1.Text = "关闭";
timer1.Enabled = true;
}
else
{
button1.Text = "开启";
timer1.Enabled = false;
}
} //定时器
private void timer1_Tick(object sender, EventArgs e)
{
if (GetPidByProcessName(processName) == )
{
timer1.Enabled = false;
}
//baseAddress : 游戏内存基址 processName : 游戏进程名
//读取 基址1 中存放的值
int address = ReadMemoryValue(baseAddress, processName);
//计算 基址2的地址 = 基址1中的值 + 偏移量1
address = address + 0x868;
//读取 基址2 中存放的值
address = ReadMemoryValue(address, processName);
//计算 阳光的地址 = 基址2中的值 + 偏移量2
address = address + 0x5578;
//给阳光地址中写入数值,0x378 : 888
WriteMemoryValue(address, processName, 0x378);
}
}
}

下面增加了一个刷新金币的示例 (注意, 金币值是界面的金币输 除以 10 , 我们刷100 在界面里面显示为1000)

        private void button2_Click(object sender, EventArgs e)
{
if (GetPidByProcessName(processName) == )
{
MessageBox.Show("游戏没有运行!");
return;
} //baseAddress : 游戏内存基址 processName : 游戏进程名
//读取 基址1 中存放的值
int address = ReadMemoryValue(baseAddress, processName);
//计算 基址2的地址 = 基址1中的值 + 偏移量1
address = address + 0x950;
//读取 基址2 中存放的值
address = ReadMemoryValue(address, processName);
//计算 阳光的地址 = 基址2中的值 + 偏移量2
address = address + 0x50;
//给阳光地址中写入数值,0x378 : 888
WriteMemoryValue(address, processName, GetInt(textBox2.Text));
} private int GetInt(string s)
{
int n = ;
int.TryParse(s, out n);
if (n <= )
{
n = ;
}
return n;
}

今天又增加了无植物无冷却时间的功能

        int count = ;
private void Form1_Load(object sender, EventArgs e)
{
if (GetPidByProcessName(processName) != )
{
int address = ReadMemoryValue(baseAddress, processName);
address = address + 0x868;
address = ReadMemoryValue(address, processName);
address = address + 0x15c;
address = ReadMemoryValue(address, processName);
address = address + 0x24;
address = ReadMemoryValue(address, processName);
count = address;
label3.Text = "植物栏个数: " + address.ToString() + " 个";
}
} private void timer2_Tick(object sender, EventArgs e)
{
if (GetPidByProcessName(processName) == )
{
timer2.Enabled = false;
}
if (count > )
{
for (int i = ; i < count; i++)
{
int address = ReadMemoryValue(baseAddress, processName);
address = address + 0x868;//一级地址
address = ReadMemoryValue(address, processName);
address = address + 0x15c;//二级地址
address = ReadMemoryValue(address, processName);
address = address + 0x4c;//第一栏 植物的地址
// 每后一个植物 地址 偏移 50 (在十进制里是80)
//偏移 0x24 的地址 是标示是否在冷却中 值 :( 0 : 为冷却中, 1 为冷却完成)
address = address + * i + 0x24;
WriteMemoryValue(address, processName, );
//如果不偏移 0x24 的地址为冷却时间地址, 值不确定, 一般最大设为6000 也可以完成此功能
//address = address + 80 * i;
//WriteMemoryValue(address, processName, 6000);
}
}
else
{
int address = ReadMemoryValue(baseAddress, processName);
address = address + 0x868;
address = ReadMemoryValue(address, processName);
address = address + 0x15c;
address = ReadMemoryValue(address, processName);
address = address + 0x24;
address = ReadMemoryValue(address, processName);
count = address;
label3.Text = "植物栏个数: " + address.ToString() + " 个";
}
} private void button3_Click(object sender, EventArgs e)
{
if (GetPidByProcessName(processName) == )
{
MessageBox.Show("游戏没有运行!");
return;
}
if (button3.Text == "有冷却")
{
button3.Text = "无冷却";
timer2.Enabled = true;
}
else
{
button3.Text = "有冷却";
timer2.Enabled = false;
}
}

C# 操作地址 从内存中读取写入数据(初级)的更多相关文章

  1. FFMPEG内存操作(二)从内存中读取数及数据格式的转换

    相关博客列表: FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析 FFMPEG内存操作(二)从内存中读取数及数据格式的转换 FFmpeg内存操作(三)内存转码器 在雷神 ...

  2. 数据库的应用——直接从内存中读取osg节点 (转)

    数据库的应用——直接从内存中读取osg节点 目的:要从数据库中读取节点数据到osg. 一开始的方法是这样的,每当我要添加一个数据库中的节点数据时,首先把它读取到内存中,然后写入一个文件,最后再次从文件 ...

  3. ffmpeg 从内存中读取数据(或将数据输出到内存)

    更新记录(2014.7.24): 1.为了使本文更通俗易懂,更新了部分内容,将例子改为从内存中打开. 2.增加了将数据输出到内存的方法. 从内存中读取数据 ffmpeg一般情况下支持打开一个本地文件, ...

  4. ffmpeg 从内存中读取数据(或将数据输出到内存)(转)

    更新记录(2014.7.24): 1.为了使本文更通俗易懂,更新了部分内容,将例子改为从内存中打开. 2.增加了将数据输出到内存的方法. 从内存中读取数据 ffmpeg一般情况下支持打开一个本地文件, ...

  5. ffmpeg 从内存中读取数据 .

    http://blog.csdn.net/leixiaohua1020/article/details/12980423 ——————————————————————————————————————— ...

  6. C/C++程序从文本文件中读取(保存)数据

    :本文仅供初学者参阅,解惑 在C程序中: 与程序代码外的数据(文件)打交道,我们使用到流(stream)这个概念,实现进程的虚拟内存与文件之间的数据交换. ——文件流:C标准库提供了FILE(之所以命 ...

  7. 用多态来实现U盘,Mp3,移动硬盘和电脑的对接,读取写入数据。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. matlab中读取txt数据文件(txt文本文档)

    matlab中读取txt数据文件(txt文本文档) 根据txt文档不同种类介绍不同的读取数据方法 一.纯数据文件(没有字母和中文,纯数字) 对于这种txt文档,从matalb中读取就简单多了 例如te ...

  9. <转>libjpeg解码内存中的jpeg数据

    转自http://my.unix-center.net/~Simon_fu/?p=565 熟悉libjpeg的朋友都知道libjpeg是一个开源的库.Linux和Android都是用libjpeg来 ...

随机推荐

  1. 20191121-5 Scrum立会报告+燃尽图 01

    此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/10065 一.小组情况 组长:贺敬文组员:彭思雨 王志文 位军营 徐丽君队名 ...

  2. Linux系统下关闭与启动Oracle11g的顺序与命令

    关闭: 1.关EM:[oracle@localhost ~] emctl stop dbconsole 2.关监听:[oracle@localhost ~] lsnrctl stop 3.关数据库:S ...

  3. 修改网卡缓存,解决Linux 网卡丢包严重问题

    Linux 网卡丢包严重 生产中有一台linux设备并发比较大,droped包比较多,尤其是在跑游戏数据包的时候,存在严重的丢包现象,怀疑网卡性能不足,在更换设备前想能不有通过软件方法解决,通过网上一 ...

  4. Python 生成随机数函数和加密函数(MD5)

    内容来自debugtalk import hashlib import random import string def gen_random_string(str_len): '''生成指定长度的随 ...

  5. ubuntu如何删除刚添加的源?

    答: sudo add-apt-repository -r <source_url> 如: sudo add-apt-repository -r ppa:linaro-maintainer ...

  6. 【批处理】ren命令_批量重命名文件

    [ren命令] 说明:ren是“rename(重命名)”的简写: 命令:REN [Drive:][path] <old filename> <new filename> 解释: ...

  7. LC 975. Odd Even Jump

    You are given an integer array A.  From some starting index, you can make a series of jumps.  The (1 ...

  8. python之scrapy爬取jingdong招聘信息到mysql数据库

    1.创建工程 scrapy startproject jd 2.创建项目 scrapy genspider jingdong 3.安装pymysql pip install pymysql 4.set ...

  9. Fluent Ribbon Control Suite和AvalonDock 控件库

    Fluent Ribbon Control Suite 是一个Ribbon控件,可以用来创建Office 2010 样式的用户界面,支持MVVM,最近快要更新了,将会有Office 2013 样式的主 ...

  10. 搭建Kubernetes容器集群管理系统

    1.Kubernetes 概述 Kubernetes 是 Google 开源的容器集群管理系统,基于 Docker 构建一个容器的调度服务,提供资源调度.均衡容灾.服务注册.劢态扩缩容等功能套件. 基 ...