C#使用WinAPI读写进程内存

您所在的位置:网站首页 跨进程读内存 C#使用WinAPI读写进程内存

C#使用WinAPI读写进程内存

2024-02-03 01:52| 来源: 网络整理| 查看: 265

0x01

使用kernel32.dll中的ReadProcessMemory和WriteProcessMemory内存函数可以完成对程序内存的读写。

我在写读内存整数型、写内存整数型和读内存小数型三个方法的时候测试可以正确读写进程地址的内存,但是我在写内存小数型的时候遇到了问题,记录一下。

0x02

ReadProcessMemory函数原型如下:

BOOL ReadProcessMemory( HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead );

hProcess 远程进程句柄,指被读取者进程句柄

lpBaseAddress 远程进程中内存地址,指具体从何处读取

lpBuffer 本地进程中内存地址,指函数将读取的内容写入此处

nSize 要传送的字节数,指要写入多少

lpNumberOfBytesRead 实际传送的字节数,指函数返回时报告实际写入多少

WriteProcessMemory函数原型如下:

BOOL WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten ); hProcess 由OpenProcess返回的进程句柄,如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程 lpBaseAddress 要写的内存首地址 lpBuffer 指向要写的数据的指针 nSize 要写入的字节数

0x03

测试类

using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace C_Sharp读写内存 { public abstract class test { [DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")] public static extern int _MemoryReadByteSet(int hProcess, int lpBaseAddress, byte[] lpBuffer, int nSize, int lpNumberOfBytesRead); [DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")] public static extern int _MemoryReadInt32(int hProcess, int lpBaseAddress, ref int lpBuffer, int nSize, int lpNumberOfBytesRead); [DllImport("kernel32.dll", EntryPoint = "WriteProcessMemory")] public static extern int _MemoryWriteByteSet(int hProcess, int lpBaseAddress, byte[] lpBuffer, int nSize, int lpNumberOfBytesWritten); [DllImport("kernel32.dll", EntryPoint = "WriteProcessMemory")] public static extern int _MemoryWriteInt32(int hProcess, int lpBaseAddress, ref int lpBuffer, int nSize, int lpNumberOfBytesWritten); [DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess")] public static extern int GetCurrentProcess(); [DllImport("kernel32.dll", EntryPoint = "OpenProcess")] public static extern int OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId); [DllImport("kernel32.dll", EntryPoint = "CloseHandle")] public static extern int CloseHandle(int hObject); [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] public static extern int _CopyMemory_ByteSet_Float(ref float item, ref byte source, int length); const int PROCESS_POWER_MAX = 2035711; /// /// 读内存整数型 /// /// 进程ID /// 0x地址 /// 0失败 public static int ReadMemoryInt32(int pID, int bAddress) { int num = 0; int handle = GetProcessHandle(pID); int num3 = test._MemoryReadInt32(handle, bAddress, ref num, 4, 0); test.CloseHandle(handle); if (num3==0) { return 0; } else { return num; } } /// /// 写内存整数型 /// /// 进程ID /// 0x地址 /// 写入值 /// false失败 true成功 public static bool WriteMemoryInt32(int pID, int bAddress,int value) { int handle = GetProcessHandle(pID); int num2 = test._MemoryWriteInt32(handle, bAddress, ref value, 4, 0); test.CloseHandle(handle); return num2 != 0; } /// /// 读内存小数型 /// /// 进程ID /// 0x地址 /// 0失败 public static float ReadMemoryFloat(int pID, int bAddress) { //byte[] array = test.GetVoidByteSet(4); byte[] array = new byte[4];//不取空字节集也可以正确转换成单精度小数型 int handle = GetProcessHandle(pID); int temp = test._MemoryReadByteSet(handle, bAddress, array, 4, 0); if (temp == 0) { return 0f; } else { return test.GetFloatFromByteSet(array, 0); } } /// /// 写内存小数型 /// /// 进程ID /// 0x地址 /// 写入数据 /// false失败 public static bool WriteMemoryFloat(int pID, int bAddress, float value) { //byte[] byteSet = test.GetByteSet(value); byte[] byteSet = BitConverter.GetBytes(value);//https://msdn.microsoft.com/en-us/library/yhwsaf3w //byte[] byteSet = Encoding.GetEncoding("gb2312").GetBytes(value.ToString()); return test.WriteMemoryByteSet(pID, bAddress, byteSet, 0); } /// /// 写内存字节集 /// /// 进程ID /// 0x地址 /// 字节数据 /// 写入长度 0代表字节数据的长度 /// false失败 private static bool WriteMemoryByteSet(int pID, int bAddress, byte[] value, int length=0) { int handle = test.GetProcessHandle(pID); int nSize = (length == 0) ? value.Length : length; int tmp = test._MemoryWriteByteSet(handle, bAddress, value, nSize, 0);//byte[]属于引用类型 引用类型不用ref也是以传址方式进行运算 //test.CloseHandle(pID); return tmp != 0; } /// /// 取空白字节集 /// /// /// public static byte[] GetVoidByteSet(int num) { if (num


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3