• <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, 評論 - 26, 引用 - 0
            數據加載中……

            【轉帖】Windwos CE 跨進程內存注入(PocketPC)

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

              一、程序實現的先決條件

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

              1、將需要掛接窗體的代碼放到目標進程的地址空間中去。

              2、執行這一段代碼,并獲得目標進程窗體的消息。

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

              二、程序實現的基本原理

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

              PerformCallBack4函數的定義:

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

              其中函數的參數CallBackInfo結構定義:

            [StructLayout(LayoutKind.Sequential)]
            public struct CallBackInfo
            {
            public IntPtr hProc; //遠程的目標進程
            public IntPtr pfn; //指向遠程目標進程的函數地址的指針
            public IntPtr pvArg0; //函數的需要的第一個參數
            }//end struct

              而PerformCallback4的 ni_pVoid1、ni_pVoid2、ni_pVoid3為傳遞到遠程目標進程執行函數的其它三個參數。

              至于將代碼放到目標進程的內存空間,我們可以利用CE設計上的一個特性:

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

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

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

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

              本文我們對實現的原理進行了剖析,在下一篇文章中我們將以一個小示例程序演示實現的全過程。



            在文章《淺析Windows CE跨進程內存注入實現窗體消息掛接(上)》中,我們已經得到了這個七巧板游戲所需要的所有小板塊,剩下的事就是等待我們按一定順序將合適的板塊放到合適的位置,本章我們開始進行真刀真槍的實戰演練。

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

            程序的執行步驟設計如下:

            1、編寫一個窗體消息掛接DLL,這個DLL提供一個,函數中利用setwindowlong函數將窗體的默認消息處理過程改為這個掛接DLL中定義的一個窗體過程。

            2、在C#程序中利用findwindow等API函數獲得exlore類窗體的句柄及窗體所屬的進程,并使用performcallback4在目標進程空間中執行coredll.dll的loadLibrary函數將我們寫的掛接dll放到目標進程中。

            3、在C#程序中使用performcallback4在目標進程空間中執行掛接DLL提供的導出接口函數實現跨進程窗體消息截獲.

            一、程序的實現如下:

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

            在HookWindowsProcMFCDLL.cpp中進行掛接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;

            //將一個窗體消息處理掛接到net精簡版MessageWindow對象上的代碼
            typedef struct
            {
             WNDPROC OldWinProc;//保留窗體原始消息處理過程的函數指針
             HWND WindowHandle;//保存net精簡版中對應的窗口掛接的MessageWindow對象的句柄
            } DEFUDT_AttachWinInfo; //end struct

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

            //對指定的窗口進程進行掛接
            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中消息接收窗口對應的原始消息處理函數的函數指針
             m_aAttachWinInfoMap.Lookup(ni_hDetachWin,tudtAttachWinInfo) ;

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

             //將掛接信息消息處理映謝類中刪除
             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#的主程序中,我們使用這個DLL掛接explore類的程序窗體,以下給出掛接部分的代碼:

            int m_hTargetWindow;//要掛接的目標窗體句柄
            IntPtr m_hTargetProcess;//目標窗體所屬的進程
            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;

             //掛接指定的進程窗體消息
             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);

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

            注:clsCECoreAPI的函數全是封裝的標準CE API,由于這些API在msdn 中都有詳細的文檔注釋,因篇幅所限,不再將代碼一一列舉.

            在執行這個程序時,將模擬器的共享路徑設為PC機的桌面,這樣模擬器的storage card目錄就等同桌面了,點模擬器的開始菜單,選程序,你就可以看到explore窗體的消息都輸出到桌面的WinProcInfo.txt文件中了,運行結果如下:

              

             目前本程序只在PPC2003/wm5 for PPC測試通過,由于smartphone系統在編譯時使用了和ppc系統不同的機制,內存運作不明,本程序在smartphone上無法正確運行,有好的建議的話請指教一二,謝謝.

            posted on 2008-08-14 09:29 井泉 閱讀(771) 評論(0)  編輯 收藏 引用 所屬分類: c code

            成人资源影音先锋久久资源网| 2021国内久久精品| 四虎国产永久免费久久| 久久97久久97精品免视看秋霞 | 99久久成人国产精品免费| 久久99国产综合精品免费| 国产精品一久久香蕉产线看| 国产香蕉97碰碰久久人人| 亚洲伊人久久综合影院| 久久久久久久亚洲Av无码| 久久国产视屏| 99久久成人国产精品免费| 亚洲精品国产自在久久| 久久99精品国产一区二区三区 | 久久久久久午夜成人影院| 久久露脸国产精品| 久久综合九色综合久99| 日本加勒比久久精品| 久久线看观看精品香蕉国产| 亚洲综合伊人久久综合| 伊人久久精品影院| 国产精品欧美久久久久天天影视| 精品熟女少妇AV免费久久| 国产成人久久精品麻豆一区| 精品久久久久久久久午夜福利| 伊人久久大香线蕉无码麻豆 | 亚洲成人精品久久| 国产精品一久久香蕉国产线看观看 | 久久久久久国产a免费观看黄色大片| 久久91精品久久91综合| 久久精品国产亚洲AV无码麻豆| 怡红院日本一道日本久久 | AAA级久久久精品无码区| 97久久国产亚洲精品超碰热| 久久精品成人欧美大片| 免费精品国产日韩热久久| 久久综合伊人77777| 久久受www免费人成_看片中文| 久久一区二区三区99| 四虎影视久久久免费观看| 久久久久亚洲AV无码专区网站 |