• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Dict.CN 在線詞典, 英語學習, 在線翻譯

            學海苦作舟,書山勤為徑

            留下點回憶

            常用鏈接

            統計

            積分與排名

            Denoise

            English study

            Web技術

            數據壓縮

            一些連接

            最新評論

            進程間通訊-WriteProcessMemory和ReadProcessMemory

            最近在寫個程序的時候需要在進程間通訊,具體需求是這樣。

            1.?????? 主要有兩個進程:一個進程作為被請求進程,我們稱為 SERVER 進程;另一個進程是請求進程,稱為 CLIENG 進程。

            2.?????? SERVER 進程提供一些服務,其完成計算功能;而 CLIENT 進程需要在它執行完計算之后將結果取會。

            ?

            由于計算結果可能是一個結構,也可能是一個復雜的數據,所以通過消息來在進程傳遞信息是有限的。另一方面一般是單方向的通訊,實際上這里的需求有一個雙向性,看下圖:

            ProcessComm.JPG


            這里兩個進程都可以有自己的窗口,因此實際上我們可以通過消息來通知對方。但仔細一想,請求服務通過windows消息是沒有問題的,通知結果通過消息是不妥當的,實際上我們需要在請求服務完以后立即得到執行結果,而使用windows消息可能有時間上的問題,而且同步非常麻煩。

            想要的結果是在 CLIENT 請求服務以后立即得到返回結果,但我們可以改變一下思路就容易多了:結果不是有 SERVER 返回,而由 CLIENG 自己去獲取。這樣,我們可以在請求消息的時候使用 SendMessage 來發送這個請求。這是必須的, SendMessage 發送消息是同步的方式,必須等到消息處理完畢之后才返回,而這正是我們想要的結果。那么 CLIENT 怎么樣才能獲得 SERVER 進程的結果來。

            我們知道, WINDOWS 下每個進程都有自己的地址空間,一般情況下一個進程訪問你一個進程的地址是不正確的,最簡單的是提示該地址無效,程序崩潰。當然還是有很多中方式來讀取對方進程的地址空間上的數據。

            1.? 可以做一個 DLL ,利用注入 DLL 的方式,來將該 DLL 注入到遠程進程的地址空間上,然后通過 DLL API 來讀取。這個方式有點麻煩,還必須寫一個 DLL ,還要注入 DLL

            2.? 使用 WriteProcessMemory ReadProcessMemory 來讀寫遠程進程的內存。這種方式相對比較簡單,其有一個參數遠程進程的 HANDLE 指示你需要讀寫哪個進程的內存。當然,使用這兩個函數是需要遠程進程的地址空間的,這個地址是通過 VirtualAllocEx 來分配的,其通過 VirtualFreeEx 來釋放。這兩個 API 也有一個進程句柄參數。

            有人問,為什么不使用 WM_COPYDATA 來傳遞大塊數據?好,該消息是可以傳遞大塊數據,但我們的應用中需要消息的雙向,所以這里使用 WM_COPYDATA 是不合適的。

            ?

            下面我們看一下第 2 種方法的具體步驟:

            1.? 找到對方進程的窗口。

            2.? 找到他的進程 ID

            3.? 使用 PROCESS_VM_OPERATION| PROCESS_VM_WRITE|PROCESS_VM_READ 標志來打開該進程,得到該繼承的 HANDLE

            4.? 使用 VirtualAllocEx 來在該進程上分配適當大小的內存,得到一個地址,這個地址是遠程進程的,通過不同的方式來修改該地址上的值是無效的。

            5.? 如果需要傳遞一些參數到遠程進程,我們可以在該內存上寫一些內容,通過 WriteProcessMemory 來完成

            6.? 使用 SendMessage 來發送請求服務消息,同時將上面分配的內存地址作為參數傳遞給遠程進程。

            7.? 遠程進程得到指定消息后處理該消息,取得參數,計算結果,將結果寫到指定的地址。由于這個地址是遠程進程自己的地址空間,其操作這塊內存的方法沒有什么特別之處。

            8.? SendMessage 消息返回, CLIENT 知道后,從上面的內存地址中讀取返回結果;這里必須使用 ReadProcessMemory 來讀取。好了,整個過程結束。

            9.? 調用 VritualFreeEx 將上面的內存釋放。

            這里需要強調兩點:

            1.? 打開進程的時候必須設置對虛擬內存可操作、可寫、可讀,如果只是可寫,那么 ReadProcessMemory 將讀取不正確。

            2.? 必須釋放該內存。

            ?

            下面是部分程序:

            CLIENT 程序:

            #define ??? WM_COMPAREIMAGE WM_USER +100

            ?

            void CTestCompareDlg::OnBnClickedButton1()

            {

            ??? HANDLE hProcess = NULL;

            ??? DWORD dwProcessId = 0;

            ??? HWND hServerWnd = ::FindWindow(NULL,"CompareServer");

            ??? if(hServerWnd == NULL)

            ??? {

            ?????? //Need create the process

            ?????? return ;

            ??? }

            ??? ::GetWindowThreadProcessId(hServerWnd,&dwProcessId);

            ??? hProcess = OpenProcess(PROCESS_VM_OPERATION|

            ?????? PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,dwProcessId);

            ??? if(hProcess == NULL) return ;

            ?

            ??? MyInfo * pMyInfo = NULL;

            ?

            ??? pMyInfo = (MyInfo *)VirtualAllocEx(hProcess,NULL,

            ?????? sizeof(MyInfo),MEM_COMMIT,PAGE_READWRITE);

            ?

            ??? if(pMyInfo == NULL) return ;

            ??? MyInfo myInfo;

            ??? myInfo.blue = 20.01;

            ??? myInfo.red = 3333;

            ?

            ??? WriteProcessMemory(hProcess,pMyInfo,&myInfo,sizeof(MyInfo),NULL);

            ?

            ??? ::SendMessage(hServerWnd,WM_COMPAREIMAGE,sizeof(MyInfo),(LPARAM)pMyInfo);

            ???

            ??? DWORD dwRead = 0;

            ??? MyInfo myInfo2;

            ??? BOOL bRet = ::ReadProcessMemory(hProcess,pMyInfo,&myInfo2,sizeof(MyInfo),&dwRead);

            ?

            ??? dwRead = GetLastError();

            ??? m_log.Format("red =%.2f,blue=%.2f",myInfo2.blue,myInfo2.red);

            ??? TRACE(m_log);

            ??? VirtualFreeEx(hProcess,pMyInfo,0,MEM_RELEASE);

            ??? UpdateData(FALSE);

            }

            ?

            SERVER 程序:

            LRESULT??? CMyWindow::OnCompareImage(HWND hWnd,WPARAM wParam,LPARAM lParam)

            {

            ??? if(wParam <sizeof(MyInfo)) return -1;

            ??? MyInfo * pMyInfo = (MyInfo *)lParam;

            ?

            ??? sprintf(m_strLog,"client:red=%.2f,blue=%.2f",pMyInfo->red,pMyInfo->blue);

            ??? ::TextOut(GetDC(hWnd),0,50,m_strLog,strlen(m_strLog));

            ??? pMyInfo->blue = 1.0;

            ??? pMyInfo->red = 2.0;

            ??? return 0;

            }

            源碼下載:CompareServer.zip

            posted on 2006-04-20 21:54 笨笨 閱讀(9548) 評論(6)  編輯 收藏 引用

            評論

            # re: 進程間通訊-WriteProcessMemory和ReadProcessMemory 2006-04-21 09:11 小明

            雖然是可行的,更好的方法是使用Pipe

            //example from msdn
            while (1)
            {
            // Read client requests from the pipe.
            fSuccess = ReadFile(
            hPipe, // handle to pipe
            chRequest, // buffer to receive data
            BUFSIZE*sizeof(TCHAR), // size of buffer
            &cbBytesRead, // number of bytes read
            NULL); // not overlapped I/O

            if (! fSuccess || cbBytesRead == 0)
            break;
            GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);

            // Write the reply to the pipe.
            fSuccess = WriteFile(
            hPipe, // handle to pipe
            chReply, // buffer to write from
            cbReplyBytes, // number of bytes to write
            &cbWritten, // number of bytes written
            NULL); // not overlapped I/O

            if (! fSuccess || cbReplyBytes != cbWritten) break;
            }
              回復  更多評論   

            # re: 進程間通訊-WriteProcessMemory和ReadProcessMemory 2006-04-21 09:20 christanxw

            內存映射文件才是進程間共享的根本!  回復  更多評論   

            # re: 進程間通訊-WriteProcessMemory和ReadProcessMemory 2007-01-26 14:00 yesry

            厲害  回復  更多評論   

            # re: 進程間通訊-WriteProcessMemory和ReadProcessMemory 2008-10-17 09:59 coolicelee

            可以在DLL終定義一個Share段,大家通過調用DLL訪問,比如在代碼中定義
            #pragma data_seg("SharedSCT")
            DWORD g_dwValue = 0;
            #pragma data_seg()
            然后在def中定義
            SECTIONS
            SharedSCT Read Write Shared  回復  更多評論   

            # re: 進程間通訊-WriteProcessMemory和ReadProcessMemory 2009-04-01 16:41 loskiller

            請問,創建出來的pMyInfo 要如何釋放?  回復  更多評論   

            # re: 進程間通訊-WriteProcessMemory和ReadProcessMemory 2010-08-15 21:33 fifi

            WM_COPYDATA 也可實現雙向的,需要變通一下!  回復  更多評論   

            伊人久久综合精品无码AV专区| 久久久噜噜噜久久| 久久精品国产精品亚洲精品| 伊人久久综合精品无码AV专区| 久久人人爽人人爽人人片AV不 | 亚洲欧美伊人久久综合一区二区| 亚洲精品乱码久久久久久蜜桃图片 | 久久综合久久自在自线精品自| 国产精品美女久久久久网| 欧美色综合久久久久久| 国产精品禁18久久久夂久| 亚洲国产成人久久精品99 | 久久天天日天天操综合伊人av| 伊人久久大香线蕉综合Av| 国产精品女同一区二区久久| 日韩精品久久无码中文字幕| 久久国产免费| 中文字幕成人精品久久不卡| 亚洲精品无码成人片久久| 久久精品国产精品亚洲艾草网美妙| 久久天天躁狠狠躁夜夜96流白浆| 一本大道久久东京热无码AV | 亚洲国产天堂久久久久久| 国产高潮国产高潮久久久| 精品伊人久久大线蕉色首页| 久久嫩草影院免费看夜色| 国产精品美女久久久| 久久国产亚洲精品无码| 无码伊人66久久大杳蕉网站谷歌 | AV狠狠色丁香婷婷综合久久| 亚洲欧美日韩久久精品第一区| 久久久久亚洲av毛片大| 久久无码人妻精品一区二区三区| 欧美一区二区精品久久| 国产午夜福利精品久久2021| 国产亚洲精久久久久久无码| 69SEX久久精品国产麻豆| 国产精品久久久久aaaa| 欧美一区二区精品久久| 精品久久久久久国产免费了| 久久久精品波多野结衣|