1. 程式人生 > >【舊文章搬運】無Device的驅動如何通訊

【舊文章搬運】無Device的驅動如何通訊

原文發表於百度空間,2009-07-14
==========================================================================

標準的驅動與ring3的通訊過程是這樣的:
驅動中建立裝置,併為裝置建立符號連結,ring3用CreateFile開啟符號連結得到裝置控制代碼,然後DeviceIoControl傳送ControlCode
DeviceIoControl的內容被封裝成IRP到達Device,Device其所屬Driver的對應派遣例程對IRP進行處理,處理完後IoCompleteRequest完成該IRP最後返回到ring3.
如果有必要的話,還得用Event進行一下同步~

如果沒有Device(甚至還可能沒有DriverObject),這一切該如何進行?
道理其實是很簡單的,我們不要拘泥於某些固定的東西不變,來好好想一想。
先扯點通訊的東西。通訊,就是把資訊從發信者傳送到收信者的過程,資訊傳輸的通道就是通道。
我們的目標是把資訊從ring3傳遞到驅動中去,上面的標準通訊過程,其實只不過是相當於我們自己建立了一個標準通道
沒有Device,只是說不能用標準通道來通訊了,但是還可以有別的通訊方法,只要我們能把資訊從ring3傳遞給驅動,任何方法都可以~~
我來隨便說幾種吧:

一、共享記憶體+Event
ring3用CreateFileMapping建立一塊命名的共享記憶體,還有一個事件物件,ring0中獲取相應的物件,共享記憶體中的內容事先定好格式,比如哪裡是ControlCode,哪裡是InputLength,哪裡是OutputLength,哪裡是InputBuffer,哪裡是OutputBuffer,構成一個簡單的協議包,這其實相當於一個變形的IRP結構~~當需要通訊的時候,ring3將相應的內容寫入共享記憶體,然後設定Event通知驅動,驅動收到後就可以從共享記憶體中取到ControlCode,InputLen,InputBuffer等等資訊,進行相應處理就可以了,處理完後再以Event通知ring3,ring3就可以從OutputBuffer中獲取處理結果了,不過這裡沒有考慮非同步模式,一般自己的驅動也很少用非同步~

二、Hook IopXxxControlFile
NtDeviceIoControlFile直接呼叫IopXxxControlFile進行處理,很容易Hook(Call替換方式hook最好,安全),也沒有SSDT Hook那麼扎眼。Hook該函式最大的好處是你仍然可以使用標準的DeviceIoControl來發送ControlCode和驅動通訊.Hook成功後,可以開啟任意一個Device,比如Beep,,然後就可以用DeviceIoControl傳送ControlCode了,當然ControlCode得有點特殊標記(比如某個特殊標誌位),總之你得能認出來這是你的ring3 App發來的ControlCode就行,然後Hook函式中如果是自己的ControlCode就進行相應處理,否則呼叫原始函式讓系統處理去吧。或者自己使用一個特殊的無效控制代碼(但是要保證能通過檢查到達ring0)來發DeviceIoControl,驅動中檢查此控制代碼是否是某特殊值,是則認為是自已人發的ControlCode,進行處理就OK了。

稍微變形一點,直接Hook掉Beep的IRP_MJ_DEVICE_CONTROL派遣例程,然後ring3直接開啟Beep用DeviceIoControl發ControlCode就行了~~


三、Hook NativeAPI
先舉兩個例子:
HideToolz沒有Device,是使用ZwTerminateProcess來通訊的~
某遊戲的驅動用ZwQueryVirtualMemory來通訊~~
不需要說什麼了吧?NativeAPI都要經過syscall進入ring0,然後可能繼續到達某些XX位置,只要在適當的位置攔截一下取走自己的資訊就行了~
其實只要能把資訊傳遞給驅動,很多API都可以(當然純ring3實現的API不行哦)


方法還有好多好多,標準方法就那麼一兩種,但是非標準的方法有多少種?盡情發揮想像吧~~