如何从特定进程中读取特定值的内存更改值并将其写回进程内存
本文关键字:进程 内存 写回 读取 | 更新日期: 2023-09-27 18:33:56
我正在使用:ProcessMemoryReaderLib.dll将其引用到我的项目中。这是 form1 代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using ProcessMemoryReaderLib;
using System.IO;
namespace ProcessMemory
{
public partial class Form1 : Form
{
ProcessMemoryReader pReader;
int store;
IntPtr score_addr;
byte[] write;
public Form1()
{
InitializeComponent();
for (int i = 0 ; i < 2; i++)
{
store = 0;
pReader = new ProcessMemoryReader(); //create a new writer - reader
Process[] hProcessSnap; //create an array containing all running processes
Process hProcess = null;
hProcessSnap = Process.GetProcesses(); //Load all processes in the array
// The address
score_addr = (IntPtr)00000005;//(IntPtr)0x1007800;
write = new byte[4];
write = BitConverter.GetBytes(0);
for (int n = 0; n < hProcessSnap.Length; n++)
{
// ProcessName is not Unique, there could be many matching processes
// and this loop will only return the last one.
if (hProcessSnap[n].ProcessName == "FlashPlayerPlugin_11_8_800_168")
hProcess = hProcessSnap[n];
}
pReader.ReadProcess = hProcess;
pReader.OpenProcess();
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
pReader.WriteProcessMemory(score_addr, write, out store);
}
}
}
我添加了自己的 for 循环。一般来说,这个想法是在内存中的特定过程中找到一个特定的值。例如:score_addr = (IntPtr(00000005;
00000005 = 5 十六进制
现在,我在具有此值的特定进程内存中的内存中找到了许多位置。现在我要去流程更改内部的一些内容,做一些更改,该过程是一个程序,所以我更改了我想要的值,如果它是 5 现在是 4
所以现在我将在进程内存中搜索值 4。所以现在是 5,现在是 4,结果应该很窄,例如,在进程的内存中只有 3-4 个位置会是 4。
现在我想把这 3-4 个地址将每个地址的值更改为 8。所以现在如果我在我的程序(进程(中查看,我会看到值已更改为 8。
- 扫描进程名称的内存。
- 使用示例 5 的特定值查找进程内存中的所有位置/地址。
- 转到那里的过程/程序更改,所以现在值 5 是 4。
- 从内存中最后一个位置再次扫描值 4,找到值 4 的所有位置/地址。
- 值 4 的所有结果中的更改会将每个内存地址的值更改为示例 8 的值。
- 写回此结果值 4 的确切位置,现在的值更改为 8。
因此,如果我现在查看我的流程,它现在将显示值 8。
我该怎么做?
我曾经也在做类似的事情,并试图弄清楚如何做2. Search for a value
。我还没有成功,所以请注意答案不完整。
我使用以下方法访问内存(给定特定地址(。
public int GetInteger(int memoryAddress, uint bytes) {
int bytesRead;
byte[] memoryValue;
if(bytes == 1) {
#region single byte
byte[] temp = pReader.ReadProcessMemory((IntPtr)memoryAddress, bytes, out bytesRead);
memoryValue = new byte[4];
memoryValue[0] = temp[0];
memoryValue[1] = memoryValue[2] = memoryValue[3] = 0;
// little endian
#endregion
} else if(bytes == 2) {
#region two bytes
byte[] temp = pReader.ReadProcessMemory((IntPtr)memoryAddress, bytes, out bytesRead);
memoryValue = new byte[4];
memoryValue[0] = temp[0];
memoryValue[1] = temp[1];
memoryValue[2] = memoryValue[3] = 0;
#endregion
} else if(bytes == 3) {
#region three bytes
byte[] temp = pReader.ReadProcessMemory((IntPtr)memoryAddress, bytes, out bytesRead);
memoryValue = new byte[4];
memoryValue[0] = temp[0];
memoryValue[1] = temp[1];
memoryValue[2] = temp[2];
memoryValue[3] = 0;
#endregion
} else if(bytes == 4) {
memoryValue = pReader.ReadProcessMemory((IntPtr)memoryAddress, bytes, out bytesRead);
} else {
// do more if you have to deal with values like eight-byte values.
}
int result = BitConverter.ToInt32(memoryValue, 0);
if(result < 0) {
throw new OverflowException(result + "(possible overflow)");
}
return result;
}
public string GetString(int memoryAddress, uint bytes) {
int bytesRead;
byte[] memoryValue = pReader.ReadProcessMemory((IntPtr)memoryAddress, bytes, out bytesRead);
Encoding encoding = Encoding.Default;
string result = encoding.GetString(memoryValue, 0, (int)bytes);
result = result.TrimEnd(''0');
return result;
}
public void SetInteger(int memoryAddress, int value, uint bytes) {
byte[] temp = new byte[bytes];
for(int i = 0; i < bytes; i++) {
temp[i] = 0;
}
byte[] byteValue = BitConverter.GetBytes(value);
pReader.WriteProcessMemory((IntPtr)memoryAddress, byteValue, bytes);
}
public void SetString(int memoryAddress, string value, uint bytes) {
byte[] byteValue = new byte[bytes];
for(int i = 0; i < bytes; i++) {
byteValue[i] = 0;
}
Encoding encoding = Encoding.Default;
byteValue = encoding.GetBytes(value);
pReader.WriteProcessMemory((IntPtr)memoryAddress, byteValue, bytes);
}
如果您知道要访问的所有地址,这应该就足够了。
我试图用这样的东西搜索一个值
// NEVER DO THAT.
List<int> candidates = new List<int>();
for(int i = 0; i < Int32.MaxValue; i++) {
//if you don't know the byte size of the searchee, it gets even worse. :s
//for(int bytes = 1; j < 4; j++)
if(GetInteger(i, bytes) == THE_VALUE_TO_SEARCH_FOR) {
candidates.Add(i);
}
}
然后我的电脑爆炸了。(否 =D(
找出其他内容,如果有的话,请分享。