分享C#操作内存读写方法的主要实现代码
发布时间:2022-10-08 08:08:44
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#读取内存例子
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Management;
publicclass key
{
constuint PROCESS_ALL_ACCESS =0x001F0FFF;
constuint KEYEVENTF_EXTENDEDKEY =0x1;
constuint KEYEVENTF_KEYUP =0x2;
privatereadonlyint MOUSEEVENTF_LEFTDOWN =0x2;
privatereadonlyint MOUSEEVENTF_LEFTUP =0x4;
constuint KBC_KEY_CMD =0x64;
constuint KBC_KEY_DATA =0x60;
//得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄
[DllImport("user32.dll", CharSet = CharSet.Auto)]
publicstaticextern IntPtr FindWindow(
string lpClassName, // pointer to class name
string lpWindowName // pointer to window name
);
[DllImport("user32.dll")]
privatestaticexternint GetWindowThreadProcessId(IntPtr id, int pid);
[DllImport("kernel32.dll")]
privatestaticexternvoid CloseHandle
(
uint hObject //Handle to object
);
//读取进程内存的函数
[DllImport("kernel32.dll")]
staticexternbool ReadProcessMemory(uint hProcess, IntPtr lpBaseAddress,
IntPtr lpBuffer, uint nSize, refuint lpNumberOfBytesRead);
//得到目标进程句柄的函数
[DllImport("kernel32.dll")]
publicstaticexternuint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
//鼠标事件声明
[DllImport("user32.dll")]
staticexternbool setcursorpos(int x, int y);
[DllImport("user32.dll")]
staticexternvoid mouse_event(mouseeventflag flags, int dx, int dy, uint data, UIntPtr extrainfo);
//键盘事件声明
[DllImport("user32.dll")]
staticexternbyte MapVirtualKey(byte wCode, int wMap);
[DllImport("user32.dll")]
staticexternshort GetKeyState(int nVirtKey);
[DllImport("user32.dll")]
staticexternvoid keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
//键盘事件声明winio
[DllImport("winio.dll")]
publicstaticexternbool InitializeWinIo();
[DllImport("winio.dll")]
publicstaticexternbool GetPortVal(IntPtr wPortAddr, outint pdwPortVal, byte bSize);
[DllImport("winio.dll")]
publicstaticexternbool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
[DllImport("winio.dll")]
publicstaticexternbyte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
[DllImport("winio.dll")]
publicstaticexternbool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
[DllImport("winio.dll")]
publicstaticexternbool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
[DllImport("winio.dll")]
publicstaticexternbool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
[DllImport("winio.dll")]
publicstaticexternvoid ShutdownWinIo();
///<summary>
/// 获取进程pid
///</summary>
///<param name="name"></param>
///<returns></returns>
privateint pid(String name)
{
try
{
ObjectQuery oQuery =new ObjectQuery("select * from Win32_Process where Name='"+ name +"'");
ManagementObjectSearcher oSearcher =new ManagementObjectSearcher(oQuery);
ManagementObjectCollection oReturnCollection = oSearcher.Get();
string pid ="";
string cmdLine;
StringBuilder sb =new StringBuilder();
foreach (ManagementObject oReturn in oReturnCollection)
{
pid = oReturn.GetPropertyValue("ProcessId").ToString();
//cmdLine = (string)oReturn.GetPropertyvalue("CommandLine");
//string pattern = "-ap \"(.*)\"";
//Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
// Match match = regex.Match(cmdLine);
//string appPoolName = match.Groups[1].ToString();
//sb.AppendFormat("W3WP.exe PID: {0} AppPoolId:{1}\r\n", pid, appPoolName);
}
return Convert.ToInt32(pid);
}
catch (Exception ss)
{ return0; }
}
privateint pid(IntPtr id)
{
int pid =0;
pid = GetWindowThreadProcessId(id, pid);
return260;
}
///<summary>
/// 读取内存值
///</summary>
///<param name="name">进程id</param>
///<param name="dizhi">读取的内存地址</param>
///<returns></returns>
//public String getread(String QEC,String EC, IntPtr dizhi, uint size)
//{
// Byte bt = new Byte();
// IntPtr id=FindWindow(QEC, EC);
// uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid(id));
// IntPtr fanhui = new IntPtr();
// String gg = null;
// if (hProcess == 0)
// {
//// gg = ReadProcessMemory(hProcess, dizhi, fanhui, size, 0);
//// CloseHandle(hProcess);
// }
// return gg;
//}
public String getread(String jincheng, String EC, IntPtr dizhi, uint size)
{
byte[] vBuffer =newbyte[4];
IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 得到缓冲区的地址
uint vNumberOfBytesRead =0;
Byte bt =new Byte();
//IntPtr id = FindWindow(QEC, EC);
uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid(jincheng));
//pid(0);
IntPtr fanhui =new IntPtr();
String gg =null;
//if (hProcess == 0)
//{
if (ReadProcessMemory(hProcess, dizhi, vBytesAddress, (uint)vBuffer.Length, ref hProcess))
{
CloseHandle(hProcess);
}
else
{
CloseHandle(hProcess);
}
// }
int vInt = Marshal.ReadInt32(vBytesAddress);
return vInt.ToString();
}
///<summary>
/// 获取键盘状态
///</summary>
///<param name="Key"></param>
///<returns></returns>
publicbool GetState(VirtualKeys Key)
{
return (GetKeyState((int)Key) ==1);
}
///<summary>
/// 发送键盘事件
///</summary>
///<returns></returns>
publicvoid Send(VirtualKeys Key, bool State)
{
if (State != GetState(Key))
{
byte a = MapVirtualKey((byte)Key, 0);
keybd_event((byte)Key, MapVirtualKey((byte)Key, 0), 0, 0);
System.Threading.Thread.Sleep(1000);
keybd_event((byte)Key, MapVirtualKey((byte)Key, 0), KEYEVENTF_KEYUP, 0);
}
}
///<summary>
/// 初始化winio
///</summary>
publicvoid sendwinio()
{
if (InitializeWinIo())
{
KBCWait4IBE();
}
}
privatevoid KBCWait4IBE() //等待键盘缓冲区为空
{
//int[] dwVal = new int[] { 0 };
int dwVal =0;
do
{
//这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中
//GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度
bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
}
while ((dwVal &0x2) >0);
}
///<summary>
/// 模拟键盘标按下
///</summary>
///<param name="vKeyCoad"></param>
publicvoid MykeyDown(int vKeyCoad)
{
int btScancode =0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
// btScancode = vKeyCoad;
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
//SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0xe2, 1);// '写入按键信息,按下键
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
//SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按键信息,按下键
}
///<summary>
/// 模拟键盘弹出
///</summary>
///<param name="vKeyCoad"></param>
publicvoid MykeyUp(int vKeyCoad)
{
int btScancode =0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
//btScancode = vKeyCoad;
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0xe0, 1);// '写入按键信息,释放键
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按键信息,释放键
}
///<summary>
/// 模拟鼠标按下
///</summary>
///<param name="vKeyCoad"></param>
publicvoid MyMouseDown(int vKeyCoad)
{
int btScancode =0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
//btScancode = vKeyCoad;
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1);// '发送键盘写入命令
//SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode |0x80), 1);// '写入按键信息,按下键
}
///<summary>
/// 模拟鼠标弹出
///</summary>
///<param name="vKeyCoad"></param>
publicvoid MyMouseUp(int vKeyCoad)
{
int btScancode =0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
// btScancode = vKeyCoad;
KBCWait4IBE(); // '发送数据前应该先等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode |0x80), 1);// '写入按键信息,释放键
}
///<summary>
/// 发送鼠标事件
///</summary>
///<returns></returns>
publicvoid SendMouse()
{
}
///<summary>
/// 鼠标动作枚举
///</summary>
publicenum mouseeventflag : uint
{
move =0x0001,
leftdown =0x0002,
leftup =0x0004,
rightdown =0x0008,
rightup =0x0010,
middledown =0x0020,
middleup =0x0040,
xdown =0x0080,
xup =0x0100,
wheel =0x0800,
virtualdesk =0x4000,
absolute =0x8000
}
///<summary>
/// 键盘动作枚举
///</summary>
publicenum VirtualKeys : byte
{
//VK_NUMLOCK = 0x90, //数字锁定键
//VK_SCROLL = 0x91, //滚动锁定
//VK_CAPITAL = 0x14, //大小写锁定
//VK_A = 62, //键盘A
VK_LBUTTON =1, //鼠标左键
VK_RBUTTON =2, //鼠标右键
VK_CANCEL =3, //Ctrl+Break(通常不需要处理)
VK_MBUTTON =4, //鼠标中键
VK_BACK =8, //Backspace
VK_TAB =9, //Tab
VK_CLEAR =12, //Num Lock关闭时的数字键盘5
VK_RETURN =13,//Enter(或者另一个)
VK_SHIFT =16, //Shift(或者另一个)
VK_CONTROL =17, //Ctrl(或者另一个)
VK_MENU =18,//Alt(或者另一个)
VK_PAUSE =19, //Pause
VK_CAPITAL =20, //Caps Lock
VK_ESCAPE =27,//Esc
VK_SPACE =32, //Spacebar
VK_PRIOR =33, //Page Up
VK_NEXT =34,//Page Down
VK_END =35, //End
VK_HOME =36,//Home
VK_LEFT =37, //左箭头
VK_UP =38, //上箭头
VK_RIGHT =39, //右箭头
VK_DOWN =40, //下箭头
VK_SELECT =41, //可选
VK_PRINT =42, //可选
VK_EXECUTE =43, //可选
VK_SNAPSHOT =44,//Print Screen
VK_INSERT =45,//Insert
VK_DELETE =46, //Delete
VK_HELP =47, //可选
VK_NUM0 =48, //0
VK_NUM1 =49, //1
VK_NUM2 =50, //2
VK_NUM3 =51, //3
VK_NUM4 =52, //4
VK_NUM5 =53, //5
VK_NUM6 =54, //6
VK_NUM7 =55, //7
VK_NUM8 =56, //8
VK_NUM9 =57, //9
VK_A =65, //A
VK_B =66, //B
VK_C =67, //C
VK_D =68, //D
VK_E =69, //E
VK_F =70, //F
VK_G =71, //G
VK_H =72, //H
VK_I =73, //I
VK_J =74, //J
VK_K =75, //K
VK_L =76, //L
VK_M =77, //M
VK_N =78, //N
VK_O =79, //O
VK_P =80, //P
VK_Q =81, //Q
VK_R =82, //R
VK_S =83, //S
VK_T =84, //T
VK_U =85, //U
VK_V =86, //V
VK_W =87, //W
VK_X =88, //X
VK_Y =89, //Y
VK_Z =90, //Z
VK_NUMPAD0 =96, //0
VK_NUMPAD1 =97, //1
VK_NUMPAD2 =98, //2
VK_NUMPAD3 =99, //3
VK_NUMPAD4 =100, //4
VK_NUMPAD5 =101, //5
VK_NUMPAD6 =102, //6
VK_NUMPAD7 =103, //7
VK_NUMPAD8 =104, //8
VK_NUMPAD9 =105, //9
VK_NULTIPLY =106, //数字键盘上的*
VK_ADD =107,//数字键盘上的+
VK_SEPARATOR =108,//可选
VK_SUBTRACT =109, //数字键盘上的-
VK_DECIMAL =110,//数字键盘上的.
VK_DIVIDE =111, //数字键盘上的/
VK_F1 =112,
VK_F2 =113,
VK_F3 =114,
VK_F4 =115,
VK_F5 =116,
VK_F6 =117,
VK_F7 =118,
VK_F8 =119,
VK_F9 =120,
VK_F10 =121,
VK_F11 =122,
VK_F12 =123,
VK_NUMLOCK =144,//Num Lock
VK_SCROLL =145 // Scroll Lock
}
}
注:using System.Management需要添加System.Management的引用,否则编译容易出错
猜你喜欢
- 公司在使用定时任务的时候,使用的是spring scheduled。代码如下:@EnableSchedulingpublic class T
- 单行文本的输入存在严重的缺陷,也不适合实际的运用,本节通过一个无功能的记事本来介绍可以进行多行输入的JTextArea:JTextArea(
- 前言Basic编码是标准的BASE64编码,用于处理常规的需求:输出的内容不添加换行符,而且输出的内容由字母加数字组成。最近做了个Web模版
- 总之是用jdbc 的游标移动package com.sp.person.sql.util; import java.sql.Connecti
- C# 和 java 比较:java 中使用的是接口。C# 使用委托机制,可以用时 + 运算符进行注册,直接多播。而 java 中是一般是使用
- 1. 字段取别名,和属性名保持一致映射文件<mapper namespace="com.atguigu.mybatis.ma
- 本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下先是效果图:主菜单:游戏:设置:错误处理:代码:#include
- IntelliJ IDEA是广受Java开发者喜爱的工具,其商业版的价格十分昂贵,如下图:现在有机会免费获取IntelliJ IDEA的正版
- 1、为什么使用Spring提供的JDBC的封装?因为Spring提供了完整的模板类以及基类可以简化开发,我们只需写少量的代码即可。2、实例讲
- 摘要:这个问题算是老生常谈了,我也是一段时间没弄过了,所以感觉有些忘了,就记录一下。一、后端通过shiro在session中存储数据://
- 摘要:用spring-boot开发RESTful API非常的方便,在生产环境中,对发布的API增加授权保护是非常必要的。现在我们来看如何利
- 本文实例讲述了Java之JFrame输出Helloworld的方法。分享给大家供大家参考。具体如下:JAVA的GUI程序的基本思路是以JFr
- Redisson是架设在redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。充分的利用了Redis键值数
- 这篇文章主要介绍了Spring整合MyBatis图示过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 前言Groovy 是一种基于 JVM 的动态语言,与 Java 语言紧密集成,可以很方便地在 Java 项目中使用。Groovy 有着简洁的
- 一、项目要求实现一个通讯录通讯录可以用来存储100个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址提供方法:添加联系人信息删除指定
- 前言Date 类Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。构造方法
- Struts2简介Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts
- 详解HDFS多文件Join操作的实例最近在做HDFS文件处理之时,遇到了多文件Join操作,其中包括:All Join以及常用的Left J
- 1.查找数据库中表的列名<pre name="code" class="html">St