C#操作内存读写方法是什么呢?让我们来看看具体的实例实现:
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读出指定的内存地址数据
1 //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 public class key
11 {
12 const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
13 const uint KEYEVENTF_EXTENDEDKEY = 0x1;
14 const uint KEYEVENTF_KEYUP = 0x2;
15 private readonly int MOUSEEVENTF_LEFTDOWN = 0x2;
16 private readonly int MOUSEEVENTF_LEFTUP = 0x4;
17 const uint KBC_KEY_CMD = 0x64;
18 const uint KBC_KEY_DATA = 0x60;
19 //得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄
20 [DllImport("user32.dll", CharSet = CharSet.Auto)]
21 public static extern IntPtr FindWindow(
22 string lpClassName, // pointer to class name
23 string lpWindowName // pointer to window name
24 );
25 [DllImport("user32.dll")]
26 private static extern int GetWindowThreadProcessId(IntPtr id, int pid);
27
28 [DllImport("kernel32.dll")]
29 private static extern void CloseHandle
30 (
31 uint hObject //Handle to object
32 );
33 //读取进程内存的函数
34 [DllImport("kernel32.dll")]
35 static extern bool ReadProcessMemory(uint hProcess, IntPtr lpBaseAddress,
36 IntPtr lpBuffer, uint nSize, ref uint lpNumberOfBytesRead);
37 //得到目标进程句柄的函数
38 [DllImport("kernel32.dll")]
39 public static extern uint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
40 //鼠标事件声明
41 [DllImport("user32.dll")]
42 static extern bool setcursorpos(int x, int y);
43 [DllImport("user32.dll")]
44 static extern void mouse_event(mouseeventflag flags, int dx, int dy, uint data, UIntPtr extrainfo);
45 //键盘事件声明
46 [DllImport("user32.dll")]
47 static extern byte MapVirtualKey(byte wCode, int wMap);
48 [DllImport("user32.dll")]
49 static extern short GetKeyState(int nVirtKey);
50 [DllImport("user32.dll")]
51 static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
52 //键盘事件声明winio
53 [DllImport("winio.dll")]
54 public static extern bool InitializeWinIo();
55 [DllImport("winio.dll")]
56 public static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, byte bSize);
57 [DllImport("winio.dll")]
58 public static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
59 [DllImport("winio.dll")]
60 public static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
61 [DllImport("winio.dll")]
62 public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
63 [DllImport("winio.dll")]
64 public static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
65 [DllImport("winio.dll")]
66 public static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
67 [DllImport("winio.dll")]
68 public static extern void ShutdownWinIo();
69
70
71
72
73 ///
74 /// 获取进程pid
75 ///
76 ///
77 ///
78 private int 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 { return 0; }
104
105 }
106 private int pid(IntPtr id)
107 {
108 int pid = 0;
109 pid = GetWindowThreadProcessId(id, pid);
110 return 260;
111 }
112 ///
113 /// 读取内存值
114 ///
115 /// 进程id
116 /// 读取的内存地址
117 ///
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 = new byte[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 ///
162 /// 获取键盘状态
163 ///
164 ///
165 ///
166 public bool GetState(VirtualKeys Key)
167 {
168 return (GetKeyState((int)Key) == 1);
169 }
170 ///
171 /// 发送键盘事件
172 ///
173 ///
174 public void 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 ///
185 /// 初始化winio
186 ///
187 public void sendwinio()
188 {
189 if (InitializeWinIo())
190 {
191 KBCWait4IBE();
192 }
193 }
194 private void 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 ///
207 /// 模拟键盘标按下
208 ///
209 ///
210 public void 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 ///
230 /// 模拟键盘弹出
231 ///
232 ///
233 public void 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 ///
249 /// 模拟鼠标按下
250 ///
251 ///
252 public void 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 ///
267 /// 模拟鼠标弹出
268 ///
269 ///
270 public void 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 ///
282 /// 发送鼠标事件
283 ///
284 ///
285 public void SendMouse()
286 {
287
288 }
289 ///
290 /// 鼠标动作枚举
291 ///
292 public enum 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 ///
308 /// 键盘动作枚举
309 ///
310 public enum 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的引用,否则编译容易出错
http://www.lob.cn/sl/system/7350.shtml