Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# I r/w如何通过扫描和替换字节数组来处理内存?_C# - Fatal编程技术网

C# I r/w如何通过扫描和替换字节数组来处理内存?

C# I r/w如何通过扫描和替换字节数组来处理内存?,c#,C#,我很抱歉,这个问题可能看起来非常愚蠢。在过去的三个月里,我一直在周期性地试图找出如何通过字节数组读取/写入另一个进程内存,或运行应用程序的进程内存。据我所知,C#没有读/写内存进程的能力,因此它必须通过P/Invoke调用win32 API DLL [DllImport("kernel32.dll")] static extern Int32 ReadProcessMemory(IntPtr OpenedHandle, IntPtr lpBaseAddress, byte[] lpBuffe

我很抱歉,这个问题可能看起来非常愚蠢。在过去的三个月里,我一直在周期性地试图找出如何通过字节数组读取/写入另一个进程内存,或运行应用程序的进程内存。据我所知,C#没有读/写内存进程的能力,因此它必须通过P/Invoke调用win32 API DLL

[DllImport("kernel32.dll")]  
static extern Int32 ReadProcessMemory(IntPtr OpenedHandle, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
我的目标是像在作弊引擎中一样简单高效地搜索和替换几个字节数组。我通常会有两个变量,或者是分开的,或者是在一个数组中:

private string original = "d0 d0 66 ae 0b 68 b9 0a";
private string replace = "d0 02 02 24 00 68 b9 0a";
ReadProcessMemory
调用中,我不理解为什么需要
lpBaseAddress
OpenHandle
我通常会放置应用程序的字符串,因为我直接编辑它
lpBuffer
我假设是要读/写的实际字节数组。
size
我不太确定,而
lpNumberOfBytesRead
是要读取的数字吗?对
WriteProcessMemory
的交互提问

[DllImport("kernel32.dll")]
private static unsafe extern Boolean WriteProcessMemory(IntPtr hProcess, uint lpBaseAddress, byte[] lpBuffer, int nSize, void* lpNumberOfBytesWritten);
我想引用我读过的一些教程,但它们似乎已经不存在或被取代了。再一次,我为提出这样一个看似业余的问题而真诚道歉,然而S.O.是我最后的选择

据我所知,C#没有 读/写内存的能力 进程,因此它必须调用win32 API 通过P/Invoke调用DLL

[DllImport("kernel32.dll")]  
static extern Int32 ReadProcessMemory(IntPtr OpenedHandle, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
正确,并且您已经找到了正确的Win32 API

我通常会有两个VAR 单独或在一个数组中:

private string original = "d0 d0 66 ae 0b 68 b9 0a";
private string replace = "d0 02 02 24 00 68 b9 0a";
对于
ReadProcessMemory
WriteProcessMemory
,您将不使用字符串,而是使用实际的字节数组(
byte[]
),如您列出的p/Invoke函数签名所示。您的UI或命令行工具可以接受字符串,但需要将它们转换为字节数组

如果您还没有,您应该阅读和的MSDN文档。它们很好地描述了每个参数的期望值、发生的情况以及返回的内容

在ReadProcessMemory调用中,我不是 理解lpBaseAddress为什么是 必要的。我想要的那个把手 通常将 申请,因为我直接 编辑它

首先,
OpenHandle
参数需要一个进程的句柄,而不是文件名,我想您指的是文件名。您可以使用Win32 API获得正在运行的进程的句柄(可以找到P/Invoke签名)。要在进程中读取和写入内存,您至少需要
process\u VM\u read
process\u VM\u write
访问

我假设lpBuffer是 要读/写的实际字节数组。 我不太确定的尺码,以及 lpNumberOfBytesRead就是这个数字 阅读?相互提问 写进程内存也是如此

对于
ReadProcessMemory
lpBaseAddress
指定要从目标进程的内存中读取的位置
lpBuffer
用目标进程的内存内容填充<代码>大小指定要读取的字节数
lpNumberOfBytesRead
是一个输出参数,告诉您作为操作的一部分实际读取了多少字节。在成功的情况下,这应该与指定的缓冲区的
大小相匹配

考虑到这一点,您应该能够了解
WriteProcessMemory
的所有参数的作用


更重要的是,如何实现您正在尝试做的事情:您正在尝试执行搜索和替换操作。搜索部分将是最困难的。我可以想到两种主要方法:

  • 您可以对进程的内存进行完整扫描(从地址0到2/3GB限制(对于32位进程))以查找字节。这是最慢但最简单的方法

  • 使用堆信息,可以将扫描限制为已知的已分配地址。这是一种更快但更复杂的方法。由于您是在Windows上运行的,因此目标进程可能将使用Windows堆进行内存管理。Windows提供了一个API,用于遍历进程中分配的堆(和对象)。不幸的是,这需要堆的句柄,/方法只返回调用进程堆的句柄(它们不适用于远程进程)。因此,如果需要远程进程的堆信息,则需要向远程进程中注入一个线程来为您收集这些信息(即使用)。一旦你有了有效的堆地址,你就可以从搜索和替换应用程序中扫描这些地址


  • 非常感谢你的帮助,克里斯。我再试试看。