日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Native Application 开发详解

發(fā)布時(shí)間:2024/4/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Native Application 开发详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄:

?????????????????

1. 引子:

2. Native Application Demo 展示:

3. Native Application 簡介:

4. Native Application 有何妙用:

5. MJ0011 關(guān)于 Native Application 的文章整理:

6. 互聯(lián)網(wǎng)上其他關(guān)于 Native Application 的文章整理:

7. 小結(jié):

????????????????

1. 引子:

?????????????????????????

其實(shí)在好久以前就看了 MJ0011 翻譯的那個(gè)《Native 應(yīng)用程序詳細(xì)》系列的文章,

(PS: MJ0011 為 360 的首席技術(shù)執(zhí)行官,技術(shù)是沒的說,不過貌似有點(diǎn)狂妄之說 ~?)

而且看完后對(duì)這一系列文章也很感興趣的,所以又去 Google 上找了幾個(gè)小資料學(xué)習(xí)了一下,

而這篇文章呢,則是將我前陣子的所謂的學(xué)習(xí)給總結(jié)出來也順道給大伙分享一下。

雖然這里是說的總結(jié) Native Application,但最早出現(xiàn) Native Application 應(yīng)該是 06 年的事了,

(當(dāng)然,Native Application 這個(gè)技術(shù)是一直存在的,只是在 06 年后有了下面這篇文章后就稍微火了點(diǎn))

其是 Sysinternals 上的一篇由 Mark Russinovich 發(fā)表的文章《Inside Native Applications》

文章地址如下:http://technet.microsoft.com/en-us/sysinternals/bb897447

而我卻在 2011 年才得以來總結(jié)這個(gè)技術(shù),所以我確是屬于研究這些東西的落后者啊 ~

下面我給出一副截圖來看一下 Windows 操作系統(tǒng)下的程序的類型:

????????????

在 Windows 最初設(shè)計(jì)的時(shí)候考慮到了兼容各種系統(tǒng)的應(yīng)用程序,所以有了環(huán)境子系統(tǒng)之說,

其中一開始的時(shí)候考慮到了子系統(tǒng),POSIX 子系統(tǒng)和 OS/2 子系統(tǒng),

但是隨著歷史的發(fā)展,現(xiàn)在也就剩下個(gè) Windows 子系統(tǒng)了,

我們?nèi)粘J褂玫?Windows 操作系統(tǒng)的上層其實(shí)也就是指的這個(gè) Windows 子系統(tǒng)了,

至于這里為何要扯到 Windows 子系統(tǒng)的話,就看下文介紹了。

很多朋友都知道有 Windows 應(yīng)用程序和 Windows 內(nèi)核驅(qū)動(dòng)程序之說,

卻很少有知道在 Windows 中還有 Native Application 一說了,

但是這類程序確實(shí)是存在的 ~只不過這類程序應(yīng)用比較窄,也沒有被很好的推廣開來,

當(dāng)然還有一點(diǎn)就是 Microsoft 自然不希望你隨隨便便的使用 Native API。

???????????

??????????????

2. Native Application Demo 展示:

??????????????

首先你需要將下載(博文的最后面附上 Demo 的下載地址)的 EXE 文件拷貝一份到 system32 目錄下,

(博文的 Demo 只是拿了網(wǎng)上的代碼然后自行使用 DDK 編譯了而已,Demo 并非筆者原創(chuàng))

然后再在注冊(cè)表以下路徑中修改 BootExecute,

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

在其中添加?NativeApp_01 Hello World !?這個(gè)字符串,

????????????????????

??????????

重啟電腦,然后就可以看到下面的效果圖了(僅在 XP SP3 上進(jìn)行了測試)

??????????????

???????????????????

3. Native Application 簡介:

??????????????

何為 Native API ?

Native API 就是你 system32 目錄下的那個(gè) ntdll.dll 中所公開的 API(大部分為 Undocument)~

如果讀者看過我前面的《進(jìn)程隱藏與進(jìn)程保護(hù)(SSDT Hook 實(shí)現(xiàn))》系列文章的話,

相信肯定會(huì)知道在 Windows 中 kernel32.dll 中的 API 的調(diào)用都會(huì)經(jīng)過轉(zhuǎn)換,

也就是跳轉(zhuǎn)到 ntdll.dll 中,并且在 ntdll.dll 中也有與之相對(duì)于的 API 調(diào)用,

(比如 Kernel32.dll 中的 CreateProcess 在 ntdll.dll 中有 NtCreateProcess 與之對(duì)應(yīng))

那么什么稱之為 Native 應(yīng)用程序呢 ?

下面給出一副截圖:

????????????

從上面的截圖可以看出,在一開始的 Windows NT 內(nèi)核中是支持三個(gè)環(huán)境子系統(tǒng)的,

即 POSIX,WINDOWS,OS/2,這些子系統(tǒng)屬于同一層,它們共用了 Windows NT 所提供的 API,

即每一個(gè)子系統(tǒng)中的 API 的調(diào)用都會(huì)轉(zhuǎn)換到下一層的相同調(diào)用上,

在 Windows 環(huán)境子系統(tǒng)(有 Windows,Posix,OS/2)中的程序,

都會(huì)調(diào)用其相對(duì)于的子系統(tǒng)下的 API,比如 Windows 子系統(tǒng)中的程序有可能會(huì)調(diào)用 Win32 API CreateProcess,

而 Posix 子系統(tǒng)中的程序也有可能會(huì)調(diào)用 Posix API CreateProcess(當(dāng)然有可能在 POSIX 下創(chuàng)建進(jìn)程不是這個(gè)名稱),

但是終歸來說,這兩個(gè) CreateProcess 的調(diào)用都會(huì)轉(zhuǎn)換到 Ntdll.dll 中的 NtCreateProcess 中,

也就是上面的三個(gè)子系統(tǒng)最后的調(diào)用都會(huì)回歸到 ntdll.dll 上,

而我們的 Native Application 則是繞過 Windows 子系統(tǒng),

直接自己調(diào)用 Native API,比如創(chuàng)建進(jìn)程的話,我就不再通過子系統(tǒng)中的神馬 CreateProcess 來完成了,

而是直接在程序中調(diào)用 ntdll.dll 中的 Native API NtCreateProcess 來完成,

而這類程序即稱之為 Native Application !

???????????

Native Application 的運(yùn)行環(huán)境:

上面也說了,Native Application 是只能夠訪問 ntdll.dll 中的內(nèi)容的,

而如果是在子系統(tǒng)下運(yùn)行一個(gè)程序的話,必然會(huì)加載其他的 DLL,

比如在 Windows 子系統(tǒng)下一個(gè) kernel32.dll 是必不可少的吧,

如果 Native Application 能夠運(yùn)行在 Windows 子系統(tǒng)下的話,必然也會(huì)加載到 Kernel32.dll,

這樣不就和上面相違背了嘛 ~

總之:Native Application 是不能夠運(yùn)行在任何子系統(tǒng)下的 !

比如在 Windows 子系統(tǒng)下運(yùn)行 Native Application 會(huì)彈出如下錯(cuò)誤對(duì)話框:

??????????

Native Application 的啟動(dòng)時(shí)機(jī):

對(duì)于 Windows 操作系統(tǒng)的引導(dǎo)過程,這里需要帶一筆的,Windows 操作系統(tǒng)啟動(dòng)時(shí),

當(dāng) Windows 內(nèi)核的引導(dǎo)完成以后,就會(huì)啟動(dòng)會(huì)話管理器 smss.exe 進(jìn)程了,

smss.exe 進(jìn)程雖然是一個(gè)用戶模式的進(jìn)程,但是這個(gè)進(jìn)程相對(duì)于其他用戶模式進(jìn)程是具有一定特殊性的,

首先 smss.exe 進(jìn)程是直接建立在 Windows NT 內(nèi)核上的,其不依賴于任何一個(gè)環(huán)境子系統(tǒng),

至于不依賴于任何一個(gè)環(huán)境子系統(tǒng)這一說的話,還是可以很好的解釋的,

因?yàn)楫?dāng)環(huán)境子系統(tǒng)進(jìn)程(Windows 子系統(tǒng)進(jìn)程為 csrss.exe)就是由 smss.exe 進(jìn)程啟動(dòng)的,

然后 smss.exe 是 Windows 操作系統(tǒng)啟動(dòng)的第一個(gè)用戶態(tài)進(jìn)程,

而 Native Application 也屬于用戶態(tài)程序,自然 Native Application 的啟動(dòng)是在 smss.exe 之后,

而后前面也說過,Native Application 運(yùn)行時(shí),子系統(tǒng)進(jìn)程還尚未啟動(dòng),

所以 Native Application 的啟動(dòng)則是在 csrss.exe 之前的,

而話又說回來,csrss.exe 就是由會(huì)話管理器(smss.exe)啟動(dòng)的,

所以 Native Application 的啟動(dòng)時(shí)機(jī)也就只有一種可能了,

即 smss.exe 先啟動(dòng) Native Application,然后 Native Application 開始執(zhí)行,

等到 Native Application 都給執(zhí)行完了后 smss.exe 再啟動(dòng) csrss.exe 進(jìn)程。

(事實(shí)上,Win32 應(yīng)用程序環(huán)境子系統(tǒng) csrss.exe 本質(zhì)上也是一個(gè) Native Application ~)

下面給出一副截圖以說明 SMSS.EXE 的在啟動(dòng)過程中所完成的工作:

運(yùn)行啟動(dòng)時(shí)執(zhí)行的程序即是執(zhí)行 Native Application

??????????

???????????

4. Native Application 有何妙用:

??????????????

前面也提到過,Native Application 的應(yīng)用范圍比較窄,這主要受以下幾點(diǎn)約束:

首先,Native Application 是直接調(diào)用 Native API 來完成任務(wù)的,

而在 Windows 中,Native API 絕大部分都是 Undocument 的,這樣開發(fā)起來自然難度會(huì)大很多了。

然后,由于 Native Application 是調(diào)用的 Undocument API,

說不準(zhǔn)那一天 Microsoft 就在下一代 Windows 中修改了這個(gè) API,這樣的話,你程序的可移植性也就完全沒了。

最后的話,Native Application 的執(zhí)行環(huán)境并非是在 Windows 子系統(tǒng)中,

事實(shí)上,當(dāng) Native Application 開始執(zhí)行的時(shí)候,Windows 子系統(tǒng)進(jìn)程(csrss.exe)進(jìn)程都還沒有啟動(dòng)的 ~

所以 Native Application 的執(zhí)行是受限制的,其不能夠執(zhí)行子系統(tǒng)中的任何東西,

說白一點(diǎn)的話就是 Native Application 只能夠調(diào)用 ntdll.dll 中的 API,

其他 DLL 中的 API 一律不得調(diào)用,這樣也就注定 Native Application 的應(yīng)用范圍不會(huì)很廣泛了。

??????????

應(yīng)用范圍比較窄并不等于說沒有應(yīng)用價(jià)值,

也還是有蠻多的軟件,包括一些商業(yè)軟件也都是用了 Native Application,

下面來看一些 Native Application 的應(yīng)用(我也只是從網(wǎng)上道聽途說,不過有些也確實(shí)是自己也用過的):

最典型的應(yīng)用自然是屬于 Windows 操作系統(tǒng)自帶的磁盤自檢程序了;

然后比較典型的商業(yè)應(yīng)用是瑞星的開機(jī)殺毒,即實(shí)現(xiàn)讓病毒在你還沒有完全開機(jī)之前死掉;

然后就是可以通過 Native Application 來實(shí)現(xiàn)接管 Windows 的開機(jī)啟動(dòng)界面和密碼輸入界;

還可以通過 Native Application 來實(shí)現(xiàn)開機(jī)前的磁盤修復(fù)(Windows 自帶了這款工具也是這樣實(shí)現(xiàn)的);

??????

???????????

5. MJ0011 關(guān)于 Native Application 的文章整理:

??????????

這一小節(jié)里面主要是整理一下關(guān)于 MJ0011 的 Native Application 的博文,

也就是說我這里純粹是將他的東西給貼出來瞧瞧,關(guān)于 MJ0011 博文的原地址為:

《NATIVE應(yīng)用程序詳細(xì)之一》:

http://hi.baidu.com/mj0011/blog/item/7ee496d67a4d4d2f07088bc7.html

《NATIVE應(yīng)用程序詳細(xì)之2 NATIVE應(yīng)用程序的優(yōu)勢和劣勢》

http://hi.baidu.com/mj0011/blog/item/f8108f2f5890fb381e30896d.html

《native應(yīng)用程序詳細(xì)之三 構(gòu)建native應(yīng)用程序》:

http://hi.baidu.com/mj0011/blog/item/725b4882042b03a20df4d269.html

《深入Native應(yīng)用程序》(該文翻譯自《Inside Native Application》):

http://hi.baidu.com/mj0011/blog/item/85c0b50f80b1baedab6457de.html

《native app GUI界面的實(shí)現(xiàn)》:

http://hi.baidu.com/mj0011/blog/item/6e5a22fa214c8116a9d3115b.html

???????????????????

Native?應(yīng)用程序簡介:

NT 系統(tǒng)被設(shè)計(jì)成為支持子系統(tǒng)(封裝),它可以執(zhí)行在不同平臺(tái)上的代碼。包括但不限于:POSIX、OS/2和Win32,

為了管理這些子系統(tǒng),NT內(nèi)核輸出了大量名為 Native API的API函數(shù),子系統(tǒng)服務(wù)將這些函數(shù)包裝為他們自己的函數(shù)。

例如:CreateFile和fopen都被映射到NtCreateFile.那么子系統(tǒng)管理程序運(yùn)行在哪個(gè)子系統(tǒng)中?

為了避免先有雞還是先有蛋的問題,NT系統(tǒng)同樣支持原生的Native應(yīng)用程序。

這些Native應(yīng)用程序是獨(dú)立于子系統(tǒng)的。現(xiàn)在,所有的子系統(tǒng)應(yīng)用程序都需要注冊(cè)它們自己的子系統(tǒng)服務(wù),

顯然,Kernel32是一個(gè)Win32應(yīng)用程序,csrss注冊(cè)WIN32子系統(tǒng),然后通知子系統(tǒng)管理器SMSS,

因此,一個(gè)Native應(yīng)用程序是無法調(diào)用其中數(shù)千種API的,

同時(shí)它也無法使用一些基本的DLL中的函數(shù)例如kernel32、user32、gdi32等,

其它任何調(diào)用了這三者的DLL中的函數(shù)的DLL也無法被使用。

事實(shí)上,加載者在其入口點(diǎn)沒有被加載前,并不允許加載決大多數(shù)的Win32 DLL。

因此,native應(yīng)用程序被限制只許使用一個(gè)DLL:ntdll.dll,這個(gè)DLL供應(yīng)所有Native和運(yùn)行函數(shù)。

但是想想,既然所有Win32函數(shù)最后都是去調(diào)用Ntdll.dll中的函數(shù)來實(shí)現(xiàn)的(除了GUI部分),

這些函數(shù)就已經(jīng)足夠了,不是嗎?

???????????

Native應(yīng)用程序優(yōu)勢:

(一) 內(nèi)存使用和大小:因?yàn)镹ative應(yīng)用程序并不需要加載90多個(gè)DLL到內(nèi)存中去,因此其使用的內(nèi)存是很小的。

(二) 速度:Native API比Win32對(duì)應(yīng)的函數(shù)要更快(通常會(huì)快很多),

盡管實(shí)際上很多時(shí)間都被消耗在Win32 API的封裝上,這些包括修改、兼容性選項(xiàng),和其他的代碼部分,

這些都會(huì)在執(zhí)行真正的Native調(diào)用前執(zhí)行。如果你知道如何去做而且希望它運(yùn)行得更快,Native是一個(gè)很好的方法。

因?yàn)椴恍枰虞d那90多個(gè)DLL,kernel32不需要到csrss和smss做lpc注冊(cè),因此啟動(dòng)也是非常快速和直接的。

(三) 熟悉程度和特性:Native應(yīng)用程序并沒有古怪的入口點(diǎn)或者奇怪的Hack,就象讀命令行一樣簡單使用,

而事實(shí)上將在后面介紹,Native應(yīng)用程序和Console程序一樣啟動(dòng)與_main函數(shù),

通過一組簡單的char*[]隊(duì)列來接受命令行參數(shù)和環(huán)境變量,就象一個(gè)典型的Win32 Console程序一樣,

一些特性例如緩沖區(qū)溢出保護(hù)(/GS)、Safe SEH(/SAFESEH)、hotpathing(/HOTPATCH),

以及其他的特性都被支持。

(四) 豐富:Native API非常豐富,它們提供的特性和功能性要遠(yuǎn)遠(yuǎn)超越Win32函數(shù)所能達(dá)到的程度。

這并不是說Win32無法做到Native API那樣的更困難和更復(fù)雜的工作,而是Win32太過簡單而已,

比如Win32函數(shù)中,無法遠(yuǎn)程注入一個(gè)Section到一個(gè)進(jìn)程中,因?yàn)镸apViewOfFileEx不提供進(jìn)程句柄接口,

而Native API則可以實(shí)現(xiàn)這個(gè)功能。

(五) 安全:但是Native應(yīng)用程序有這樣一個(gè)特點(diǎn):人們對(duì)于Native API不是十分熟悉,

他們需要花費(fèi)更多的時(shí)間才能理解你的代碼,而更重要的是,無法使用一個(gè)用戶模式的debugger來調(diào)試Native應(yīng)用程序,

只有SoftIce和使用內(nèi)核模式遠(yuǎn)程連接的WinDbg才可以對(duì)其進(jìn)行調(diào)試,這足以讓那些廢物腳本小子去死了,

再說一遍,這并不意味著Native 應(yīng)用程序是“不可調(diào)試的,安全的”,只是它更模糊更難被破解。

(六) 同內(nèi)核模式的連接:因?yàn)镹ative應(yīng)用程序只使用Native API,這些函數(shù)在內(nèi)核模式仍然可用,

這樣,一個(gè)Native程序只需少量修改就可修改為內(nèi)核驅(qū)動(dòng),而Win32程序則需要幾乎重寫所有代碼。

(七) 運(yùn)行在獨(dú)立于子系統(tǒng)的環(huán)境中:因?yàn)镹ative應(yīng)用程序并不依賴與任何子系統(tǒng),

它運(yùn)行于一個(gè)正常應(yīng)用永遠(yuǎn)無法再次得到的環(huán)境中,比如autochk.exe,它運(yùn)行與任何子系統(tǒng)加載之前,

并負(fù)責(zé)顯示'press any key to scan your hard disk"信息,并掃描你的硬盤是否有錯(cuò)誤。

在這個(gè)模式運(yùn)行允許你顯示信息到啟動(dòng)屏幕上,以及很多增強(qiáng)特性。

(八) 標(biāo)準(zhǔn)性:不象Win32函數(shù)有一個(gè)正常版本,一個(gè)"Ex"版本,以及經(jīng)常有一個(gè)"擴(kuò)展其他功能"的版本,

以及經(jīng)常返回0,1,-1或一些隨機(jī)的數(shù)值來表示成功,并且要使用SetLastError來設(shè)置返回錯(cuò)誤,

在Native應(yīng)用程序中,這些垃圾都是不存在的,所有的Native API都有統(tǒng)一的標(biāo)準(zhǔn),

所有都返回NTSTAUS(除非明確表示會(huì)返回一個(gè)特定的值),NTSTAUS是一個(gè)標(biāo)準(zhǔn)的錯(cuò)誤碼定義,

而且使用它們時(shí)你也不需要考慮該死的Ex版本。

?????????????

Native?應(yīng)用程序劣勢:

(一) 和Win32開發(fā)的差異較大:如果你以前從來沒有進(jìn)行過Native API或內(nèi)核驅(qū)動(dòng)的相關(guān)開發(fā),

你可能需要學(xué)習(xí)所有的API相關(guān)知識(shí),當(dāng)然,他們的名字是相似的,但是他們的標(biāo)志經(jīng)常是完全不同的,

而且他們的返回值,很可能使你感到迷惑。

(二) 缺少文檔:雖然所有的Rtl*函數(shù)都是有文檔的,數(shù)百個(gè)其他的Native API仍是無文檔的。

(三) 缺少商業(yè)價(jià)值:雖然Native程序如此美好,但是建議你不要在商業(yè)產(chǎn)品中使用 Native API 或著使用Native應(yīng)用程序,

Native API是可能改變的,雖然它們通常沒有改變,但是他們很可能變得不再有用,不要拿你的客戶的錢冒險(xiǎn)。

(四) 沒有GUI、及輸入/輸出接口:沒有"Native控制臺(tái)程序",你無法簡單地從用戶那里接受到輸入或顯示些什么到屏幕上,

因?yàn)槟切┙涌诙紵o法再使用(控制臺(tái)API都是Win32 API)。

?????????

Native?應(yīng)用程序構(gòu)建:

你需要這兩者或兩者之一來創(chuàng)建你的 native 應(yīng)用程序:

(1)Visual C++ 2005 Express(or higher)

(2)Windows Driver Kit

我們將從基礎(chǔ)開始,首先你需要?jiǎng)?chuàng)建你的應(yīng)用程序的頭文件,precomp.h,ntddk.h

1: #include "ntddk.h"

Now that that's done, create your main initialization file,

which we will call init.c. In this file, add precomp.h like this:

1: #include "precomp.h"

And define your entrypoint:

1: NTSTATUS __cdeclmain( 2: ? 3: INT argc, 4: ? 5: PCHAR argv[], 6: ? 7: PCHAR envp[], 8: ? 9: ULONG DebugFlag OPTIONAL) 10: ? 11: { 12: ? 13: // Entry code here 14: ? 15: }

Hopefully you are familiar with this entrypoint, it's the typical one used?by C programs,

except with an addon: the "DebugFlag". Right now, we don't?need to care about this.

We'll keep this entry simple, and turn this into a "Hello World":

1: NTSTATUS __cdecl main( 2: ? 3: INT argc, 4: ? 5: PCHAR argv[], 6: ? 7: PCHAR envp[], 8: ? 9: ULONG DebugFlag OPTIONAL) 10: ? 11: { 12: ? 13: UNICODE_STRING HelloMsg = RTL_CONSTANT_STRING(L"Hello World!\n"); 14: ? 15: //Say hello 16: ? 17: NtDisplayString(&HelloMsg); 18: ? 19: } 20: ?

Now, if you're wondering what NTSTATUS is,

what NtDisplayString is or what

RTL_CONSTANT_STRING and UNICODE_STRINGs are,

then you'll need to read all?the DDK documentation you can swallow,

as well as Nebett's Undocumented?Native API book.

Although it's outdated,?the information about the APIs is?still pretty valid.

I also plan to possibly give a fully-fledged lesson on this if lots of

people are interested.So now that we have our simple program,?we need to build it.

I prefer using the WDK myself,

because it's much?simpler and doesn't require changing 100 of MSVC's default settings.

Assuming you've properly installed the WDK and entered the Windows build?environment?for

your OS (from the Start Menu),

you'll need to create two?files in the directory where init.c and precomp.h are:

sources and makefile.

Sources should look something like this:

--

1: TARGETNAME=native 2: ? 3: TARGETTYPE=PROGRAM 4: ? 5: UMTYPE=nt 6: ? 7: INCLUDES=\ 8: ? 9: $(DDK_INC_PATH); \ 10: ? 11: $(NDK_INC_PATH); 12: ? 13: SOURCES=init.c 14: ? 15: PRECOMPILED_INCLUDE=precomp.h 16: ? --

that you'll have to set NDK_INC_PATH as an environment variable yourself,

to where the NDK is installed (DDK_INC_PATH is already setup by the WDK).

Finally, you'll need a makefile:

--

1: INCLUDE $(NTMAKEENV)\makefile.def

--

That's all you really need for our purposes.

So now you should?have init.c, precomp.h, sources and makefile.

The only thing left is to?write "build",

and the WDK should do the magic and create your first native application.

Unforunately, you can't really test it for now,

unless you do?the following:Open registry editor and browse to

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

Edit the "BootExecute" key and write "native" instead of what's currently?in it,

then copy native.exe to your system32 directory and restart the?computer.

You should see the message appear on the screen for a little while.

Make sure that you do NOT boot with /NOGUIBOOT, or else you will never see?it.

??????

//??

//??

/MJ0011 翻譯《Inside Native Application》//

//??

//??

???????????

導(dǎo)言

如果你對(duì)Windows Nt結(jié)構(gòu)有一定的了解,你可能會(huì)知道,Win32 應(yīng)用程序所使用的API,

并非是"真正"的NT API,POSIX、OS/2和Win32這些Windows NT 操作系統(tǒng)環(huán)境,

使用他們自己的 API 同他們的客戶應(yīng)用程序進(jìn)行交流,但卻使用Windows NT的"Native" API同Windows NT交流,

這些Native API大都是未公開UnDocumented 的。

大約只有25個(gè)API(包含250種功能)在Windows NT設(shè)備驅(qū)動(dòng)開發(fā)工具包(DDK)里有所描述。

盡管絕大多數(shù)人都不知道,但"Native"應(yīng)用程序的確存在與Windows NT上,他們?cè)诓僮鳝h(huán)境上沒有任何客戶程序,

這些程序交流著Native NT API并且不能使用任何操作環(huán)境API比如 Win32,為什么這樣一種程序是必須的呢?

因?yàn)樵赪in32子系統(tǒng)啟動(dòng)之前(大約在登陸對(duì)話框出現(xiàn)時(shí))只可以運(yùn)行Native應(yīng)用程序,

最常見的Native應(yīng)用程序的例子是"autochk"程序,他在初始化藍(lán)色登陸屏幕前運(yùn)行chkdsk(程序在屏幕上打印一串".")。

當(dāng)然,Win32應(yīng)用程序環(huán)境服務(wù)程序:CSRSS.exe(客戶-服務(wù)運(yùn)行時(shí)間子系統(tǒng)),也是一個(gè)Native應(yīng)用程序。

在這篇文章里,我將會(huì)講述如何構(gòu)造一個(gè)Native應(yīng)用程序以及它們是如何工作的,

同時(shí)我也會(huì)提供一個(gè)Native應(yīng)用程序的示例源代碼。

這個(gè)示例很容易安裝,它會(huì)在啟動(dòng)時(shí)的藍(lán)色屏幕打印一段你指定的字符串。

???????????????

Autochk是如何被執(zhí)行的

Autochk在當(dāng)內(nèi)存分頁被打開,Windows啟動(dòng)和系統(tǒng)開始驅(qū)動(dòng)被載入之間的時(shí)間內(nèi)運(yùn)行,

在這個(gè)時(shí)間點(diǎn)會(huì)啟動(dòng)會(huì)話管理器(smss.exe)進(jìn)入Windows NT用戶模式,并且沒有任何程序被啟動(dòng)。

注冊(cè)表中:HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute

一個(gè)MULTI_SZ類型的鍵值,這里存放著將被會(huì)話管理器所執(zhí)行的程序名稱和參數(shù),通常是Autochk后加*號(hào)作為其參數(shù)

Autocheck Autochk *?
;名稱 程序名 參數(shù)

會(huì)話管理器在<winnt>\system32目錄下查找該值列出的可執(zhí)行程序,當(dāng)Autochk運(yùn)行時(shí),沒有任何文件被打開,

所以Autochk可以用raw模式打開任何一個(gè)驅(qū)動(dòng)器卷(包括根驅(qū)動(dòng)器),并操作其磁盤數(shù)據(jù)結(jié)構(gòu),

之后的任何時(shí)間點(diǎn)都無法進(jìn)行類似這樣的操作。

??????????????

編譯Native應(yīng)用程序

1. 微軟沒有提供相應(yīng)的文檔,但是NT DDK構(gòu)建器知道如何去生成一個(gè)Native應(yīng)用程序,

而且它可以被用來編譯autochk程序,和編寫設(shè)備驅(qū)動(dòng)程序一樣,你必須指定SOURCE文件中的信息來定義應(yīng)用程序,

然而和編寫驅(qū)動(dòng)不同的時(shí),你在SOURCE文件中要求生成一個(gè)Native應(yīng)用程序需要這樣定義:

TARGETTYPE=PROGRAM

2. 構(gòu)建器使用一個(gè)標(biāo)準(zhǔn)的makefile來進(jìn)行向?qū)?\ddk\inc\makefile.def 在編譯Native應(yīng)用程序時(shí),

會(huì)查找名為nt.lib的運(yùn)行庫。不幸的是,微軟并沒在DDK上裝載這個(gè)文件(在Windows Server 2003 DDK里包括了這個(gè)文件,

但是我懷疑你用這個(gè)版本來連接你的Native應(yīng)用程序是無法運(yùn)行在Windows XP或Windows 2000上的)不管怎樣,

你可以忽略這個(gè)錯(cuò)誤,方法是加入一行不考慮nt.lib,而指定Visual C++ 的運(yùn)行庫msvcrt.lib到makefile.lib中。

3. 如果你在DDK的"Checked Build"環(huán)境下進(jìn)行編譯,

將會(huì)在%BASEDIR%\lib\%CPU%\ Checked(例如c:\ddk\lib\i386\checked\ native.exe)

產(chǎn)生一個(gè)包含了全部調(diào)試信息的Native應(yīng)用程序。

4. 如果在"Free Build"環(huán)境中編譯,你會(huì)在%BASEDIR%\lib\%CPU%\Free得到一個(gè)釋出版本的程序,

這些和構(gòu)造設(shè)備驅(qū)動(dòng)程序放置的位置是一樣的。

5. Native應(yīng)用程序有著".exe"的擴(kuò)展名,但是你不能像 Win32的.exe文件那樣去運(yùn)行它,

如果你在Win32環(huán)境下運(yùn)行下,將會(huì)得到如下提示:"<應(yīng)用程序名> 應(yīng)用程序無法在Win32模式中運(yùn)行。"

?????????????

深入學(xué)習(xí)Native應(yīng)用程序

1. Native應(yīng)用程序的入口點(diǎn)是NtProcessStartup,類似WinMain或Main,不同于其他的 Win32入口點(diǎn)的是,

Native應(yīng)用程序提供一個(gè)數(shù)據(jù)結(jié)構(gòu)來存放它的唯一的參數(shù)來定位命令行參數(shù)。

2. 大多數(shù)的Native應(yīng)用程序的運(yùn)行環(huán)境是由Windows Nt的Native API輸出庫 - NTDLL.DLL提供的。

3. Native應(yīng)用程序必須使用RtlCreateHeap(一個(gè)ntdll函數(shù))來創(chuàng)建他們自己的堆來分配存儲(chǔ),

使用RtlAllocateHeap來分配內(nèi)存以及用RtlFreeHeap來釋放內(nèi)存。

4. Native應(yīng)用程序需要使用NtDisplayString 函數(shù)才可以打印想要的內(nèi)容到屏幕上(將被輸出到初始化時(shí)的藍(lán)色屏幕上)。

5. Native應(yīng)用程序不像Win32程序那樣簡單地從他們的啟動(dòng)函數(shù)返回,你需要調(diào)用NtProcessTerminate函數(shù)來結(jié)束它的進(jìn)程。

6. NTDLL運(yùn)行包含了數(shù)百個(gè)函數(shù)允許Native應(yīng)用程序執(zhí)行文件I/O,與設(shè)備驅(qū)動(dòng)進(jìn)行相連,并執(zhí)行進(jìn)程間通訊。

不幸的是,他們大部分都是未公開的。

?????????

Native應(yīng)用程序?qū)嵗?/span>

1. 我創(chuàng)建一個(gè)Native應(yīng)用程序用來演示Native應(yīng)用程序是如何構(gòu)建的以及他們是如何工作的。

運(yùn)行install.bat來安裝Native程序。

2. 批處理程序復(fù)制Native.exe到你的<winnt>\system32目錄,

并在注冊(cè)表中增加一個(gè)BootExecute的入口點(diǎn): native Hello World!

3. 當(dāng)你重新啟動(dòng)時(shí),會(huì)話管理器運(yùn)行完autochk后就會(huì)執(zhí)行Native,Native分配一些堆,

定位它的命令行參數(shù)并打印參數(shù)("Hello world!")到藍(lán)色屏幕上,它所使用的函數(shù)上面已說過了。

如果你想要打印其他的簡單內(nèi)容,可以編輯BootExecute值使用regedit或regedit32,

修改"Hello world"為你想要的信息。

4. 運(yùn)行uinstall.bat可以卸載這個(gè)Native執(zhí)行程序。它從<winnt>\system32 目錄刪除 Native.exe,

并修改BootExecute值為通常的值。

5. 如果你想要構(gòu)建native程序你必須要用Windows設(shè)備驅(qū)動(dòng)工具包(DDK),

復(fù)制makefile.def到 \ddk\inc然后你可以運(yùn)行構(gòu)建。

????????

Native.H

1: //Environment information, which includes command line and image file name 2: typedef struct 3: { 4: ULONG Unknown[21]; 5: UNICODE_STRING CommandLine; 6: UNICODE_STRING ImageFile; 7: } ENVIRONMENT_INFORMATION, *PENVIRONMENT_INFORMATION; 8: 9: // This structure is passed as NtProcessStartup's parameter 10: typedef struct 11: { 12: ULONG Unknown[3]; 13: PENVIRONMENT_INFORMATION Environment; 14: } STARTUP_ARGUMENT, *PSTARTUP_ARGUMENT; 15: 16: // Data structure for heap definition. 17: // This includes various sizing parameters and callback routines, 18: // which, if left NULL, result in default behavior 19: typedef struct 20: { 21: ULONG Length; 22: ULONG Unknown[11]; 23: } RTL_HEAP_DEFINITION, *PRTL_HEAP_DEFINITION; 24: 25: // Native NT api function to write something to the boot-time 26: // blue screen 27: NTSTATUS NTAPI NtDisplayString( 28: PUNICODE_STRING String 29: ); 30: 31: // Native applications must kill themselves when done - 32: // the job of this native API 33: NTSTATUS NTAPI NtTerminateProcess( 34: HANDLE ProcessHandle, 35: LONG ExitStatus 36: ); 37: 38: // Definition to represent current process 39: #define NtCurrentProcess() ( (HANDLE) -1 ) 40: 41: // Heap creation routine 42: HANDLE NTAPI RtlCreateHeap( 43: ULONG Flags, 44: PVOID BaseAddress, 45: ULONG SizeToReserve, 46: ULONG SizeToCommit, 47: PVOID Unknown, 48: PRTL_HEAP_DEFINITION Definition 49: ); 50: 51: // Heap allocation function (ala "malloc") 52: PVOID NTAPI RtlAllocateHeap( 53: HANDLE Heap, 54: ULONG Flags, 55: ULONG Size 56: ); 57: 58: // Heap free function (ala "free") 59: BOOLEAN NTAPI RtlFreeHeap( 60: HANDLE Heap, 61: ULONG Flags, 62: PVOID Address 63: );

???????

Native.C

1: //====================================================================== 2: // 3: // This is a demonstration of a Native NT program. These programs 4: // run outside of the Win32 environment and must rely on the raw 5: // services provided by NTDLL.DLL. AUTOCHK (the program that executes 6: // a chkdsk activity during the system boot) is an example of a 7: // native NT application. 8: // 9: // This example is a native 'hello world' program. When installed with 10: // the regedit file associated with it, you will see it print 11: // "hello world" on the initialization blue screen during the system 12: // boot. This program cannot be run from inside the Win32 environment. 13: // 14: //====================================================================== 15: #include "ntddk.h" 16: #include "stdio.h" 17: #include "native.h" 18: 19: // Our heap 20: HANDLE Heap; 21: //---------------------------------------------------------------------- 22: // NtProcessStartup 23: // Instead of a 'main', NT applications are entered via this entry point. 24: //---------------------------------------------------------------------- 25: void NtProcessStartup( PSTARTUP_ARGUMENT Argument ) 26: { 27: PUNICODE_STRING commandLine; 28: PWCHAR stringBuffer; 29: PWCHAR argPtr; 30: UNICODE_STRING helloWorld; 31: RTL_HEAP_DEFINITION heapParams; 32: 33: // Initialize some heap 34: memset( &heapParams, 0, sizeof( RTL_HEAP_DEFINITION )); 35: heapParams.Length = sizeof( RTL_HEAP_DEFINITION ); 36: Heap = RtlCreateHeap( 2, 0, 0x100000, 0x1000, 0, &heapParams ); 37: 38: // Point at command line 39: commandLine = &Argument->Environment->CommandLine; 40: // Locate the argument 41: argPtr = commandLine->Buffer; 42: while( *argPtr != L' ' ) 43: { 44: argPtr++; 45: } 46: argPtr++; 47: 48: // Print out the argument 49: stringBuffer = RtlAllocateHeap( Heap, 0, 256 ); 50: swprintf( stringBuffer, L"\n%s", argPtr ); 51: 52: helloWorld.Buffer = stringBuffer; 53: helloWorld.Length = wcslen( stringBuffer ) * sizeof(WCHAR); 54: helloWorld.MaximumLength = helloWorld.Length + sizeof(WCHAR); 55: 56: NtDisplayString( &helloWorld ); 57: 58: // Free heap 59: RtlFreeHeap( Heap, 0, stringBuffer ); 60: 61: // Terminate 62: NtTerminateProcess( NtCurrentProcess(), 0 ); 63: }

?????????????????????????

Install.bat:

1: @echo off 2: copy native.exe %systemroot%\system32\. 3: regedit /s add.reg 4: echo Native Example Installed

??????????????

UnInstall.bat:

1: @echo off 2: del %systemroot%\system32\native.exe 3: regedit /s remove.reg 4: echo Native Example Uninstalled

???????????

???????????

6. 互聯(lián)網(wǎng)上其他關(guān)于 Native Application 的文章整理:

?????????

下面給出的則是我在互聯(lián)網(wǎng)上其他地方找到的關(guān)于 Native Application 的比較好的資料,

這里也只是將這些資料進(jìn)行一個(gè)整理。

《native app 開發(fā)小結(jié)(一)》:

http://hi.baidu.com/316526334/blog/item/32823e8a83d87b1fc9fc7a0f.html

《native app 開發(fā)小結(jié)(二)》:

http://hi.baidu.com/316526334/blog/item/43a21061ad619cd28cb10d08.html

《Native Application 應(yīng)用之開機(jī)殺毒》:

http://www.cublog.cn/u/8754/showart_447592.html

?????????????

程序類型

關(guān)于程序級(jí)別的分類,大概可以分為三層:應(yīng)用層程序,即普通的APP程序;Native App程序,如常見的chkdsk工具,PQ分區(qū)工具等,都屬于這類,它是在win子系統(tǒng)未啟動(dòng)起來就執(zhí)行的程序,執(zhí)行環(huán)境比較純凈,只能調(diào)用ntdll.dll導(dǎo)出的函數(shù);

Driver 內(nèi)核驅(qū)動(dòng)程序,因功能不同也分為若干類,如設(shè)備驅(qū)動(dòng)程序,內(nèi)核擴(kuò)展程序,文件系統(tǒng)驅(qū)動(dòng),過濾驅(qū)動(dòng)等,

同屬于內(nèi)核態(tài)程序;其中,native app在項(xiàng)目開發(fā)中用的較少,所用的函數(shù)接口MS也均未公開,

開發(fā)難度和驅(qū)動(dòng)相當(dāng),所以很少有人問津。但是,事實(shí)上,在某些應(yīng)用場景下,用native app來實(shí)現(xiàn)是非常完美的,

比如:接管winodws的開機(jī)啟動(dòng)界面和密碼輸入界面,需要native app;

在開機(jī)前,執(zhí)行磁盤修復(fù),需要native app;開機(jī)前,執(zhí)行殺毒,或者磁盤整理,

因?yàn)榇藭r(shí)環(huán)境比較純凈,需要native app。諸如此類~?最近,開發(fā)一個(gè)Native App項(xiàng)目,其規(guī)模和復(fù)雜度也不一般。

期間遇到很多問題,在逐一解決的時(shí)候也收獲了很多東西。現(xiàn)在略作整理,以備將來查用,二來與大家分享之~

??????????

Native app 基本工作原理

這里,只想簡單的描述下。

Windows的設(shè)計(jì)是基于分層模型的,在設(shè)計(jì)之初,內(nèi)核NT支持三個(gè)子系統(tǒng),OS/2,posix,win32,

這些子系統(tǒng)同屬于一個(gè)層面上,它們公用windows nt提供的系統(tǒng)API和例程。其中,在某一個(gè)子系統(tǒng)上的API調(diào)用,

都會(huì)經(jīng)過NT”native”API同windowsNT進(jìn)行通信。這些native API就是ntdll.dll導(dǎo)出的函數(shù),

因?yàn)樗鼘?dǎo)出的大部分函數(shù)都只是起一個(gè)從子系統(tǒng)到NT內(nèi)核的轉(zhuǎn)發(fā)傳遞作用,所以也成為stub函數(shù),

這些函數(shù)的原型大多是未公開的,在早期的DDK里會(huì)有相關(guān)的描述,但是現(xiàn)在沒了,

取而代之的是內(nèi)核實(shí)現(xiàn)的zw*,nt*開頭的驅(qū)動(dòng)函數(shù)。這里表明了MS的一個(gè)態(tài)度,

不希望第三方在native app上干涉windows的太多工作,比如,接管了開機(jī)啟動(dòng)系統(tǒng),接管了登錄密碼界面:D.

后來,因?yàn)榉N種歷史原因,對(duì)OS/2和posix子系統(tǒng)的支持逐漸被淡忘。但是這種分層模型仍然存在,

native app就是工作在子系統(tǒng)未啟動(dòng)之前,此時(shí)的系統(tǒng)環(huán)境很純凈,權(quán)限也相對(duì)較高;

另外,對(duì)操作系統(tǒng)來說,支持native app也是一種必須,因?yàn)樵谧酉到y(tǒng)啟動(dòng)之前,

很多功能的程序只能以native app來呈現(xiàn),比如登錄界面,CSRSS~

具體的啟動(dòng)時(shí)機(jī):

Native app由啟動(dòng)會(huì)話管理器(smss.exe)來啟動(dòng),如果想通知smss來執(zhí)行一個(gè)native app程序,

只需要修改一個(gè)注冊(cè)表項(xiàng),smss在每次啟動(dòng)的時(shí)候會(huì)去檢查該項(xiàng),確保該項(xiàng)下面的每個(gè)native app程序依次執(zhí)行。

注冊(cè)表項(xiàng)為:HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute ,

其類型為MULTI_SZ, 又是MS玩的一種字符串類型—多字符串類型,也就是說,

這個(gè)MULTI_SZ字符串包含多個(gè)以\0結(jié)尾的子字符串,而整個(gè)字符串以\0\0結(jié)尾。

在該注冊(cè)表項(xiàng)后面添加要注冊(cè)的native 程序名和參數(shù)就可以了。

關(guān)于native app的更多詳細(xì)介紹,可以參考Mark Russinovich的一篇關(guān)于native的文章。

??????????????????

Native app程序結(jié)構(gòu)

Native app程序結(jié)構(gòu)很簡單,就好像我們寫hello world,需要寫一個(gè)main函數(shù)入口一樣,

native app的入口函數(shù)是NtProcessStartup,形如:

1: void NtProcessStartup( PSTARTUP_ARGUMENT Argument )

其中,參數(shù)PSTARTUP_ARGUMENT是一個(gè)結(jié)構(gòu)體,用來存放傳入?yún)?shù)。

程序退出時(shí),主動(dòng)調(diào)用函數(shù)NtProcessTerminate退出,它不會(huì)像普通應(yīng)用程序一樣一個(gè)返回return就退出了。

基本的結(jié)構(gòu)就是這樣了:

1: void NtProcessStartup( PSTARTUP_ARGUMENT Argument ) 2: ? 3: { 4: ? 5: // do something else 6: ? 7: NtProcessTerminate( NtCurrentProcess(), 0 ); 8: ? 9: } 10: ?

當(dāng)然現(xiàn)在還沒有包含頭文件之類的。

?????????????????????????????

開發(fā)語言及第三方的庫

Native app支持的開發(fā)語言有C/ASM/C++,并且完美的支持C++的類特性,不過要像編寫驅(qū)動(dòng)一樣,

需要重載new,delete等內(nèi)存分配函數(shù)。在內(nèi)存使用上,可以使用兩套接口:堆函數(shù)接口,以及虛擬內(nèi)存函數(shù)接口,

但是根據(jù)我的經(jīng)驗(yàn),使用堆函數(shù)接口,更高效并且內(nèi)存bug出現(xiàn)的頻率會(huì)大大降低。

舉個(gè)例子:我在調(diào)試native app的時(shí)候,一切正常,且全部通過,但是雙機(jī)調(diào)試的時(shí)候,

功能代碼都運(yùn)行完了,在子系統(tǒng)起來的時(shí)候,提示memory_corruption錯(cuò)誤,

這個(gè)問題整整找了好幾天都沒有找到,到最后,無意間屏蔽掉了系統(tǒng)的DbgPrint函數(shù),memory錯(cuò)誤才解決。

其原因是,native gui圖形模塊的debug消息打印的太快太頻繁,導(dǎo)致調(diào)試緩沖被溢出,

當(dāng)屏蔽了系統(tǒng)DbgPrint的時(shí)候,也就是在windbg 下bp DbgPrint,然后a eip,ret后,就正常了。

雖然這個(gè)現(xiàn)象和程序無關(guān),但是,用了虛擬內(nèi)存的話,這個(gè)問題會(huì)更加容易重現(xiàn)。關(guān)于這個(gè)問題的重現(xiàn)很容易,

就是在native 環(huán)境下雙機(jī)調(diào)試,target機(jī)器一直打印消息,當(dāng)打印到10W條以上時(shí),調(diào)試緩沖就“爆”了。

這真不知道是ms的bug,還是自己~~

??????????????????????

關(guān)于 new, delete 的重載。

使用堆函數(shù)過程如下:首先創(chuàng)建一個(gè)全局堆,然后在這個(gè)全局堆上分配和釋放局部堆。

1: HANDLE hGlobalHeap = NULL; // for globle call 2: ? 3: void* __cdecl operator new(size_t size) 4: ? 5: { 6: if(hGlobalHeap == NULL) 7: return NULL; 8: return RtlAllocateHeap(hGlobalHeap,0/*HEAP_ZERO_MEMORY*/,size); 9: } 10: ? 11: void __cdecl operator delete(void* addr) 12: ? 13: { 14: if(hGlobalHeap && addr) (void)RtlFreeHeap(hGlobalHeap,0,addr); 15: } 16: ?

??????????

關(guān)于 NDK:前面說到,native app用的是ntdll.dll的導(dǎo)出函數(shù),而這些函數(shù)MS并沒有公開接口聲明,

那么我們使用的時(shí)候,首先必須要自己定義函數(shù)聲明。

NDK就是這樣的一個(gè)類庫,它幾乎定義了ntdll.dll導(dǎo)出的全部函數(shù)的聲明以及一些常用的數(shù)據(jù)結(jié)構(gòu)的定義,

我們只需要包含相應(yīng)的頭文件,導(dǎo)入ntdll.lib庫,就可以像使用普通的API函數(shù)一樣開發(fā)native app了。

關(guān)于DLL:native app可以調(diào)用同一級(jí)別的DLL,使大型的項(xiàng)目開發(fā)更加容易,更加容易劃分模塊。

注意,DLL的編譯環(huán)境要和native app一致。

關(guān)于native app的編譯:可以選擇用vs環(huán)境,也可以用DDK/WDK,但是推薦使用WDK。

用VS環(huán)境的話,需要簡單的設(shè)置下,隨意創(chuàng)建一個(gè)類型的工程,然后修改Linker->system->Native,

就可以了。如果用WDK編譯,需要寫一個(gè)SOURCE模板,如:

1: TARGETNAME=defrag 2: ? 3: TARGETPATH=obj 4: ? 5: TARGETTYPE=PROGRAM 6: ? 7: INCLUDES=$(PUBLIC_ROOT)\inc\ddk 8: ? 9: SOURCES=defrag.cpp 10: ?

注意:上面說的DLL的編譯環(huán)境和native app的編譯環(huán)境要一致,

指的是不要用WDK編譯的native去嘗試鏈接VS編譯的DLL,反之亦然。

1: //NTSTATUS NTAPI NtDisplayString( PUNICODE_STRING String);

Native GUI???????????????

在native app執(zhí)行環(huán)境下畫界面是不可行的,但是不是說做不到。

前面說了,可以寫一個(gè)native app來接管windows的啟動(dòng)界面和密碼輸入界面,那么這個(gè)界面是如何畫的呢?

也有從驅(qū)動(dòng)里實(shí)現(xiàn)的。但是,事實(shí)上,MS提供了一個(gè)native級(jí)別的動(dòng)態(tài)庫,名為:Bootvid.dll,

用來實(shí)現(xiàn)GUI啟動(dòng)屏幕的引導(dǎo)視頻驅(qū)動(dòng),這個(gè)dll導(dǎo)出了一些函數(shù),可以實(shí)現(xiàn)畫圖,貼圖功能,

當(dāng)然,這些函數(shù)接口仍然是未公開的。呵呵~

另外,在native app程序,可以利用一個(gè)函數(shù)向屏幕打印輸出字符串,名為:

但是,事實(shí)上,這個(gè)函數(shù)已經(jīng)不推薦使用了,

在用WDK編譯native app的時(shí)候,會(huì)提示一個(gè)警告信息,deprecated~~

???????????

Native app的靈活性

native app由于受到調(diào)用函數(shù)接口未公開,以及開發(fā)難度和調(diào)試難度不小的原因,很少有項(xiàng)目問津,

但是,事實(shí)上,它仍然是一種工作于ring3的用戶態(tài)程序,只是在子系統(tǒng)啟動(dòng)之前運(yùn)行,

所以,native app程序一般不會(huì)引起系統(tǒng)藍(lán)屏的問題。

也正是如此,native 程序工作在一個(gè)相對(duì)純凈的環(huán)境下,可以訪問任何文件,甚至搬移MFT,系統(tǒng)元文件等。

Ntdll.dll為native app導(dǎo)出的函數(shù)雖少,但是可以完成很多的功能。

這些導(dǎo)出函數(shù),基本上和內(nèi)核的系統(tǒng)例程都是一一對(duì)應(yīng)的。結(jié)合其他的模塊,driver,應(yīng)用程app,

在加之native獨(dú)特的運(yùn)行環(huán)境和執(zhí)行能力,往往會(huì)達(dá)到一個(gè)良好的效果。在這里,僅僅是一個(gè)普及~

?????????

具體應(yīng)用及實(shí)例

在開發(fā)native app之前,我想,最好有開發(fā)驅(qū)動(dòng)的基礎(chǔ)。因?yàn)閚ative app程序的編寫規(guī)范基本上和驅(qū)動(dòng)一樣,

除了入口函數(shù),調(diào)試方法也一樣,必須要雙機(jī)調(diào)試。當(dāng)然,只是說編寫規(guī)則一樣,驅(qū)動(dòng)特有的函數(shù)例程以及工作原理,

二者是毫不相干的。舉個(gè)例子,操作注冊(cè)表,文件IO,線程創(chuàng)建,內(nèi)存使用,二者基本上是一致的,具體的在使用中自己體會(huì)吧。

??????????

作為入門例子

作為入門我想還是用Mark Russinovich的例子吧,就好像Hello World的作用一樣,

讓你真切的感受下native app程序。該程序在系統(tǒng)啟動(dòng)時(shí),藍(lán)屏界面上輸出一行字符串信息。

程序在附件,沒什么過多的需要解釋的。

??????????

實(shí)際開發(fā)

實(shí)際開發(fā)中,有不少的應(yīng)用例子。比如,影子系統(tǒng)的啟動(dòng)界面,PQ分區(qū)工具,

win系統(tǒng)自帶的chkdsk工具,都屬于這類程序。下面說下自己的一些經(jīng)歷吧:

項(xiàng)目中有個(gè)需要,對(duì)特定文件進(jìn)行磁盤整理。我們知道,文件系統(tǒng)導(dǎo)出了一組函數(shù)接口,

用于對(duì)磁盤上的文件進(jìn)行搬移操作,使文件內(nèi)碎片和外碎片減少,提高IO吞吐率和磁盤訪問率。

唯一的限制是,pagefile.sys和日志文件不能整理,其他的文件,如MFT,系統(tǒng)元文件都可以整理。

對(duì)于文件整理,更重要的是算法和穩(wěn)定法,當(dāng)然,這是另外一個(gè)話題了。

根據(jù)prefreth原理,一個(gè)應(yīng)用程序的工作集頁面在運(yùn)行時(shí)基本上是趨于穩(wěn)定的,

那么這些穩(wěn)定的頁面如果位于不同的文件(可能是鏈接庫之類),且這些文件在磁盤上比較分散,

那么就會(huì)影響程序的啟動(dòng)時(shí)間了,雖然prefretch做了改善,會(huì)自動(dòng)的激發(fā)系統(tǒng)的磁盤整理來對(duì)“相關(guān)”的文件緊密排放,

但仍然是不夠的。所以,關(guān)于這種性能的改善看起來微乎其微,但是做好了,價(jià)值是不可估量的。

這僅僅是一個(gè)方面,當(dāng)然,項(xiàng)目中的主要目的并不是這個(gè),雖然也是為了提高性能。

在native app下操作文件,考慮的情況是比較單一的,不會(huì)擔(dān)心文件或目錄被鎖,

從而出現(xiàn)不能訪問的情況,也不會(huì)考慮過多的并發(fā)問題。

所以,功能會(huì)更加集中,運(yùn)行效率會(huì)更高,操作的空間和權(quán)限也更大。

僅限于此,就到這吧 ~

???????????

????????

7. 小結(jié):

??????????

上面的文字呢就大體的把 Native Application 給介紹的差不多了,

主要是總結(jié)了一下自己關(guān)于 Native Application 的理解,

然后再將 MJ0011 和互聯(lián)網(wǎng)上的幾位博主的文章給整理了一下(原博文排版不怎么好),

這里對(duì) MJ0011 以及所整理的文章的博主表示感謝 ~

博文中的 Demo 我是采用的 DDK 2600.1106 編譯的,至于 WDK 7 的話,我沒有去試哦 ~

有興趣的可以直接下載了 Demo 進(jìn)行測試的,代碼什么的都在里面,

source 和 makefile 我也都整理好了放在 Demo 中 ~

???????

最后還是和以往一樣,給出些我近來的一些疑問:

我曾經(jīng)從一臺(tái)電腦 A 上下載了卡巴斯基的試用版,然后我將這個(gè)試用版的安裝文件拷貝到了電腦 B 上,

這時(shí)我發(fā)現(xiàn)卡巴斯基的這個(gè)安裝文件在電腦 B 上是無法運(yùn)行的 ~ 直接報(bào)錯(cuò),

當(dāng)然,這個(gè)安裝文件在電腦 A 上是可以運(yùn)行安裝的,

我想應(yīng)該是卡巴斯基的這個(gè)安裝文件在拷貝的過程中還是下載的過程中記錄下了我的電腦 A,

然后在安裝的時(shí)候,其自動(dòng)判斷是否是在電腦 A 上安裝運(yùn)行,

如果是的話,則可以成功安裝,如果不是,則直接報(bào)錯(cuò) ~

我想知道上面是怎么來實(shí)現(xiàn)的呢 ? 我只是下載和拷貝了一下哦 ~

????????????????

還有就是貌似要考個(gè)微軟的 MCTS 證書,

應(yīng)該是 Windows 方向的 71-511 或者 Web 方向的 71-515 這兩門考試,

不曉得大伙有什么好建議或者好的資料沒有哦 ~ 可否提供一些呢 ~ 謝謝咯 ~

????

然后再問一下哦,有沒有湖南婁底的啊 ? 國慶組隊(duì)回去否 ?(我在深圳 ~)

????????????

下載 Demo?Source Code

總結(jié)

以上是生活随笔為你收集整理的Native Application 开发详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。