驅動開發:設定Visual Studio驅動開發環境

2023-03-13 15:00:17

在正式開始驅動開發之前,需要自行搭建驅動開發的必要環境,首先我們需要安裝Visual Studio 2013這款功能強大的程式開發工具,在課件內請雙擊ISO檔案並執行內部的vs_ultimate.exe安裝包,Visual Studio的安裝非常的簡單,您只需要按照提示全部選擇預設引數即可,根據機器設定不同可能需要等待一段時間;

設定驅動開發環境

在正式開始驅動開發之前,需要自行搭建驅動開發的必要環境,首先我們需要安裝Visual Studio 2013這款功能強大的程式開發工具,在課件內請雙擊ISO檔案並執行內部的vs_ultimate.exe安裝包,Visual Studio的安裝非常的簡單,您只需要按照提示全部選擇預設引數即可,根據機器設定不同可能需要等待一段時間;

接著讀者還需要繼續安裝Windows Driver Kit 8.1工具包,請將該工具包解壓縮到桌面,並雙擊wdksetup.exe進行安裝,過程中只需要一直下一步,並等待WDK工具包安裝完成;

WDK就是核心程式設計開發工具包,某些讀者可能聽說過DDK或者IFSDDK,最典型的開發工具包莫過於DDK7600,直到目前此類工具包仍然可以正常使用,但並不推薦。

為了能測試驅動程式執行狀態,讀者需安裝VMWare虛擬機器器,雙擊附件中的VMware-workstation-full-16.2.4-20089737.exe安裝程式一直點選下一步即可,需要注意的是在如下選項中請在增強型鍵盤驅動程式上打對勾,之後等待安裝完畢即可;

接著開啟VMware虛擬機器器,並在【檔案】處選擇【新建虛擬機器器】,單機下一步並選中【稍後安裝作業系統】,在作業系統選擇頁面選擇【Win10 x64】版本。

在硬體設定處,讀者可根據自己電腦的設定靈活的選擇,當自定義設定完成後,則虛擬機器器模板將被建立。

虛擬機器器模板建立完成後,讀者可根據如下設定選擇編輯虛擬機器器設定,並在磁碟位置處將課件中的cn_windows_10_consumer_editions_version_1903_x64_dvd_8f05241d.iso掛載到虛擬機器器上;

點選開啟虛擬機器器,並按照提示將Windows系統正確的安裝,需要注意的是在選擇版本時,讀者最好使用教育版與筆者開發環境保持一致,至此只需等待系統安裝完畢,根據系統差異安裝時間可能有所差別,耐性等待即可;

當一切安裝就緒後我們需要在系統中安裝VMware Tools工具,該元件在安裝後可讓虛擬機器器具備有拖拽上傳檔案的功能,且滑鼠鍵盤將可以自由切換,該功能是我們必須要用到的;

安裝VMware Tools工具很容易,只需要點選安裝選單,後會在虛擬機器器中出現DVD驅動器,此時雙擊驅動器並按照要求安裝即可,安裝完成後重啟系統,此時則具備了拖拽上傳功能;

當這些都做好以後,建議使用者關閉虛擬機器器,並點選【虛擬機器器】選單,找到【快照】並拍攝一個快照,快照的作用是當虛擬機器器系統出現問題後可快速恢復到初始模式,避免重灌系統,在後續課程中讀者會出現無數次的藍屏,而虛擬機器器快照的快速恢復功能則是一個很好的選擇;

設定驅動開發模板

1.開啟Visual Studio開發工具,然後選擇【檔案】選單新建專案,並在已安裝模板中選中【Visual C++】新建空專案,並將專案名稱命名為【WinDDK】點選確定。

2.依次選擇【解決方案檢視-原始檔-新增新建項】索引標籤,或者直接按下Ctrl + Shift + A快捷開啟選單,並建立main.c檔案。

3.接著需要修改設定管理器,新增自定義設定管理,選擇【生成-設定管理器-新建】索引標籤,此處我們命名為WinDDK即可。

4.修改設定屬性中的【常規】屬性,點選選單欄中的偵錯,選擇【WinDDK屬性-設定-常規】修改為標黃處所示內容即可。

5.設定可執行檔案路徑與匯入庫路徑,這裡我們選擇【設定屬性-VC++目錄】依次將如下資訊填入設定項。

可執行目錄
C:\Program Files (x86)\Windows Kits\8.1\bin\x64
C:\Program Files (x86)\Windows Kits\8.1\bin

包含目錄
C:\Program Files (x86)\Windows Kits\8.1\Include\km
C:\Program Files (x86)\Windows Kits\8.1\Include\shared
C:\Program Files (x86)\Windows Kits\8.1\Include\um
C:\Program Files (x86)\Windows Kits\8.1\Include\wdf\kmdf\1.13
C:\Program Files (x86)\Windows Kits\8.1\Include\wdf\umdf\2.0
C:\Program Files (x86)\Windows Kits\8.1\Include\winrt

參照目錄
C:\Program Files (x86)\Windows Kits\8.1\Lib\win7\km\x64

庫目錄
C:\Program Files (x86)\Windows Kits\8.1\Lib\win7\km\x64
C:\Program Files (x86)\Windows Kits\8.1\Lib\wdf\kmdf\x64\1.13
C:\Program Files (x86)\Windows Kits\8.1\Lib\wdf\umdf\x64\2.0
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\km\x64

當如上檔案設定完成後,最終效果如下圖所示;

6.設定C/C++優化選項,在設定屬性中找到【C/C++-所有選項】並依次修改下方几個關鍵位置。

安全檢查         禁用安全檢查 (/GS-)
將警告視為錯誤    否 (/WX-)
警告等級         關閉所有警告
啟用C++異常      否
呼叫約定         __fastcall (/Gr)
優化            已禁用 (/Od)
執行庫          多執行緒 (/MT)
前處理器定義     _AMD64_;_DDK_;_WIN32_WINNT=0x0501;WINVER=0x0501;_NDEBUG;DBG=0;%(PreprocessorDefinitions)

當如上檔案設定完成後,最終效果如下圖所示;

7.設定聯結器選項,選擇【聯結器-所有選項】依次修改下方几個關鍵位置。

附加選項            /IGNORE:4078 /safeseh:no
附加依賴項          ntoskrnl.lib;ndis.lib;Hal.lib;wdm.lib;wdmsec.lib;wmilib.lib
固定基址            此處需要清空
忽略所有預設庫      是 (/NODEFAULTLIB)
啟用增量連結        否 (/INCREMENTAL:NO)
驅動程式            驅動程式 (/Driver)
入口點              DriverEntry
生成清單            否 (/MANIFEST:NO)
生成偵錯資訊        是 (/DEBUG)
生成對映檔案        是 (/MAP)
系統記憶體保護        是 (/NXCOMPAT)
隨機基址           此處需要清空
子系統             本機 (/SUBSYSTEM:NATIVE)

當如上檔案設定完成後,最終效果如下圖所示;

8.上方的設定已經基本完成了,接著我們編寫一段驅動初始化程式碼,然後按下F7即可完成驅動的編譯。

// 署名權
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: [email protected]

#include <ntifs.h>

// 解除安裝驅動
NTSTATUS UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver Is OK \n");
	return STATUS_SUCCESS;
}

// 驅動入口地址
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("Hello LyShark \n");
	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

9.最後生成一個驅動開發模板,依次選擇【檔案-匯出模板-專案模板-下一步-完成】即可完成模板的匯出,此時關閉VS工具並再次開啟,就能直接使用我們的模板來開發驅動了,當用戶需要使用時,不需要每次都設定。

  • 模板位置:C:\Users\admin\Documents\Visual Studio 2013\My Exported Templates

讀者也應注意,如果使用者通過模板建立驅動開發專案則需要手動在設定選單中切換到WinDDK選項的x64模式下。

設定驅動雙機偵錯

1.首先需要在VMware虛擬機器器關閉狀態下新增一個管道虛擬串列埠,此處需要刪除印表機,否則串列埠之間衝突。

操作步驟:編輯虛擬機器器設定 -> 新增 -> 串列埠 -> 完成
引數設定:使用命名管道 -> \\.\pipe\com_1 -> 該端是伺服器,另一端是應用程式 -> 輪詢時主動放棄CPU->確定

2.開啟虛擬機器器中的Windows系統,然後以管理員身份執行CMD命令列,輸入bcdedit命令,可以檢視到系統的當前啟動項,如果是新的系統,則只會有{current}啟動項以及一個{bootmgr}項。

連續執行下方的七條命令,依次建立啟動項,啟用Windows系統的偵錯模式,並開啟串列埠通訊,偵錯埠波特率為115200

bcdedit /set testsigning on
bcdedit -debug on
bcdedit /bootdebug on
bcdedit /set "{current}" bootmenupolicy Legacy             // 修改啟動方式為Legacy
bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200    // 設定串列埠1為偵錯埠波特率為115200
bcdedit /copy "{current}" /d "Debug"                       // 將當前設定複製到Debug啟動設定
bcdedit /debug "{<新建的啟動設定的識別符號>}" on               // 開啟偵錯開關

但需要注意{<新建的啟動設定的識別符號>}需替換成{bdb0b3b6-3f21-11ed-9931-d46011246f28}標誌,如下所示。

3.最後檢視一下當前偵錯設定選項,執行命令 bcdedit /dbgsettings,顯示出使用的第一個串列埠,波特率為115200bps,保持預設不需要修改。

4.設定完成後,重新啟動系統,在開機的時候選擇Windows10 [啟用偵錯程式]則系統會黑畫面,說明已經正常進入偵錯模式了。

5.此時回到物理機上面,解壓縮課件中的WinDBG_10.0.16299.15.zip到D槽根目錄下,我們在命令列中切換到WinDBG\x64的根目錄下,並執行以下命令,即可連線虛擬機器器串列埠進行偵錯了。

  • 執行命令 windbg.exe -b -k com:port=\\.\pipe\com_1,baud=115200,pipe 如下圖

6.至此我們還需要載入符號,符號的作用是方便我們偵錯,該符號是由微軟官方維護的權威資料,在命令列下依次執行以下命令,設定好符號載入並啟動系統。

kd> .sympath SRV*c:\mySymbols*http://msdl.microsoft.com/download/symbols
kd> .reload
kd> g
kd> g
kd> ed nt!Kd_SXS_Mask 0
kd> ed nt!Kd_FUSION_Mask 0
kd> u KiSystemServiceUser

這樣即可完成設定操作,此時系統已被斷下等待我們執行操作,如下圖所示。

7.最後我們設定測試一下偵錯功能,首先編寫以下程式碼,程式碼中使用DbgBreakPoint()設定斷點,將會在入口處中斷。

// 署名權
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: [email protected]

#include <ntifs.h>

// 驅動預設回撥
NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return status;
}

// 驅動解除安裝函數
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("驅動已解除安裝 \n");
}

// 驅動入口地址
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	// 初始化預設派遣函數
	NTSTATUS status = STATUS_SUCCESS;
	for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
	{
		Driver->MajorFunction[i] = DriverDefaultHandle;
	}

	// 設定斷點
	DbgBreakPoint();
	// KdBreakPoint();
	// __debugbreak();

	DbgPrint("驅動已載入 \n");

	// 驅動解除安裝函數
	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

通過Visual Studio工具編譯如上程式碼片段,並在WinDBG中輸入g命令讓系統執行起來,將編譯好的驅動程式拖入到虛擬機器器中,並以管理員身份開啟Windows 64Signer.exe,使用該工具對驅動程式進行簽名,如下圖所示;

簽名完成後將我們的驅動檔案WinDDK.sys,拖入到KmdManager.exe驅動載入工具中,並通過驅動載入工具載入執行,此時Windows系統會卡死,回到WinDBG中發現已經可以進行偵錯了,如下圖所示;

此處需要擴充套件一個知識點,如果不使用WinDBG工具而想要獲取到DbgPrint()函數輸出結果,則你可以使用課件中提供的dbgview64.exe程式,不過此程式需要注意幾點,該程式需要使用管理員身份執行,且執行後需要將Capture選單中的屬性全部打對勾,如下圖所示;

此時DebugView會出現很多的無用輸出,則你需要開啟過濾器按鈕,輸入STORMINI將此類輸出遮蔽掉,如下圖所示;

至此再次使用KmdManager工具載入WinDDK驅動,則可以無干擾的輸出我們所需結果。