欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-17 09:37:34
复制代码 代码如下: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的引用,否则编译容易出错