分享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#读取内存例子
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的引用,否则编译容易出错