当前位置: 移动技术网 > IT编程>开发语言>c# > 分享C#操作内存读写方法的主要实现代码

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
复制代码 代码如下:using system.runtime.interopservices; using system.text; publicclass functio

复制代码 代码如下:

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的引用,否则编译容易出错

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网