<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 元件/連接器 > WindowsCE跨進(jìn)程內(nèi)存注入原理

          WindowsCE跨進(jìn)程內(nèi)存注入原理

          ——
          作者: 時間:2007-02-28 來源:www.weste.net/ 收藏
          近日,由于程序設(shè)計需要,我對WincowsCE 的內(nèi)存布局進(jìn)行了研究,由于發(fā)現(xiàn)國內(nèi)在這方面的文檔資料較少,于是在研究告一段落之際,形成這篇示例文檔,以望拋磚引玉,得到別的高手的指正。

            一、程序?qū)崿F(xiàn)的先決條件

            由于windows系統(tǒng)的窗體消息總是投遞至一個特定進(jìn)程的指定窗體消息函數(shù)中。于是在本地進(jìn)程(自己的應(yīng)用程序)中取得屬于其它進(jìn)程的窗體的消息必須實現(xiàn)以下兩個部分:

            1、將需要掛接窗體的代碼放到目標(biāo)進(jìn)程的地址空間中去。

            2、執(zhí)行這一段代碼,并獲得目標(biāo)進(jìn)程窗體的消息。

            這兩步看起來很簡單,但在實現(xiàn)過程中就比較困難。由于Windows CE作為嵌入式移動設(shè)備操作系統(tǒng),與windows 98/2000/XP等桌面操作系統(tǒng)在內(nèi)核的設(shè)計理念以及API的支持上有極大的區(qū)別。這就直接導(dǎo)致了常規(guī)的桌面系統(tǒng)利用全局鼠標(biāo)鉤子注入/遠(yuǎn)程線程注入等方法在CE中完全得不通。不過可喜的是,微軟在開發(fā)工具中提供的remotexxx等遠(yuǎn)程調(diào)試程序使我清楚這個目標(biāo)并不是不可能的任務(wù),微軟既然可以做到,那就是說在CE的內(nèi)部一定有一套完整的跨進(jìn)程內(nèi)存訪問/代碼注入的機(jī)制。

            二、程序?qū)崿F(xiàn)的基本原理

            經(jīng)過兩天的google 搜索,在網(wǎng)上我發(fā)現(xiàn)了一個沒有在微軟文檔中聲明的有趣的API函數(shù):PerformCallBack4,傳說中這個函數(shù)可以在自己的應(yīng)用程序中執(zhí)行指定的進(jìn)程中的一個函數(shù),So Cool!這好象正是我所需要的東西。雖然網(wǎng)上也傳聞這個函數(shù)在wm5不受支持,其實經(jīng)過實踐這個傳聞只是謠傳而已!

            PerformCallBack4函數(shù)的定義:

          [DllImport("coredll.dll")]
          public static extern uint PerformCallBack4(ref CallBackInfo CallBackInfo,
          IntPtr ni_pVoid1,IntPtr ni_pVoid2,IntPtr ni_pVoid3);

            其中函數(shù)的參數(shù)CallBackInfo結(jié)構(gòu)定義:

          [StructLayout(LayoutKind.Sequential)]
          public struct CallBackInfo
          {
          public IntPtr hProc; //遠(yuǎn)程的目標(biāo)進(jìn)程
          public IntPtr pfn; //指向遠(yuǎn)程目標(biāo)進(jìn)程的函數(shù)地址的指針
          public IntPtr pvArg0; //函數(shù)的需要的第一個參數(shù)
          }//end struct

            而PerformCallback4的 ni_pVoid1、ni_pVoid2、ni_pVoid3為傳遞到遠(yuǎn)程目標(biāo)進(jìn)程執(zhí)行函數(shù)的其它三個參數(shù)。

            至于將代碼放到目標(biāo)進(jìn)程的內(nèi)存空間,我們可以利用CE設(shè)計上的一個特性:

            1、為了節(jié)約內(nèi)存使用,CE將所有程序調(diào)用的動態(tài)鏈接庫(DLL)都映射到同一個內(nèi)存地址中。

            2、CE的內(nèi)存布局中劃分有一個slot0的內(nèi)存位置,這個內(nèi)存位置是由正在執(zhí)行的進(jìn)程所占有的,每一個特定的時間片,只能有一個進(jìn)程可以占有這個內(nèi)存空間。在進(jìn)程要求執(zhí)行時,系統(tǒng)并不直接執(zhí)行進(jìn)程所處內(nèi)存位置的代碼,而是將該進(jìn)程的執(zhí)行代碼復(fù)制到slot0的內(nèi)存位置中產(chǎn)生一個副本執(zhí)行。也就是說進(jìn)程在執(zhí)行時內(nèi)存將會有進(jìn)程執(zhí)行代碼的兩個完全一樣的版本:存在于slot0中正在執(zhí)行的進(jìn)程代碼和進(jìn)程本身所處的內(nèi)存中的代碼。

            在這個特性下,可以得到結(jié)論:如果進(jìn)程A通過LoadLibrary函數(shù)裝載Test.dll,而進(jìn)程B也通過LoadLibrary函數(shù)裝載同一個Test.dll,這個Test.dll的所有函數(shù)在進(jìn)程A和進(jìn)程B中執(zhí)行時,相對于slot0中的進(jìn)程執(zhí)行代碼都會得到同一地址。

            3、在CE中,系統(tǒng)在內(nèi)存中劃分出33個slot,slot0保留給正在執(zhí)行的進(jìn)程,然后在進(jìn)程啟動時將所有的代碼放到除slot0以外的一個slot中(這就是臭名昭著的CE系統(tǒng)中內(nèi)存最多只能有不多于32個程序執(zhí)行的限制的來由)。在進(jìn)程執(zhí)行時,每個應(yīng)用程序的內(nèi)存訪問默認(rèn)只能訪問slot0內(nèi)存空間中的地址以及進(jìn)程所處的slot內(nèi)存空間的地址。 但為使設(shè)備驅(qū)動程序可以訪問到它們所需的其它應(yīng)用程序數(shù)據(jù),CE提供了兩個函數(shù)以打破這個限制,SetKmode和SetProcPermission,SetKmode函數(shù)告訴系統(tǒng),當(dāng)前運行的進(jìn)程是否需要在內(nèi)核模式中執(zhí)行;SetProcPermission函數(shù)可以接受一個位掩碼,每一位代碼一個slot的訪問控制,1代表可以訪問該slot的內(nèi)存內(nèi)容。0表示不能訪問該slot的內(nèi)存內(nèi)容。這兩個函數(shù)在msdn中有幫助文檔,可參閱msdn的文檔說明。



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();