C#ReadProcessMemory

时间:2018-12-31 14:05:36

标签: c# memory readprocessmemory

我基本上是想弄清楚如何在过程中搜索值而不给出确切的偏移量。该过程可以是任何东西(记事本,iexplorer,msword等)。只是寻找一个进程的第一个和最后一个内存地址之间的值,而不是给出一个特定的偏移量,这是我必须从另一个应用程序中找到的,例如 ollydbg

这就是我所拥有的

const int PROCESS_WM_READ = 0x0010;

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(int hProcess,
Int64 lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);

public static string search = "somestring";

static void Main(string[] args)
{
    Process process = Process.GetProcessById(15728);
    IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);

    int bytesRead = 0;
    byte[] buffer = new byte[16]; 

    ReadProcessMemory((int)processHandle, 0x20BC4ADE4C8, buffer, buffer.Length, ref bytesRead);

    Console.WriteLine(Encoding.Unicode.GetString(buffer) +
          " (" + bytesRead.ToString() + "bytes)");
    if (Encoding.Unicode.GetString(buffer).Contains(somestring))
        Console.WriteLine("Match");
    else
        Console.WriteLine("Didint Match");
    Console.ReadLine();
}

1 个答案:

答案 0 :(得分:0)

您无法避免根据需要将地址传递到ReadProcessMemory,而且我认为没有其他API可以让您读取进程的内存。

因此,您要做的就是传递基址。您可以自己计算它,而不必获取基地址。 This question can help

接下来,您将需要找到进程的内存大小,并将其传递给nSize参数。但是...这可能不是一个好主意,因为

  1. 您必须确定该值是什么(我不确定如何;您可以通过对可能的最大值进行二进制搜索并找到不会强制{{1 }}返回ReadProcessMemory或使用性能计数器或其他某种机制)。

  2. 处理内存限制,必须为缓冲区分配大量内存。

因此,无需读取所有内存,而是使用较小的缓冲区大小多次调用false。该算法可能类似于

ReadProcessMemory

如果以上循环未找到您的字符串,则您仍未完成,因为字符串可能跨越了两个缓冲区之间的边界。要解决此问题,请创建另一个循环,以扫描从while not an error read into a buffer, scanning it for your string if found return true; bump the offset boundary offset - string size的每个边界,如果找到则返回true。