【问题标题】:How can i read from a specific process it's memory for a specific value change the value and write it back to the process memory?如何从特定进程读取特定值的内存更改值并将其写回进程内存?
【发布时间】:2013-10-05 02:28:16
【问题描述】:

我正在使用: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。

  1. 扫描内存中的进程名。
  2. 使用特定值(例如 5)定位进程内存中的所有位置/地址。
  3. 转到进程/程序更改那里的东西,所以现在值 5 是 4。
  4. 从内存中的最后一个位置再次扫描值 4,找到值 4 的所有位置/地址。
  5. 值 4 的所有结果的更改将每个内存地址的值更改为值例如 8。
  6. 写回这个值 4 的结果的确切位置,现在它的值已更改为 8。

因此,如果我现在查看我的流程,它现在将显示值 8。

我该怎么做?

【问题讨论】:

    标签: c# winforms memory


    【解决方案1】:

    我曾经也在做类似的事情并试图弄清楚如何做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)

    找出其他东西,如果有,请分享。

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 2016-06-25
      相关资源
      最近更新 更多