如何在另一个进程的内存中搜索byte []数组,然后在byte []数组所在的位置获取地址?
我想将一个字节数组写入另一个进程的内存(WriteProcessMemory())。该调用的一个参数是uint Address.Well我想通过在进程中搜索一个字节数组来获取地址。 / p>
例如,我搜索{0xEB,0x20,0x68,0x21,0x27,0x65,??,0x21,0x64,0xA1}
我们假设这个数组只放在我想写内存的进程的内存中的一个位置。
要获取该地址,我必须搜索该字节数组。
是否可以在C#中完成?
编辑: 这适用于本机应用程序,而非.NET。没有必要低估我的问题,有C ++的组件可以做到这一点,我只想用C#来做。
感谢您的理解!
答案 0 :(得分:16)
是否可以在C#中完成? 在c#(或任何其他语言)中,一切皆有可能,你只需要弄清楚如何;
这里的硬编码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize,
out int lpNumberOfBytesRead
);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
static void Main(string[] args)
{
Process[] procs = Process.GetProcessesByName("explorer");
if (procs.Length <= 0) //proces not found
return; //can replace with exit nag(message)+exit;
IntPtr p = OpenProcess(0x10 | 0x20, true, procs[0].Id); //0x10-read 0x20-write
uint PTR = 0x0; //begin of memory
byte[] bit2search1 = {0xEB ,0x20,0x68,0x21,0x27,0x65}; //your bit array until ??
int k = 1; //numer of missing array (??)
byte[] bit2search2 = {0x21,0x64,0xA1};//your bit array after ??
byte[] buff = new byte[bit2search1.Length+1+bit2search2.Length]; //your array lenght;
int bytesReaded;
bool finded = false;
while (PTR != 0xFF000000) //end of memory // u can specify to read less if u know he does not fill it all
{
ReadProcessMemory(p, (IntPtr)PTR, buff, buff.Length, out bytesReaded);
if (SpecialByteCompare(buff, bit2search1,bit2search2,k))
{
//do your stuff
finded = true;
break;
}
PTR += 0x1;
}
if (!finded)
Console.WriteLine("sry no byte array found");
}
private static bool SpecialByteCompare(byte[] b1, byte[] b2, byte[] b3, int k) //readed memory, first byte array, second byte array, number of missing byte's
{
if (b1.Length != (b2.Length + k + b3.Length))
return false;
for (int i = 0; i < b2.Length; i++)
{
if (b1[i] != b2[i])
return false;
}
for (int i = 0; i < b3.Length; i++)
{
if (b1[b2.Length + k + i] != b3[i])
return false;
}
return true;
}
}
}
答案 1 :(得分:6)
我猜您可以使用ReadProcessMemory Windows API调用。甚至还有一个premade P/Invoke signature,所以你不必费心手工制作它。您翻阅整个过程的内存,在其中搜索您的模式,然后就完成了。
答案 2 :(得分:3)
您需要使用这些API:
[DllImport("Kernel32.Dll")]
public static extern uint VirtualQueryEx(IntPtr ProcessHandle, uint Address, ref MEMORY_BASIC_INFORMATION MemInfo, int MemInfoLength);
[DllImport("Kernel32.Dll")]
public static extern bool ReadProcessMemory(IntPtr ProcessHandle, uint Address, byte[] Buffer, uint Size, ref uint BytesRead);
[DllImport("Kernel32.Dll")]
public static extern bool WriteProcessMemory(IntPtr ProcessHandle, uint Address, byte[] Buffer, uint Size, ref uint BytesRead);
pinvoke.net是Windows API调用的绝佳资源。我为GTA编写了一个培训师:如果你想查看sourceforge上的code,可以使用这些电话的Vice City。代码并不漂亮,很久以前我只是把它放在一起,但是有一些辅助类来枚举进程的内存区域并搜索某些字节或字符串。
答案 3 :(得分:1)
这可以帮助您找到正确的方法:
private static int GetMemoryAddressOfString(byte[] searchedBytes, Process p)
{
//List<int> addrList = new List<int>();
int addr = 0;
int speed = 1024*64;
for (int j = 0x400000; j < 0x7FFFFFFF; j+= speed)
{
ManagedWinapi.ProcessMemoryChunk mem = new ProcessMemoryChunk(p, (IntPtr)j, speed + searchedBytes.Length);
byte[] bigMem = mem.Read();
for (int k = 0; k < bigMem.Length - searchedBytes.Length; k++)
{
bool found = true;
for (int l = 0; l < searchedBytes.Length; l++)
{
if(bigMem[k+l] != searchedBytes[l])
{
found = false;
break;
}
}
if(found)
{
addr = k+j;
break;
}
}
if (addr != 0)
{
//addrList.Add(addr);
//addr = 0;
break;
}
}
//return addrList;
return addr;
}
答案 4 :(得分:-1)
是否可以在C#中完成?
是。但非常努力。从本机应用程序来看很困难,因为没有阻抗与进程的非托管视图和它们需要使用的内存映射不匹配。
考虑:
建议: