• <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>
            隨筆 - 74, 文章 - 0, 評(píng)論 - 26, 引用 - 0
            數(shù)據(jù)加載中……

            【轉(zhuǎn)帖】Windwos CE 跨進(jìn)程內(nèi)存注入(PocketPC)

            近日,由于程序設(shè)計(jì)需要,我對(duì)WincowsCE 的內(nèi)存布局進(jìn)行了研究,由于發(fā)現(xiàn)國(guó)內(nèi)在這方面的文檔資料較少,于是在研究告一段落之際,形成這篇示例文檔,以望拋磚引玉,得到別的高手的指正。

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

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

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

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

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

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

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

              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ù)的需要的第一個(gè)參數(shù)
            }//end struct

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

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

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

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

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

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

              本文我們對(duì)實(shí)現(xiàn)的原理進(jìn)行了剖析,在下一篇文章中我們將以一個(gè)小示例程序演示實(shí)現(xiàn)的全過(guò)程。



            在文章《淺析Windows CE跨進(jìn)程內(nèi)存注入實(shí)現(xiàn)窗體消息掛接(上)》中,我們已經(jīng)得到了這個(gè)七巧板游戲所需要的所有小板塊,剩下的事就是等待我們按一定順序?qū)⒑线m的板塊放到合適的位置,本章我們開(kāi)始進(jìn)行真刀真槍的實(shí)戰(zhàn)演練。

            程序目標(biāo):捕獲explore窗體(也就是程序窗體的消息并輸出到WinProcInfo.txt中)

            程序的執(zhí)行步驟設(shè)計(jì)如下:

            1、編寫(xiě)一個(gè)窗體消息掛接DLL,這個(gè)DLL提供一個(gè),函數(shù)中利用setwindowlong函數(shù)將窗體的默認(rèn)消息處理過(guò)程改為這個(gè)掛接DLL中定義的一個(gè)窗體過(guò)程。

            2、在C#程序中利用findwindow等API函數(shù)獲得exlore類(lèi)窗體的句柄及窗體所屬的進(jìn)程,并使用performcallback4在目標(biāo)進(jìn)程空間中執(zhí)行coredll.dll的loadLibrary函數(shù)將我們寫(xiě)的掛接dll放到目標(biāo)進(jìn)程中。

            3、在C#程序中使用performcallback4在目標(biāo)進(jìn)程空間中執(zhí)行掛接DLL提供的導(dǎo)出接口函數(shù)實(shí)現(xiàn)跨進(jìn)程窗體消息截獲.

            一、程序的實(shí)現(xiàn)如下:

            在VS2005中建立一個(gè)智能設(shè)備的MFC DLL,命名為HookWindowsProcMFCDLL。

            在HookWindowsProcMFCDLL.cpp中進(jìn)行掛接DLL的核心編碼:

            LRESULT CALLBACK fnHookWindowProc(HWND hwnd,UINT msg,WPARAM wparam, LPARAM lparam);

            int __declspec(dllexport) WINAPI fnAttachWinProc(HWND ni_hAttatchWin,PVOID ,PVOID,PVOID);

            int __declspec(dllexport) WINAPI fnDetachWinMsgProc(HWND ni_hDetachWin);

            WNDPROC tpOldWindowProc;

            FILE *m_pDebugOutputFile;

            //將一個(gè)窗體消息處理掛接到net精簡(jiǎn)版MessageWindow對(duì)象上的代碼
            typedef struct
            {
             WNDPROC OldWinProc;//保留窗體原始消息處理過(guò)程的函數(shù)指針
             HWND WindowHandle;//保存net精簡(jiǎn)版中對(duì)應(yīng)的窗口掛接的MessageWindow對(duì)象的句柄
            } DEFUDT_AttachWinInfo; //end struct

            CMap<HWND,HWND,DEFUDT_AttachWinInfo,DEFUDT_AttachWinInfo> m_aAttachWinInfoMap;

            //對(duì)指定的窗口進(jìn)程進(jìn)行掛接
            int __declspec(dllexport) WINAPI fnAttachWinProc(HWND ni_hAttatchWin,
            PVOID ni_0,
            PVOID ni_1,
            PVOID ni_2 )
            {
             DEFUDT_AttachWinInfo tudtAttachWinInfo;
             m_pDebugOutputFile = fopen("\\Storage Card\\WinProcInfo.txt", "w");
             WNDPROC tpOldWindowProc=(WNDPROC)::SetWindowLong(ni_hAttatchWin, GWL_WNDPROC,(LONG) fnHookWindowProc );
             fprintf(m_pDebugOutputFile,"Attatch successfully! OldWindowProc: %08X\n",tpOldWindowProc);
             tudtAttachWinInfo.OldWinProc=tpOldWindowProc ;
             tudtAttachWinInfo.WindowHandle=ni_hAttatchWin;
             m_aAttachWinInfoMap.SetAt(ni_hAttatchWin,tudtAttachWinInfo);
             fclose(m_pDebugOutputFile);
             return 77;// (int)tpOldWindowProc ;
            }//end function

            int __declspec(dllexport) WINAPI fnDetachWinMsgProc(HWND ni_hDetachWin)
            {
             DEFUDT_AttachWinInfo tudtAttachWinInfo;
             WNDPROC tpOldWindowProc;

             //取得在ncf中消息接收窗口對(duì)應(yīng)的原始消息處理函數(shù)的函數(shù)指針
             m_aAttachWinInfoMap.Lookup(ni_hDetachWin,tudtAttachWinInfo) ;

             //將窗體的消息處理函數(shù)設(shè)為默認(rèn)的處理過(guò)程
             tpOldWindowProc =(WNDPROC) SetWindowLong(ni_hDetachWin,GWL_WNDPROC , (LONG)tudtAttachWinInfo.OldWinProc);

             //將掛接信息消息處理映謝類(lèi)中刪除
             m_aAttachWinInfoMap.RemoveKey(ni_hDetachWin);

             return (int)tpOldWindowProc ;

            }//end function


            LRESULT CALLBACK fnHookWindowProc(HWND hwnd,UINT msg,WPARAM wparam, LPARAM lparam)
            {
             DEFUDT_AttachWinInfo tudtAttachWinInfo;
             m_aAttachWinInfoMap.Lookup(hwnd,tudtAttachWinInfo) ;
             m_pDebugOutputFile = fopen("\\Storage Card\\WinProcInfo.txt", "a");
             if (m_pDebugOutputFile!=NULL)
             {
              fprintf(m_pDebugOutputFile,"HWND: %08X Msg: %08X Wparam %08X Lparam %08X \n",
            hwnd,msg,wparam,lparam);

             }//EHD IF

             fclose(m_pDebugOutputFile);
             //tudtAttachWin=maatt
             LRESULT tobjResult= ::CallWindowProc(tudtAttachWinInfo.OldWinProc ,hwnd,msg,wparam,lparam);
             return tobjResult;
            }//end function

            而在C#的主程序中,我們使用這個(gè)DLL掛接explore類(lèi)的程序窗體,以下給出掛接部分的代碼:

            int m_hTargetWindow;//要掛接的目標(biāo)窗體句柄
            IntPtr m_hTargetProcess;//目標(biāo)窗體所屬的進(jìn)程
            IntPtr m_hModule; //掛接DLL的句柄

            private void Form1_Load(object sender, EventArgs e)
            {
             IntPtr tpTemp = IntPtr.Zero, tpTempa = IntPtr.Zero;
             uint tuntApiRet;

             m_hTargetWindow = (int)clsCECoreAPI.FindWindow("Explore", null );//資源管理器 0x0013e800;

             //掛接指定的進(jìn)程窗體消息
             IntPtr thCurrentProcess = clsCECoreAPI.GetCurrentProcess();
             m_hTargetProcess=IntPtr.Zero ;// (IntPtr) (unchecked((int)0xedd84e4a));
             tuntApiRet= clsCECoreAPI.GetWindowThreadProcessId(new IntPtr(unchecked((int) m_hTargetWindow)),
            ref m_hTargetProcess);

             string tstrArgument;
             tstrArgument = "\\Program Files\\processinject\\HookWindowsProcMFCDLL.dll";// HookWindowsProcMFCDLL.dll";
             IntPtr tpArg0;

             int tintOriginalKMode = clsCECoreAPI.SetKMode(1);
             int tintOriginalProcPermission = (int)clsCECoreAPI.SetProcPermissions(0xffffffff);

             IntPtr tpFuncProc = clsCECoreAPI.GetProcAddress(clsCECoreAPI.GetModuleHandle("coredll.dll"), "LoadLibraryW");

             CallBackInfo tudtCALLBACKINFO;

             tpArg0 = clsCECoreAPI.MapPtrToProcess(tstrArgument, thCurrentProcess);

             tudtCALLBACKINFO.hProc = m_hTargetProcess;// Proc;
             tudtCALLBACKINFO.pfn = clsCECoreAPI.MapPtrToProcess(tpFuncProc, m_hTargetProcess);
             tudtCALLBACKINFO.pvArg0 = tpArg0;
             m_hModule =new IntPtr(unchecked(
            (int) clsCECoreAPI.PerformCallBack4(ref tudtCALLBACKINFO,IntPtr.Zero,IntPtr.Zero,IntPtr.Zero )));
             //clsCECoreAPI.Sleep(1000);

             IntPtr thModule = clsCECoreAPI.LoadLibrary("HookWindowsProcMFCDLL.dll");
             tpFuncProc = clsCECoreAPI.GetProcAddress(thModule, "fnAttachWinProc");

             tpArg0 = (IntPtr) m_hTargetWindow;// clsCECoreAPI.MapPtrToProcess(ref thTargetWindow, thCurrentProcess);

             tudtCALLBACKINFO.hProc = m_hTargetProcess;
             tudtCALLBACKINFO.pfn = clsCECoreAPI.MapPtrToProcess(tpFuncProc, m_hTargetProcess);
             tudtCALLBACKINFO.pvArg0 = tpArg0 ;
             tuntApiRet = clsCECoreAPI.PerformCallBack4(ref tudtCALLBACKINFO,IntPtr.Zero,IntPtr.Zero,IntPtr.Zero );
             //clsCECoreAPI.Sleep(5000);
            }

            [DllImport("HookWindowsProcMFCDLL.dll")]
            public static extern int fnAttachWinProc(IntPtr ni_hAttatchWin);

            [DllImport("HookWindowsProcMFCDLL.dll")]
            public static extern int fnDetachWinMsgProc(IntPtr ni_hDetachWin);

            取消掛接的代碼根據(jù)上述代碼很容易就可以建立,不再細(xì)敘。

            注:clsCECoreAPI的函數(shù)全是封裝的標(biāo)準(zhǔn)CE API,由于這些API在msdn 中都有詳細(xì)的文檔注釋?zhuān)蚱蓿辉賹⒋a一一列舉.

            在執(zhí)行這個(gè)程序時(shí),將模擬器的共享路徑設(shè)為PC機(jī)的桌面,這樣模擬器的storage card目錄就等同桌面了,點(diǎn)模擬器的開(kāi)始菜單,選程序,你就可以看到explore窗體的消息都輸出到桌面的WinProcInfo.txt文件中了,運(yùn)行結(jié)果如下:

              

             目前本程序只在PPC2003/wm5 for PPC測(cè)試通過(guò),由于smartphone系統(tǒng)在編譯時(shí)使用了和ppc系統(tǒng)不同的機(jī)制,內(nèi)存運(yùn)作不明,本程序在smartphone上無(wú)法正確運(yùn)行,有好的建議的話請(qǐng)指教一二,謝謝.

            posted on 2008-08-14 09:29 井泉 閱讀(789) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): c code

            久久精品国产国产精品四凭| 久久精品99久久香蕉国产色戒 | 香蕉久久夜色精品国产2020| 久久久久综合国产欧美一区二区| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 国产精品九九久久免费视频| 精品视频久久久久| 无遮挡粉嫩小泬久久久久久久| 久久国产精品99久久久久久老狼| 久久激情亚洲精品无码?V| 无码人妻久久久一区二区三区| 久久久精品久久久久特色影视| 亚洲AV日韩精品久久久久久| 欧美日韩中文字幕久久久不卡| 国产一级做a爰片久久毛片| 久久福利资源国产精品999| 国产日产久久高清欧美一区| 久久亚洲精品国产精品婷婷| 久久久久亚洲?V成人无码| 国产精品久久久久国产A级| 国产精品久久久久久久app| 青青青国产精品国产精品久久久久| 久久精品视频一| 亚洲国产成人精品91久久久| 99久久国产综合精品五月天喷水| 成人久久精品一区二区三区| 亚洲精品无码专区久久同性男| 国产精品美女久久久| 精品久久久久久久久中文字幕| 日韩精品久久久久久久电影蜜臀 | 亚洲午夜无码久久久久| 人妻无码久久精品| 久久se精品一区二区影院 | 久久精品视频网| 久久精品嫩草影院| 国产—久久香蕉国产线看观看| 成人国内精品久久久久影院| 中文精品久久久久国产网址| 伊人色综合久久天天| 韩国三级中文字幕hd久久精品 | 久久成人精品|