久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

使用TDI與WinSock進行客戶端服務(wù)器編程

 夢醉千秋 2013-11-21
37 默認 【原創(chuàng)】使用TDI與WinSock進行客戶端服務(wù)器編程
Cryin 當前離線

標 題: 【原創(chuàng)】使用TDI與WinSock進行客戶端服務(wù)器編程
作 者: Cryin
時 間: 2010-12-24,18:47:37
鏈 接: http://bbs./showthread.php?t=127069


題目:使用TDI與WinSock進行客戶端服務(wù)器編程
日期:2010年12月24日
作者:Cryin' (http://hi.baidu.com/justear)

簡介:

在本文中,,您將了解到使用傳輸驅(qū)動程序接口TDI與應(yīng)用層套接字WinSock客戶端服務(wù)器應(yīng)用程序內(nèi)核級編程實現(xiàn)細節(jié)。介紹常用的TDI函數(shù)并提供編寫TDI與WinSock(TCP)應(yīng)用程序的詳細說明,。最后還提供了源代碼以演示編寫程序的步驟,。

開始之前:

在開始學(xué)習本文內(nèi)容之前,假設(shè)讀者以具備以下基礎(chǔ):
   Windows 內(nèi)核級編程的知識和經(jīng)驗
   網(wǎng)絡(luò)編程概念及應(yīng)用層Socket編程經(jīng)驗
   了解并安裝有Microsoft DDK

WinSock(服務(wù)器):

應(yīng)用層套接字編程流程比較簡單,,這里簡單介紹:
   加載套接字庫并創(chuàng)建Socket(socket())
   綁定套接字到指定端口和IP(bind())
   設(shè)置套接字進行監(jiān)聽以等待連接請求(listen())
   接受連接請求(accept())
   發(fā)送或接收信息(send()/recv())
   關(guān)閉套接字(closesocket())   

TDI(客戶端):

TDI 定義在傳輸協(xié)議棧中較高級別公開的內(nèi)核模式網(wǎng)絡(luò)接口,,如下圖:
名稱:  圖片1.png
查看次數(shù): 254
文件大小:  33.7 kb
圖:傳輸協(xié)議棧
TDI應(yīng)用程序可以分為兩種類型,與基于Socket的應(yīng)用程序類似:
   面向連接(使用TCP協(xié)議,,通信可靠)
   面向誤連接(使用UDP協(xié)議,,通信不可靠)

常用TDI函數(shù):

這里討論一些比較常用的TDI,以便實現(xiàn)基于傳輸驅(qū)動程序接口TDI與WinSock客戶端服務(wù)器編程。

打開TDI設(shè)備:

VOID  InitializeObjectAttributes(
    OUT POBJECT_ATTRIBUTES  InitializedAttributes,
    IN PUNICODE_STRING  ObjectName,
    IN ULONG  Attributes,
    IN HANDLE  RootDirectory,
    IN PSECURITY_DESCRIPTOR  SecurityDescriptor
  );
所附帶的參數(shù):
InitializedAttributes
  要初始化的OBJECT_ATTRIBUTES結(jié)構(gòu)的指針
ObjectName
  Unicode 設(shè)備名稱,,對于無連接的情況為 device\UDP,,對于本文是面向連接的通信,則為 device\TCP,。此 ObjectName必須為 Unicode 字符串,。該 Unicode 字符串可以使用 RtlInitUnicodeString 庫調(diào)用進行初始化。
Attributes
  只需填寫為OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE即可
RootDirectory
  此處為NULL
SecurityDescriptor
  設(shè)置安全描述符,。由于筆者總是打開內(nèi)核句柄,,所以很少設(shè)置這個參數(shù)
  
  接下來需要打開本地傳輸?shù)刂返奈募ο螅蛻舳藨?yīng)用程序必須調(diào)用ZwCreateFile函數(shù)并在擴展屬性中傳遞此地址。當ZwCreateFile成功調(diào)用時,,將返回傳輸文件(表示連接端點)的句柄,。客戶端必須調(diào)用ObReferenceObjectByHandle函數(shù),,該函數(shù)將返回相應(yīng)的傳輸文件對象,。該傳輸文件對象將用于向遠程服務(wù)端發(fā)送數(shù)據(jù)或接收數(shù)據(jù)。此外客戶端必須事件處理例程以接收各種網(wǎng)絡(luò)事件,,如接收數(shù)據(jù)、斷開連接,、錯誤等,。
NTSTATUS ObReferenceObjectByHandle(
    IN HANDLE  Handle,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_TYPE  ObjectType  OPTIONAL,
    IN KPROCESSOR_MODE  AccessMode,
    OUT PVOID  *Object,
    OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
  );
所附帶的參數(shù): 
Handle 
  為對象指定一個打開句柄。此句柄由 ZwCreateFile 返回,。 
DesiredAccess 
  指定所請求的對象訪問權(quán)限類型,。此字段的解釋取決于對象類型。 
ObjectType 
  指向?qū)ο箢愋偷闹羔???梢詾?nbsp;*IoFileObjectType 或 *ExEventObjectType。如果   AccessMode 為 KernelMode,,此參數(shù)可以為 NULL,。 
AccessMode 
  指定要為訪問檢查使用的訪問模式。必須為 UserMode 或 KernelMode,。對于底層驅(qū)動  程序,,應(yīng)指定 KernelMode。 
Object 
  指向接收對象指針的變量,。 
HandleInformation 
  驅(qū)動程序會將此參數(shù)設(shè)置為 NULL,。 
  
VOID KeInitializeEvent(
    IN PRKEVENT  Event,
    IN EVENT_TYPE  Type,
    IN BOOLEAN  State
  );
所附帶的參數(shù):
Event
  指向事件對象地址的指針
Type
  事件類型,NotificationEvent 或者SynchronizationEvent
State
  事件初始化信號狀態(tài)
  
IoSetCompletionRoutine函數(shù)將向基礎(chǔ)驅(qū)動程序注冊回調(diào)函數(shù),,以在鏈中底層驅(qū)動程序完成了對 IRP 的請求時進行調(diào)用,。將在 IRP 完成(成功或失敗)和取消 IRP 請求時調(diào)用回調(diào)例程,。
VOID IoSetCompletionRoutine(
    IN PIRP  Irp,
    IN PIO_COMPLETION_ROUTINE  CompletionRoutine,
    IN PVOID  Context,
    IN BOOLEAN    InvokeOnSuccess,
    IN BOOLEAN  InvokeOnError,
    IN BOOLEAN  InvokeOnCancel
  );
所附帶的參數(shù): 
Irp 
  指向驅(qū)動程序希望跟蹤的 IRP 的指針 
CompletionRoutine 
  指定驅(qū)動程序提供的 IoCompletion 例程(更低層的驅(qū)動程序完成數(shù)據(jù)包時調(diào)用)的入  口點
Context 
  指向驅(qū)動程序確定的上下文的指針,,以將該上下文傳遞給 IoCompletion 例程 
InvokeOnSuccess 
  指定如果 IRP 完成,且 IRP 的 IO_STATUS_BLOCK 結(jié)構(gòu)中包含成功狀態(tài)值,,是否  基于 NT_SUCCESS 宏(在 ntdef.h 中定義)的結(jié)果調(diào)用完成例程 
InvokeOnError 
  指定如果 IRP 完成,,且 IRP 的 IO_STATUS_BLOCK 結(jié)構(gòu)中非成功狀態(tài)值,是否調(diào)  用完成例程
InvokeOnCancel 
  指定如果驅(qū)動程序或內(nèi)核調(diào)用 IoCancelIrp 來取消 IRP,,是否調(diào)用完成例程
  
IoAllocateMdl 函數(shù)用于分配 MDL 結(jié)構(gòu),,該結(jié)構(gòu)足夠?qū)μ峁┑木彌_區(qū)進行映射。驅(qū)動程序間傳輸?shù)臄?shù)據(jù)均采用 MDL 結(jié)構(gòu)的形式。驅(qū)動程序應(yīng)使用此函數(shù)分配的 MDL 調(diào)用 MmBuildMdlForNonPagedPool 以從非分頁池建立 MDL,。此外,,還可以選擇將此函數(shù)與具有 IRP 的 MDL 關(guān)聯(lián)(如果傳遞了此 IRP)。
PMDL IoAllocateMdl(
    IN PVOID  VirtualAddress,
    IN ULONG  Length,
    IN BOOLEAN  SecondaryBuffer,
    IN BOOLEAN  ChargeQuota,
    IN OUT PIRP  Irp  OPTIONAL ); 
所附帶的參數(shù): 
VirtualAddress 
  指向 MDL 要描述的緩沖區(qū)的虛擬基地址的指針 
Length 
  指定 MDL 要描述的緩沖區(qū)的長度(以字節(jié)為單位),。此值必須小于以下公式的計算值:   PAGE_SIZE * (65535 - sizeof
  (MDL)) / sizeof(ULONG_PTR) 
SecondaryBuffer 
  指示緩沖區(qū)是主緩沖區(qū)還是次緩沖區(qū),。確定 MDL 如何鏈接到 IRP。IRP 中除 MDL 描  述的第一個緩沖區(qū)外的所有緩沖區(qū)均被視為次緩沖區(qū),。如果沒有與 MDL 關(guān)聯(lián)的 IRP,,  此字段必須為 FALSE 
ChargeQuota 
  應(yīng)由中間驅(qū)動程序設(shè)置為 FALSE。只有特定的高層驅(qū)動程序才能將此值設(shè)置為   TRUE,,應(yīng)在發(fā)出 I/O 請求以分配另一個 IRP 線程的上下文中調(diào)用此類驅(qū)動程序,。 
  Irp 指向與 MDL 關(guān)聯(lián)的 IRP 的指針。如果 Irp 指針非空,,所分配的 MDL 將根據(jù)   SecondaryBuffer 的值與指定的 IRP 的 MDL 列表關(guān)聯(lián)

IoCallDriver 會在進行調(diào)用時將經(jīng)過格式化的 IRP 請求傳遞給基礎(chǔ)驅(qū)動程序(按照在設(shè)備對象指定的方式),。在調(diào)用此函數(shù)前,調(diào)用驅(qū)動程序必須為目標驅(qū)動程序設(shè)置 I/O 堆棧位置,。(有關(guān)更多信息,,請參閱 DDK 幫助中關(guān)于將 IRP 傳遞到驅(qū)動程序棧的內(nèi)容。)調(diào)用方必須檢查返回值,,以確保已由較低層的驅(qū)動程序完成了 IRP 請求,。如果返回值不是 SUCCESS,則調(diào)用方在繼續(xù)下一個任務(wù)之前,,必須等待相應(yīng)的事件,。
NTSTATUS IoCallDriver(
    IN PDEVICE_OBJECT  DeviceObject,
    IN OUT PIRP  Irp ); 
所附帶的參數(shù): 
DeviceObject 
  指向設(shè)備對象的指針,該對象表示所請求的 I/O 操作的目標設(shè)備
Irp 
  指向 IRP 的指針 
返回值
  IoCallDriver 返回較低層驅(qū)動程序在給定請求的 IO 狀態(tài)塊中設(shè)置的 NTSTATUS 值,;  或者,,如果請求在排隊進行進一步處理,則返回 STATUS_PENDING

PIRP TdiBuildInternalDeviceControlIrp(
    IN CCHAR  IrpSubFunction,
    IN PDEVICE_OBJECT  DeviceObject,
    IN PFILE_OBJECT  FileObject,
    IN PKEVENT  Event,
    IN PIO_STATUS_BLOCK  IoStatusBlock
    );
所附帶的參數(shù):
IrpSubFunction
  返回與制定參數(shù)對應(yīng)的后面要處理的IRP,,參數(shù)可以為以下值:
  TDI_ASSOCIATE_ADDRESS 
  The caller will pass the returned IRP to TdiBuildAssociateAddress. 
  TDI_DISASSOCIATE_ADDRESS 
  The caller will pass the returned IRP to TdiBuildDisassociateAddress. 
  TDI_CONNECT 
  The caller will pass the returned IRP to TdiBuildConnect. 
  TDI_LISTEN 
  The caller will pass the returned IRP to TdiBuildListen. 
  TDI_ACCEPT 
  The caller will pass the returned IRP to TdiBuildAccept. 
  TDI_DISCONNECT 
  The caller will pass the returned IRP to TdiBuildDisconnect. 
  TDI_SEND 
  The caller will pass the returned IRP to TdiBuildSend. 
  TDI_RECEIVE 
  The caller will pass the returned IRP to TdiBuildReceive. 
  TDI_SEND_DATAGRAM 
  The caller will pass the returned IRP to TdiBuildSendDatagram. 
  TDI_RECEIVE_DATAGRAM 
  The caller will pass the returned IRP to TdiBuildReceiveDatagram. 
  TDI_SET_EVENT_HANDLER 
  The caller will pass the returned IRP to TdiBuildSetEventHandler. 
  TDI_QUERY_INFORMATION 
  The caller will pass the returned IRP to TdiBuildQueryInformation. 
  TDI_SET_INFORMATION 
  The caller will pass the returned IRP to TdiBuildSetInformation. 
  TDI_ACTION 
  The caller will pass the returned IRP to TdiBuildAction. 
DeviceObject
  設(shè)備對象
FileObject
  由ObReferenceObjectByHandle指定的FileObject
Event
  事件指針
IoStatusBlock
  指向IO_STATUS_BLOCK對象的指針

編寫TDI客戶端的還需要用到的函數(shù)有:
   建立連接TdiBuildConnect
   發(fā)送信息TdiBuildSend
   接收信息TdiBuildReceive
   關(guān)閉連接TdiBuildDisconnect
有關(guān)更多TDI的函數(shù),,請參考MSDN。實例截圖:
名稱:  圖片2.png
查看次數(shù): 253
文件大小:  125.6 kb
圖:使用TDI與WinSock進行客戶端服務(wù)器編程效果圖
實例代碼:
  Winsock服務(wù)端編譯環(huán)境:Microsoft Visual C++ 6.0
  TDI客戶端編譯環(huán)境:WDK 7600.16385.0
  測試環(huán)境:Windows XP SP3
  源代碼下載:http://code.google.com/p/tdiwinsockcommunication/
參考文獻:
  http://www.ibm.com/developerworks/cn...resources.html
  Professional.Rootkits

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多