C#操作内存读写方法的主要实现代码

时间:2024-01-12 15:00:44

C#操作内存读写方法是什么呢?让我们来看看具体的实例实现:

  1. using System.Runtime.InteropServices;
  2. using System.Text;
  3. publicclass Function
  4. {
  5. //C#操作内存读写方法
  6. publicstaticbyte PtrToByte( int Ptr )
  7. {
  8. byte b = Marshal.ReadByte( ( IntPtr ) Ptr );
  9. return b;
  10. }
  11. publicstaticchar PtrToChar( int Ptr )
  12. {
  13. byte b = Marshal.ReadByte( ( IntPtr ) Ptr );
  14. return ( char ) b;
  15. }
  16. publicstaticshort PtrToShort( int Ptr )
  17. {
  18. short b = Marshal.ReadInt16( ( IntPtr ) Ptr );
  19. return b;
  20. }
  21. //C#操作内存读写方法
  22. publicstaticushort PtrToUShort( int Ptr )
  23. {
  24. ushort b = ( ushort ) Marshal.ReadInt16( ( IntPtr ) Ptr );
  25. return b;
  26. }
  27. publicstaticint PtrToInt( int Ptr )
  28. {
  29. int b = Marshal.ReadInt32( ( IntPtr ) Ptr );
  30. return b;
  31. }
  32. publicstaticuint PtrToUInt( int Ptr )
  33. {
  34. uint b = ( uint ) Marshal.ReadInt32( ( IntPtr ) Ptr );
  35. return b;
  36. }
  37. publicstaticlong PtrToLong( int Ptr )
  38. {
  39. long b = Marshal.ReadInt64( ( IntPtr ) Ptr );
  40. return b;
  41. }  //C#操作内存读写方法
  42. publicstaticulong PtrToULong( int Ptr )
  43. {
  44. ulong b = ( ulong ) Marshal.ReadInt64( ( IntPtr ) Ptr );
  45. return b;
  46. }
  47. // Convert an ip address stored an address to equivalent string value
  48. publicstaticstring GetPtrToIpAddr(int intPtr, int varlen)
  49. {
  50. int i = 0;
  51. StringBuilder sb = new StringBuilder(0,varlen*4);
  52. byte[] byx = newbyte[varlen];
  53. // ip address cann't have zero value C#操作内存读写方法
  54. // ip address cann't have zero length C#操作内存读写方法
  55. if( ( intPtr == 0 ) || ( varlen == 0 ) ) return"";
  56. Marshal.Copy( ( IntPtr ) intPtr , byx , 0 , varlen );
  57. for( i = 0; i < varlen - 1; i ++ )
  58. {
  59. sb.Append(byx[i]);
  60. sb.Append('.');
  61. }
  62. sb.Append(byx[varlen - 1]);
  63. return sb.ToString();
  64. }
  65. }

BOOL ReadProcessMemory( HANDLE hProcess, PVOID pvAddressRemote, PVOID pvBufferLocal, DWORD dwSize, PDWORD pdwNumBytesRead);

参数
hProcess为远程进程的句柄
pvAddressRemote用于指明远程进程中的地址
pvBufferLocal是本地进程中的内存地址
dwSize是需要传送的字节数
pdwNumBytesRead和pdwNumBytesWritten用于指明实际传送的字节数.当函数返回时,可以查看这两个参数的值.

ReadProcessMemory读出数据,权限要大一些。下面这个打开进程的方式具备了查询 读和写的权限

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, ProcessId)

然后就要结合上面的程序来搜索了。只有当内存是处于被占用状态时才去读取其中的内容,而忽略空闲状态的内存。程序我就不在这儿写了,和上面那段差不多。只是把dwTotalCommit = dwTotalCommit + mi.RegionSize换成了读取内存以及搜索这一块内存的函数而已。

1.通过FindWindow读取窗体的句柄

2.通过GetWindowThreadProcessId读取查找窗体句柄进程的PID值

3.用OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, ProcessId)打开查到PID值的进程. 此打开具备 读取,写入,查询的权限

4.ReadProcessMemory读出指定的内存地址数据

//C#读取内存例子 
  2
  3 using System;
  4 using System.Collections.Generic;
  5 using System.Text;
  6 using System.Runtime.InteropServices;
  7 using System.Diagnostics;
  8 using System.Management;
  9
10 publicclass key
11     {
12         constuint PROCESS_ALL_ACCESS =0x001F0FFF;
13         constuint KEYEVENTF_EXTENDEDKEY =0x1;
14         constuint KEYEVENTF_KEYUP =0x2;
15         privatereadonlyint MOUSEEVENTF_LEFTDOWN =0x2;
16         privatereadonlyint MOUSEEVENTF_LEFTUP =0x4;
17         constuint KBC_KEY_CMD =0x64;
18         constuint KBC_KEY_DATA =0x60;
19         //得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄
20         [DllImport("user32.dll", CharSet = CharSet.Auto)]
21         publicstaticextern IntPtr FindWindow(
22         string lpClassName, // pointer to class name
23         string lpWindowName // pointer to window name
24         );
25         [DllImport("user32.dll")]
26         privatestaticexternint GetWindowThreadProcessId(IntPtr id, int pid);
27
28         [DllImport("kernel32.dll")]
29         privatestaticexternvoid CloseHandle
30         (
31         uint hObject //Handle to object
32         );
33         //读取进程内存的函数
34         [DllImport("kernel32.dll")]
35         staticexternbool ReadProcessMemory(uint hProcess, IntPtr lpBaseAddress,
36         IntPtr lpBuffer, uint nSize, refuint lpNumberOfBytesRead);
37         //得到目标进程句柄的函数
38         [DllImport("kernel32.dll")]
39         publicstaticexternuint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
40         //鼠标事件声明
41         [DllImport("user32.dll")]
42         staticexternbool setcursorpos(int x, int y);
43         [DllImport("user32.dll")]
44         staticexternvoid mouse_event(mouseeventflag flags, int dx, int dy, uint data, UIntPtr extrainfo);
45         //键盘事件声明
46         [DllImport("user32.dll")]
47         staticexternbyte MapVirtualKey(byte wCode, int wMap);
48         [DllImport("user32.dll")]
49         staticexternshort GetKeyState(int nVirtKey);
50         [DllImport("user32.dll")]
51         staticexternvoid keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
52         //键盘事件声明winio
53         [DllImport("winio.dll")]
54         publicstaticexternbool InitializeWinIo();
55         [DllImport("winio.dll")]
56         publicstaticexternbool GetPortVal(IntPtr wPortAddr, outint pdwPortVal, byte bSize);
57         [DllImport("winio.dll")]
58         publicstaticexternbool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
59         [DllImport("winio.dll")]
60         publicstaticexternbyte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
61         [DllImport("winio.dll")]
62         publicstaticexternbool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
63         [DllImport("winio.dll")]
64         publicstaticexternbool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
65         [DllImport("winio.dll")]
66         publicstaticexternbool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
67         [DllImport("winio.dll")]
68         publicstaticexternvoid ShutdownWinIo();
69
70
71
72
73         ///<summary>
74         /// 获取进程pid
75         ///</summary>
76         ///<param name="name"></param>
77         ///<returns></returns>
78         privateint pid(String name)
79         {
80             try
81             {
82                 ObjectQuery oQuery =new ObjectQuery("select * from Win32_Process where Name='"+ name +"'");
83                 ManagementObjectSearcher oSearcher =new ManagementObjectSearcher(oQuery);
84                 ManagementObjectCollection oReturnCollection = oSearcher.Get();
85
86                 string pid ="";
87                 string cmdLine;
88                 StringBuilder sb =new StringBuilder();
89                 foreach (ManagementObject oReturn in oReturnCollection)
90                 {
91                     pid = oReturn.GetPropertyValue("ProcessId").ToString();
92                     //cmdLine = (string)oReturn.GetPropertyvalue("CommandLine");
93
94                     //string pattern = "-ap \"(.*)\"";
95                     //Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
96                     // Match match = regex.Match(cmdLine);
97                     //string appPoolName = match.Groups[1].ToString();
98                     //sb.AppendFormat("W3WP.exe PID: {0} AppPoolId:{1}\r\n", pid, appPoolName);
99                 }
100                 return Convert.ToInt32(pid);
101             }
102             catch (Exception ss)
103             { return0; }
104
105         }
106         privateint pid(IntPtr id)
107         {
108             int pid =0;
109             pid = GetWindowThreadProcessId(id, pid);
110             return260;
111         }
112         ///<summary>
113         /// 读取内存值
114         ///</summary>
115         ///<param name="name">进程id</param>
116         ///<param name="dizhi">读取的内存地址</param>
117         ///<returns></returns>
118         //public String getread(String QEC,String EC, IntPtr dizhi, uint size)
119         //{
120         // Byte bt = new Byte();
121         // IntPtr id=FindWindow(QEC, EC);
122         // uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid(id));
123         // IntPtr fanhui = new IntPtr();
124         // String gg = null;
125         // if (hProcess == 0)
126         // {
127         //// gg = ReadProcessMemory(hProcess, dizhi, fanhui, size, 0);
128         //// CloseHandle(hProcess);
129
130
131         // }
132         // return gg;
133         //}
134         public String getread(String jincheng, String EC, IntPtr dizhi, uint size)
135         {
136             byte[] vBuffer =newbyte[4];
137             IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 得到缓冲区的地址
138
139             uint vNumberOfBytesRead =0;
140             Byte bt =new Byte();
141             //IntPtr id = FindWindow(QEC, EC);
142             uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid(jincheng));
143             //pid(0);
144             IntPtr fanhui =new IntPtr();
145             String gg =null;
146             //if (hProcess == 0)
147             //{
148             if (ReadProcessMemory(hProcess, dizhi, vBytesAddress, (uint)vBuffer.Length, ref hProcess))
149             {
150                 CloseHandle(hProcess);
151             }
152             else
153             {
154                 CloseHandle(hProcess);
155             }
156
157             // }
158             int vInt = Marshal.ReadInt32(vBytesAddress);
159             return vInt.ToString();
160         }
161         ///<summary>
162         /// 获取键盘状态
163         ///</summary>
164         ///<param name="Key"></param>
165         ///<returns></returns>
166         publicbool GetState(VirtualKeys Key)
167         {
168             return (GetKeyState((int)Key) ==1);
169         }
170         ///<summary>
171         /// 发送键盘事件
172         ///</summary>
173         ///<returns></returns>
174         publicvoid Send(VirtualKeys Key, bool State)
175         {
176             if (State != GetState(Key))
177             {
178                 byte a = MapVirtualKey((byte)Key, 0);
179                 keybd_event((byte)Key, MapVirtualKey((byte)Key, 0), 0, 0);
180                 System.Threading.Thread.Sleep(1000);
181                 keybd_event((byte)Key, MapVirtualKey((byte)Key, 0), KEYEVENTF_KEYUP, 0);
182             }
183         }
184         ///<summary>
185         /// 初始化winio
186         ///</summary>
187         publicvoid sendwinio()
188         {
189             if (InitializeWinIo())
190             {
191                 KBCWait4IBE();
192             }
193         }
194         privatevoid KBCWait4IBE() //等待键盘缓冲区为空
195         {
196             //int[] dwVal = new int[] { 0 };
197             int dwVal =0;
198             do
199             {
200                 //这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中
201                 //GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度
202                 bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
203             }
204             while ((dwVal &0x2) >0);
205         }
206         ///<summary>
207         /// 模拟键盘标按下
208         ///</summary>
209         ///<param name="vKeyCoad"></param>
210         publicvoid MykeyDown(int vKeyCoad)
211         {
212             int btScancode =0;
213
214             btScancode = MapVirtualKey((byte)vKeyCoad, 0);
215             // btScancode = vKeyCoad;
216
217             KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
218             SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
219             //SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
220             KBCWait4IBE();
221             SetPortVal(KBC_KEY_DATA, (IntPtr)0xe2, 1);// '写入按键信息,按下键
222             KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
223             SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
224             //SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
225             KBCWait4IBE();
226             SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按键信息,按下键
227
228         }
229         ///<summary>
230         /// 模拟键盘弹出
231         ///</summary>
232         ///<param name="vKeyCoad"></param>
233         publicvoid MykeyUp(int vKeyCoad)
234         {
235             int btScancode =0;
236             btScancode = MapVirtualKey((byte)vKeyCoad, 0);
237             //btScancode = vKeyCoad;
238
239             KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
240             SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
241             KBCWait4IBE();
242             SetPortVal(KBC_KEY_DATA, (IntPtr)0xe0, 1);// '写入按键信息,释放键
243             KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
244             SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
245             KBCWait4IBE();
246             SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按键信息,释放键
247         }
248         ///<summary>
249         /// 模拟鼠标按下
250         ///</summary>
251         ///<param name="vKeyCoad"></param>
252         publicvoid MyMouseDown(int vKeyCoad)
253         {
254             int btScancode =0;
255
256             btScancode = MapVirtualKey((byte)vKeyCoad, 0);
257             //btScancode = vKeyCoad;
258
259             KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
260             SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1);// '发送键盘写入命令
261             //SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
262             KBCWait4IBE();
263             SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode |0x80), 1);// '写入按键信息,按下键
264
265         }
266         ///<summary>
267         /// 模拟鼠标弹出
268         ///</summary>
269         ///<param name="vKeyCoad"></param>
270         publicvoid MyMouseUp(int vKeyCoad)
271         {
272             int btScancode =0;
273             btScancode = MapVirtualKey((byte)vKeyCoad, 0);
274             // btScancode = vKeyCoad;
275
276             KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
277             SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1); //'发送键盘写入命令
278             KBCWait4IBE();
279             SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode |0x80), 1);// '写入按键信息,释放键
280         }
281         ///<summary>
282         /// 发送鼠标事件
283         ///</summary>
284         ///<returns></returns>
285         publicvoid SendMouse()
286         {
287
288         }
289         ///<summary>
290         /// 鼠标动作枚举
291         ///</summary>
292         publicenum mouseeventflag : uint
293         {
294             move =0x0001,
295             leftdown =0x0002,
296             leftup =0x0004,
297             rightdown =0x0008,
298             rightup =0x0010,
299             middledown =0x0020,
300             middleup =0x0040,
301             xdown =0x0080,
302             xup =0x0100,
303             wheel =0x0800,
304             virtualdesk =0x4000,
305             absolute =0x8000
306         }
307         ///<summary>
308         /// 键盘动作枚举
309         ///</summary>
310         publicenum VirtualKeys : byte
311         {
312             //VK_NUMLOCK = 0x90, //数字锁定键
313             //VK_SCROLL = 0x91, //滚动锁定
314             //VK_CAPITAL = 0x14, //大小写锁定
315             //VK_A = 62, //键盘A
316             VK_LBUTTON =1, //鼠标左键
317             VK_RBUTTON =2,  //鼠标右键
318             VK_CANCEL =3,    //Ctrl+Break(通常不需要处理)
319             VK_MBUTTON =4,   //鼠标中键
320             VK_BACK =8,     //Backspace
321             VK_TAB =9,     //Tab
322             VK_CLEAR =12,    //Num Lock关闭时的数字键盘5
323             VK_RETURN =13,   //Enter(或者另一个)
324             VK_SHIFT =16,    //Shift(或者另一个)
325             VK_CONTROL =17,   //Ctrl(或者另一个)
326             VK_MENU =18,    //Alt(或者另一个)
327             VK_PAUSE =19,    //Pause
328             VK_CAPITAL =20,   //Caps Lock
329             VK_ESCAPE =27,   //Esc
330             VK_SPACE =32,    //Spacebar
331             VK_PRIOR =33,    //Page Up
332             VK_NEXT =34,    //Page Down
333             VK_END =35,     //End
334             VK_HOME =36,    //Home
335             VK_LEFT =37,    //左箭头
336             VK_UP =38,     //上箭头
337             VK_RIGHT =39,    //右箭头
338             VK_DOWN =40,    //下箭头
339             VK_SELECT =41,   //可选
340             VK_PRINT =42,    //可选
341             VK_EXECUTE =43,   //可选
342             VK_SNAPSHOT =44,  //Print Screen
343             VK_INSERT =45,   //Insert
344             VK_DELETE =46,   //Delete
345             VK_HELP =47,   //可选
346             VK_NUM0 =48, //0
347             VK_NUM1 =49, //1
348             VK_NUM2 =50, //2
349             VK_NUM3 =51, //3
350             VK_NUM4 =52, //4
351             VK_NUM5 =53, //5
352             VK_NUM6 =54, //6
353             VK_NUM7 =55, //7
354             VK_NUM8 =56, //8
355             VK_NUM9 =57, //9
356             VK_A =65, //A
357             VK_B =66, //B
358             VK_C =67, //C
359             VK_D =68, //D
360             VK_E =69, //E
361             VK_F =70, //F
362             VK_G =71, //G
363             VK_H =72, //H
364             VK_I =73, //I
365             VK_J =74, //J
366             VK_K =75, //K
367             VK_L =76, //L
368             VK_M =77, //M
369             VK_N =78, //N
370             VK_O =79, //O
371             VK_P =80, //P
372             VK_Q =81, //Q
373             VK_R =82, //R
374             VK_S =83, //S
375             VK_T =84, //T
376             VK_U =85, //U
377             VK_V =86, //V
378             VK_W =87, //W
379             VK_X =88, //X
380             VK_Y =89, //Y
381             VK_Z =90, //Z
382             VK_NUMPAD0 =96, //0
383             VK_NUMPAD1 =97, //1
384             VK_NUMPAD2 =98, //2
385             VK_NUMPAD3 =99, //3
386             VK_NUMPAD4 =100, //4
387             VK_NUMPAD5 =101, //5
388             VK_NUMPAD6 =102, //6
389             VK_NUMPAD7 =103, //7
390             VK_NUMPAD8 =104, //8
391             VK_NUMPAD9 =105, //9
392             VK_NULTIPLY =106,  //数字键盘上的*
393             VK_ADD =107,    //数字键盘上的+
394             VK_SEPARATOR =108, //可选
395             VK_SUBTRACT =109,  //数字键盘上的-
396             VK_DECIMAL =110,  //数字键盘上的.
397             VK_DIVIDE =111,   //数字键盘上的/
398             VK_F1 =112,
399             VK_F2 =113,
400             VK_F3 =114,
401             VK_F4 =115,
402             VK_F5 =116,
403             VK_F6 =117,
404             VK_F7 =118,
405             VK_F8 =119,
406             VK_F9 =120,
407             VK_F10 =121,
408             VK_F11 =122,
409             VK_F12 =123,
410             VK_NUMLOCK =144,  //Num Lock
411             VK_SCROLL =145   // Scroll Lock
412         }
413     }
414
415 注:using System.Management需要添加System.Management的引用,否则编译容易出错