成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

網絡安全編程:內核下文件讀寫函數

安全
文件讀寫程序分為4個函數,分別是DriverUnload()、DriverEntry()、CreateFileTest()和OpenFileTest()。

 [[388651]]

文件讀寫程序分為4個函數,分別是DriverUnload()、DriverEntry()、CreateFileTest()和OpenFileTest()。這4個函數的功能非常明確,DriverUnload()是一個卸載例程,DriverEntry()是驅動程序的入口,CreateFileTest()是用來新建文件的,OpenFileTest()是用來打開已建立文件并進行讀寫的函數。

1. 文件的創建、打開與關閉

對于文件的創建或打開,在內核驅動中都是通過內核函數ZwCreateFile()進行操作的。和Win32 API類似,會通過參數接收返回的文件句柄。它的返回值是一個操作是否成功的狀態碼。ZwCreateFile()函數的定義如下: 

  1. NTSTATUS ZwCreateFile(  
  2.  __out PHANDLE FileHandle,  
  3.  __in ACCESS_MASK DesiredAccess,  
  4.  __in POBJECT_ATTRIBUTES ObjectAttributes,  
  5.  __out PIO_STATUS_BLOCK IoStatusBlock,  
  6.  __in_opt PLARGE_INTEGER AllocationSize,  
  7.  __in ULONG FileAttributes,  
  8.  __in ULONG ShareAccess,  
  9.  __in ULONG CreateDisposition,  
  10.  __in ULONG CreateOptions,  
  11.  __in_opt PVOID EaBuffer,  
  12.  __in ULONG EaLength  
  13. );  

參數介紹如下。

FileHandle:用來接收創建文件后的文件句柄。

DesiredAccess:打開文件操作的描述,讀或寫,一般指定為 GENERIC_READ 或 GENERIC_WRITE;該參數和 CreateFile()函數中的參數相同。

ObjectAttributes:指向 OBJECT_ATTRIBUTES 結構體的指針,該結構體包含要創建或打開的文件名。

IoStatusBlock:指向 IO_STATUS_BLOCK 結構體的指針,該結構體用于接收操作結果的狀態。

AllocationSize:該參數指向一個 64 位的整數,用于文件初始化分配時的大小。

FileAttributes:通常為 FILE_ATTRIBUTE_NORMAL,該參數和 CreateFile()函數中的參數相同。

ShareAccess:指定文件的共享方式,可以指定為 FILE_SHARE_READ、FILE_SHARE_WRITE 或 FILE_SHARE_DELETE,該參數和 CreateFile()函數中的參數相同。

CreateDisposition:描述本次調用 ZwCreateFile()函數的意圖,可以指定為 FILE_CREATE、FILE_OPEN、FILE_OPEN_IF 等。

CreateOptions:通常指定為 FILE_SYNCHRONOUS_IO_NONALERT,表示文件是同步操作,比如在寫入文件時,調用 ZwWriteFile()函數,在 ZwWriteFile()調用返回時,文件寫操作已經完成。

EaBuffer:該參數表示一個指針,指向可選的擴展屬性區,一般為 NULL。

EaLength:該參數表示擴展屬性區的長度,一般為 0。

ZwCreateFile()函數的第 3 個參數是一個指向 OBJECT_ATTRIBUTES 的結構體,該結構體的定義如下: 

  1. typedef struct _OBJECT_ATTRIBUTES {  
  2.  ULONG Length;  
  3.  HANDLE RootDirectory;  
  4.  PUNICODE_STRING ObjectName;  
  5.  ULONG Attributes;  
  6.  PVOID SecurityDescriptor;  
  7.  PVOID SecurityQualityOfService;  
  8. } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;  
  9. typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES; 

該結構體通常不需要用戶逐個進行初始化,而是使用InitializeObjectAttributes()函數進行初始化,該函數的定義如下: 

  1. VOID InitializeObjecttAttributes(  
  2.  OUT POBJECT_ATTRIBUTES InitializedAttributes,  
  3.  IN PUNICODE_STRING ObjectName,  
  4.  IN ULONG Attributes,  
  5.  IN HANDLE RootDirectory,  
  6.  IN PSECURITY_DESCRIPTOR SecurityDescriptor  
  7. );  

從InitializeObjectAttributes()函數的定義可以看出,其參數與OBJECT_ATTRIBUTES結構體的成員變量相同。InitializeObjectAttributes()函數的參數說明如下。

InitializeAttributes:指向 OBJECT_ATTRIBUTES 結構體的指針。

ObjectName:對象名稱,用 UNICODE_STRING 描述,對于 ZwCreateFile()函數而言,該處指定為文件名。

Attributes:一般設置為 OBJ_CASE_INSENSITIVE,意味著名字字符串不區分大小寫。

RootDirectory:一般設置為 NULL。

SecurityDescriptor:用于設置安全描述符,一般設置為 NULL。

ObjectName 必須使用 UNICODE_STRING 類型進行描述,UNICODE_STRING 是內核對寬字符串封裝的一種數據結構,該結構體的定義如下: 

  1. typedef struct _UNICODE_STRING {  
  2.  USHORT Length;  
  3.  USHORT MaximumLength;  
  4.  PWSTR Buffer;  
  5. } UNICODE_STRING, *PUNICODE_STRING; 

結構體成員說明如下。

Length:字符串的參數,單位是字節,如果是 N 個字符,那幺 Length 的值為 N 個字符的 2 倍。

MaximumLength:整個字符緩沖區的最大長度,單位是字節。

Buffer:緩沖區的指針。

對于 UNICODE_STRING 類型的字符串,通過 KdPrint()也可以進行調試輸出,輸出的方式類似如下: 

  1. UNICODE_STRING uniString;  
  2. KdPrint(("%wZ", &uniString)); 

UNICODE_STRING類型的字符串在使用前需要進行初始化,初始化的方法有兩種:一種是使用內核函數RtlInitUnicodeString()進行初始化,另一種方式是自行申請內存空間來進行初始化。通常情況下都是用第1種方法。RtlInitUnicodeString()函數的定義如下: 

  1. VOID RtlInitUnicodeString(  
  2.  IN OUT PUNICODE_STRING DestinationString,  
  3.  IN PCWSTR SourceString  
  4. );  

參數說明如下。

DestinationString:要初始化的 UNICODE_STRING 字符串的指針。

SourceString:字符串的內容。

在為InitializeObjectAttributes()函數傳遞第2個參數時,需要指定的文件名是一個符號鏈接。在應用層下,描述一個文件的完整路徑是“c:\a.txt”;而在內核下,描述的方式為“\??\c:\a.txt”。符號鏈接在內核模式下以“\??\”(或者是“\DosDevices\”)開頭;在用戶模式下使用符號鏈接,則以“\\.\”開頭。

上面介紹的ZwCreateFile()函數不但可以創建文件,還可以打開文件。但是由于它的參數過于繁多,因此內核函數中專門提供了一個用于進行文件打開的函數ZwOpenFile(),其定義如下: 

  1. NTSTATUS ZwOpenFile(  
  2.  OUT PHANDLE FileHandle,  
  3.  IN ACCESS_MASK DesiredAccess,  
  4.  IN POBJECT_ATTRIBUTES ObjectAttributes,  
  5.  OUT PIO_STATUS_BLOCK IoStatusBlock,  
  6.  IN ULONG ShareAccess,  
  7.  IN ULONG OpenOptions  
  8. );  

ZwOpenFile()函數相當于一個只用來打開文件的精簡版的ZwCreateFile()函數,其各參數使用方法與ZwCreateFile()函數相同,這里不重復介紹。

文件句柄的關閉使用內核函數ZwClose(),其定義如下:

  1. NTSTATUS ZwClose(IN HANDLE Handle); 

該函數只包含一個參數,即被打開文件的句柄。該函數除了可以關閉文件句柄以外,還可以關閉其它類型資源的句柄,比如注冊表句柄等。

2. 文件的相關操作

文件相關的操作主要介紹4個內核函數,分別是ZwReadFile()、ZwWriteFile()、ZwQueryInformationFile()和ZwSetInformationFile()。例子代碼中實現了對文件的讀寫操作,判斷打開的文件是否為目錄,獲取文件的長度和設置文件的指針。

首先來看ZwQueryInformationFile()和ZwSetInformationFile()兩個函數的定義。ZwQueryIn formationFile()函數的定義如下: 

  1. NTSTATUS ZwQueryInformationFile(  
  2.  IN HANDLE FileHandle,  
  3.  OUT PIO_STATUS_BLOCK IoStatusBlock,  
  4.  OUT PVOID FileInformation,  
  5.  IN ULONG Length,  
  6.  IN FILE_INFORMATION_CLASS FileInformationClass  
  7. );  

參數說明如下。

FileHandle:被打開的文件句柄。

IoStatusBlock:返回設置的狀態。

FileInformation:依據 FileInformationClass 的不同而不同。

Length:FileInformation 數據的長度。

FileInformationClass:描述需獲取的屬性類型。

ZwSetInformationFile()函數的定義如下: 

  1. NTSTATUS ZwSetInformationFile(  
  2.  IN HANDLE FileHandle,  
  3.  OUT PIO_STATUS_BLOCK IoStatusBlock,  
  4.  IN PVOID FileInformation,  
  5.  IN ULONG Length,  
  6.  IN FILE_INFORMATION_CLASS FileInformationClass  
  7. );  

ZwSetInformationFile()函數的參數與 ZwQueryInformationFile()函數的參數幾乎相同,但是兩個函數的第 3 個參數稍有差別,差別在于對 ZwQueryInformationFile()來說是一個輸出參數,對于 ZwSetInformationFile()來說是一個輸入參數。這里一定要注意。

對于ZwQueryInformationFile()和ZwSetInformationFile()這兩個函數來說,第5個參數決定了要讀取或設置的屬性的類型,第3個參數根據第5個參數來接受或傳遞相應的值。

兩個函數的第5個參數的常用值有3種類型,分別是FileStandardInformation、FileBasic Information和FilePositionInformation。每種類型分別又對應不同的結構體,這些結構體則是被ZwQueryInformationFile()和ZwSetInformationFile()函數的第3個參數所用。

FileStandardInformation對應的結構體定義如下: 

  1. typedef struct FILE_STANDARD_INFORMATION {  
  2.  LARGE_INTEGER AllocationSize; // 為文件分配的大小(占用簇所需大小)  
  3.  LARGE_INTEGER EndOfFile; // 距離文件結尾的字節數  
  4.  ULONG NumberOfLinks; // 有多少個鏈接文件  
  5.  BOOLEAN DeletePending; // 是否準備刪除  
  6.  BOOLEAN Directory; // 是否為目錄  
  7. } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; 

FileBasicInformation對應的結構體定義如下: 

  1. typedef struct FILE_BASIC_INFORMATION {  
  2.  LARGE_INTEGER CreationTime; // 文件創建時間  
  3.  LARGE_INTEGER LastAccessTime; // 最后訪問時間  
  4.  LARGE_INTEGER LastWriteTime; // 最后寫入時間  
  5.  LARGE_INTEGER ChangeTime; // 修改時間  
  6.  ULONG FileAttributes; // 文件屬性  
  7. } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; 

FilePositionInformation對應的結構體定義如下: 

  1. typedef struct FILE_POSITION_INFORMATION {  
  2.  LARGE_INTEGER CurrentByteOffset; // 當前文件指針位置  
  3. } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; 

明白了第3個參數和第5個參數以后,就可以清楚第4個參數的取值了,該取值是第3個參數的大小。

上面的結構體中大量使用了LARGE_INTEGER的數據類型,它其實是一個聯合體。LARGE_INTEGER的定義如下: 

  1. typedef union _LARGE_INTEGER {  
  2.   struct {  
  3.     ULONG LowPart;  
  4.     LONG HighPart;  
  5.   };  
  6.   struct {  
  7.     ULONG LowPart;  
  8.     LONG HighPart;  
  9.   } u;  
  10.   LONGLONG QuadPart;  
  11. } LARGE_INTEGER; 

該結構體主要是用來表示64位的整數類型,通常使用其QuadPart成員。

ZwReadFile()函數的定義如下: 

  1. NTSTATUS ZwReadFile(  
  2.  IN HANDLE FileHandle,  
  3.  IN HANDLE Event OPTIONAL,  
  4.  IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,  
  5.  IN PVOID ApcContext OPTIONAL,  
  6.  OUT PIO_STATUS_BLOCK IoStatusBlock,  
  7.  OUT PVOID Buffer,  
  8.  IN ULONG Length,  
  9.  IN PLARGE_INTEGER ByteOffset OPTIONAL,  
  10.  IN PULONG Key OPTIONAL  
  11. ); 

參數說明如下。

FileHandle:打開文件的句柄。

Event:用于異步完成讀取時,一般設置為 NULL。

ApcRoutine:回調例程,用于異步完成讀取時,一般設置為 NULL。

ApcContext:一般設置為 NULL。

IoStatusBlock:指向 IO_STATUS_BLOCK 的指針,記錄讀取操作的狀態,IoStatusBlock.Information 用于記錄讀取的字節數。

Buffer:保存讀取文件內容的緩沖區。

Length:準備讀取文件內容的字節數。

ByteOffset:指定讀取內容的偏移地址。

Key:讀取文件時的附加信息,一般設置為 NULL。

ZwWriteFile()函數的定義如下: 

  1. NTSTATUS ZwWriteFile(  
  2.  IN HANDLE FileHandle,  
  3.  IN HANDLE Event OPTIONAL,  
  4.  IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,  
  5.  IN PVOID ApcContext OPTIONAL,  
  6.  OUT PIO_STATUS_BLOCK IoStatusBlock,  
  7.  IN PVOID Buffer,  
  8.  IN ULONG Length,  
  9.  IN PLARGE_INTEGER ByteOffset OPTIONAL,  
  10.  IN PULONG Key OPTIONAL  
  11. );  

該函數的參數類似于ZwReadFile()函數,Buffer中保存的是欲寫入文件內容的緩沖區。

3. 內存管理函數

文件讀寫代碼中用到了3個內存相關的內核函數,分別是ExAllocatePool()、RtlFillMem ory()和ExFreePool()。

ExAllocatePool()函數用于申請一塊內存空間,其定義如下: 

  1. PVOID ExAllocatePool(  
  2.  IN POOL_TYPE PoolType,  
  3.  IN SIZE_T NumberOfBytes  
  4. );  

參數說明如下。

PoolType:該參數是一個枚舉值,常用的值有兩個,分別是 NonPagedPool 和 PagedPool;前者表示非分頁內存,而后者表示分頁內存;永遠不會被交換到文件中的虛擬內存稱為非分頁內存,可以被交換到文件中的虛擬內存稱為分頁內存。

NumberOfBytes:表示需要分配的內存大小。

該函數的返回值是一個內存地址。

RtlFillMemory()函數用于填充內存,其定義如下: 

  1. VOID RtlFillMemory(  
  2.  IN VOID UNALIGNED *Destination,  
  3.  IN SIZE_T Length,  
  4.  IN UCHAR Fill  
  5. );  

參數說明如下。

Desination:填充內存地址的起始位置。

Length:填充的長度。

Fill:需要填充的字節。

ExFreePool()函數用于回收 ExAllocatePool()申請的內存空間,其定義如下:

  1. VOID ExFreePool(IN PVOID P); 

該函數只有一個參數,是指向ExAllocatePool()函數分配內存空間的指針。 

 

責任編輯:龐桂玉 來源: 計算機與網絡安全
相關推薦

2021-06-24 08:37:34

網絡安全內核代碼

2021-02-07 10:55:01

網絡安全文件API

2021-05-24 11:55:55

網絡安全Windows鉤子函數

2021-03-03 12:20:42

網絡安全DLL編程

2021-04-19 10:26:41

網絡安全PE文件

2021-03-05 13:46:56

網絡安全遠程線程

2021-01-26 13:45:03

網絡安全Winsock編程

2021-05-06 16:35:12

網絡安全網絡安全編程文件補丁

2021-02-21 18:19:43

網絡安全網絡安全編程創建進程

2021-05-08 11:50:59

網絡安全API函數代碼

2021-02-23 10:20:07

網絡安全進程代碼

2021-04-14 15:53:58

網絡安全C語言wcslen

2016-10-10 00:18:27

2021-04-06 11:04:54

網絡安全C語言代碼

2021-02-15 15:23:03

網絡安全注冊表API

2021-06-18 09:55:09

網絡安全目錄監控

2011-03-17 13:32:45

2021-01-18 10:35:18

網絡安全Windows代碼

2021-03-01 11:20:13

網絡安全多線程代碼

2021-02-04 10:50:11

網絡安全非阻塞模Winsock編程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲视频国产 | 久久一区精品 | av在线免费观看网址 | 国产一区二区三区四区在线观看 | 中文字幕日韩在线观看 | 成人免费观看视频 | 羞羞视频在线网站观看 | 亚洲国产午夜 | 97碰碰碰 | 九一视频在线播放 | 久久亚洲国产精品 | 日韩在线电影 | 韩日一区二区三区 | 日本一区二区三区在线观看 | 在线看av的网址 | 久久精品国产精品青草 | 亚洲高清av在线 | 欧美日韩综合精品 | 九九国产 | 国产精品不卡视频 | 亚洲成人蜜桃 | 欧美综合一区 | 精品欧美一区二区精品久久久 | 久久久久成人精品亚洲国产 | 亚洲精品视频在线看 | 久久久久久免费毛片精品 | 国产精品欧美精品日韩精品 | 久久高清免费视频 | 电影在线 | 精品一区二区三区91 | 欧洲妇女成人淫片aaa视频 | 国内精品视频在线观看 | 国产不卡在线 | 亚洲精品乱码久久久久久久久 | 国产在线精品免费 | 久久宗合色 | 婷婷五月色综合香五月 | 亚洲精品久久久久久首妖 | 亚洲视频免费在线看 | 91在线视频在线观看 | 最新国产福利在线 |