C#操作内存读写方法是什么呢?让我们来看看具体的实例实现:
- using System.Runtime.InteropServices;
- using System.Text;
- publicclass Function
- {
- //C#操作内存读写方法
- publicstaticbyte PtrToByte( int Ptr )
- {
- byte b = Marshal.ReadByte( ( IntPtr ) Ptr );
- return b;
- }
- publicstaticchar PtrToChar( int Ptr )
- {
- byte b = Marshal.ReadByte( ( IntPtr ) Ptr );
- return ( char ) b;
- }
- publicstaticshort PtrToShort( int Ptr )
- {
- short b = Marshal.ReadInt16( ( IntPtr ) Ptr );
- return b;
- }
- //C#操作内存读写方法
- publicstaticushort PtrToUShort( int Ptr )
- {
- ushort b = ( ushort ) Marshal.ReadInt16( ( IntPtr ) Ptr );
- return b;
- }
- publicstaticint PtrToInt( int Ptr )
- {
- int b = Marshal.ReadInt32( ( IntPtr ) Ptr );
- return b;
- }
- publicstaticuint PtrToUInt( int Ptr )
- {
- uint b = ( uint ) Marshal.ReadInt32( ( IntPtr ) Ptr );
- return b;
- }
- publicstaticlong PtrToLong( int Ptr )
- {
- long b = Marshal.ReadInt64( ( IntPtr ) Ptr );
- return b;
- } //C#操作内存读写方法
- publicstaticulong PtrToULong( int Ptr )
- {
- ulong b = ( ulong ) Marshal.ReadInt64( ( IntPtr ) Ptr );
- return b;
- }
- // Convert an ip address stored an address to equivalent string value
- publicstaticstring GetPtrToIpAddr(int intPtr, int varlen)
- {
- int i = 0;
- StringBuilder sb = new StringBuilder(0,varlen*4);
- byte[] byx = newbyte[varlen];
- // ip address cann't have zero value C#操作内存读写方法
- // ip address cann't have zero length C#操作内存读写方法
- if( ( intPtr == 0 ) || ( varlen == 0 ) ) return"";
- Marshal.Copy( ( IntPtr ) intPtr , byx , 0 , varlen );
- for( i = 0; i < varlen - 1; i ++ )
- {
- sb.Append(byx[i]);
- sb.Append('.');
- }
- sb.Append(byx[varlen - 1]);
- return sb.ToString();
- }
- }
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的引用,否则编译容易出错