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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows内核函数

發(fā)布時間:2023/12/2 windows 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows内核函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

字符串處理

在驅(qū)動中一般使用的是ANSI字符串和寬字節(jié)字符串,在驅(qū)動中我們?nèi)匀豢梢允褂肅中提供的字符串操作函數(shù),但是在DDK中不提倡這樣做,由于C函數(shù)容易導致緩沖區(qū)溢出漏洞,針對字符串的操作它提供了一組函數(shù)分別用來處理ANSI字符串和UNICODE字符串。
針對兩種字符串,首先定義了它們的結(jié)構(gòu)體

typedef struct _STRING {USHORT Length;//字符串的長度USHORT MaximumLength;//字符緩沖的長度PCHAR Buffer;//字符緩沖的地址 } ANSI_STRING, *PANSI_STRING;typedef struct _UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;

對于這兩個字符串的打印,可以使用%wZ打印UNICODE_STRING用%Z打印ANSI_STRING

字符串的初始化

VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,IN PCSZ SourceString);VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,IN PCWSTR SourceString);

這兩個函數(shù)只是簡單的將SourceString 的首地址賦值給Buffer成員,并初始化相關的長度,所以在使用時需要考慮緩沖的生命周期,權(quán)限,同時如果我們改變SourceString 里面存儲的字符串,那么對應的UNICODE_STRING 或者ANSI_STRING中的值也會改變,比如下面的代碼

RtlInitUnicodeString(&uTest, L"Hello World"); RtlCopyMemory(uTest.Buffer, L"Test");

由于Buffer指向的是不可修改的常量內(nèi)存部分,所以后面試圖修改它的時候會造成程序崩潰。

void InitString(&pUnicodeString) {WCHAR szBuf[255] = L"Hello world";RtlInitUnicodeString(pUnicodeString, szBuffer); } void test() {UNICODE_STRING uTest;InitString(&uTest);//后面的操作 }

我們在另外一個函數(shù)中利用局部變量來初始化這個字符串的時候由于當函數(shù)調(diào)用完成,函數(shù)中局部變量被銷毀,這個時候指向的那塊內(nèi)存可能已經(jīng)被其他函數(shù)所占用,而我們后面通過操作UNICODE_STRING,又要操作這段內(nèi)存,這個時候一定會出現(xiàn)問題,所以一般如果要在多個函數(shù)中使用這個UNICODE_STRING時一般申請一段堆內(nèi)存,但是在使用完成后一定要記得自己回收這段內(nèi)存,否則會造成內(nèi)存泄露,對此DDK專門提供了一組函數(shù)來銷毀字符串中的堆內(nèi)存

VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString);VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString);

字符串拷貝:

VOID RtlCopyString(IN OUT PSTRING DestinationString,IN PSTRING SourceString OPTIONAL);VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,IN PUNICODE_STRING SourceString);

字符串比較

LONG RtlCompareString(IN PSTRING String1,IN PSTRING String2,BOOLEAN CaseInSensitive//是否忽略大小寫);LONG RtlCompareUnicodeString(IN PUNICODE_STRING String1,IN PUNICODE_STRING String2,IN BOOLEAN CaseInSensitive);

字符串轉(zhuǎn)化為大寫

VOID RtlUpperString(IN OUT PSTRING DestinationString,IN PSTRING SourceString);NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,IN PCUNICODE_STRING SourceString,IN BOOLEAN AllocateDestinationString//是否要求該函數(shù)自行為輸出參數(shù)分配內(nèi)存);

這兩個函數(shù)在調(diào)用是目標字符串和源字符串可以是同一個字符串
字符串與整形數(shù)字之間的轉(zhuǎn)化可以使用函數(shù)

NTSTATUSRtlUnicodeStringToInteger(IN PUNICODE_STRING String,IN ULONG Base OPTIONAL,//需要的數(shù)的進制OUT PULONG Value);NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value,IN ULONG Base OPTIONAL,IN OUT PUNICODE_STRING String);

ANSI與UNICODE字符串的相互轉(zhuǎn)化可以使用下面的函數(shù)

NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,IN PUNICODE_STRING SourceString,IN BOOLEAN AllocateDestinationString);NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,IN PANSI_STRING SourceString,IN BOOLEAN AllocateDestinationString);

文件操作

創(chuàng)建或者打開一個文件

文件的創(chuàng)建和打開都是使用函數(shù)ZwCreateFile

NTSTATUS ZwCreateFile(OUT PHANDLE FileHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,OUT PIO_STATUS_BLOCK IoStatusBlock,IN PLARGE_INTEGER AllocationSize OPTIONAL,IN ULONG FileAttributes,IN ULONG ShareAccess,IN ULONG CreateDisposition,IN ULONG CreateOptions,IN PVOID EaBuffer OPTIONAL,IN ULONG EaLength);
  • FileHandle:這個函數(shù)通過這個參數(shù)返回文件句柄
  • DesiredAccess:以何種權(quán)限打開或者創(chuàng)建這個文件,GENERIC_READ可讀,GENERIC_WRITE可寫,GENERIC_EXECUTE可執(zhí)行,GENERIC_ALL所有權(quán)限
  • ObjectAttributes:這是一個文件屬性的結(jié)構(gòu)體,里面包含有要打開的文件的名稱
  • IoStatusBlock:接受函數(shù)操作文件的結(jié)果狀態(tài)
  • AllocationSize:指定在創(chuàng)建愛女或者寫文件時初始大小,如果給0,則文件大小會隨著寫入數(shù)據(jù)的增加而動態(tài)的增加
  • FileAttributes:指定新創(chuàng)建文件的屬性,一般給0或者FILE_ATTRIBUTE_NORMAL
  • ShareAccess:文件的共享權(quán)限,其他線程或者進程通過這個句柄訪問文件的權(quán)限,給0表示不允許其他進程通過這個句柄訪問,FILE_SHARE_READ讀, FILE_SHARE_WRITE寫,FILE_SHARE_DELETE刪除
  • CreateDisposition:指定當文件存在或者不存在時這個函數(shù)的動作。它的取值可以有下面幾個
  • 取值文件存在文件不存在
    FILE_SUPERSEDE新建一個文件替代新建文件
    FILE_CREATE返回一個錯誤創(chuàng)建文件
    FILE_OPEN打開文件返回一個錯誤
    FILE_OPEN_IF打開文件創(chuàng)建文件
    FILE_OVERWRITE打開,并且將之前的內(nèi)容覆蓋返回錯誤
    FILE_OVERWRITE_IF打開,并且將之前的內(nèi)容覆蓋創(chuàng)建文件

    9. CreateOptions打開或者創(chuàng)建文件時的附加操作,一般給FILE_SYNCHRONOUS_IO_NONALERT
    10. EaBuffer指向擴展空間的指針
    11. EaLength擴展空間的大小
    這個函數(shù)與應用層的CreateFile不同的時,在指定打開或者創(chuàng)建文件名時是使用結(jié)構(gòu)OBJECT_ATTRIBUTES來指定,針對這個結(jié)構(gòu),有一個函數(shù)能夠初始化它

    VOID InitializeObjectAttributes(OUT POBJECT_ATTRIBUTES InitializedAttributes,IN PUNICODE_STRING ObjectName,//文件名IN ULONG Attributes,IN HANDLE RootDirectory,IN PSECURITY_DESCRIPTOR SecurityDescriptor);

    Attributes:該對象的描述信息,一般給OBJ_CASE_INSENSITIVE 表示對大小寫敏感
    RootDirectory :該文件的根目錄,一般給NULL
    SecurityDescriptor :安全描述符,一般也是給NULL
    另外這里的名稱必須使用符號鏈接名或者設備名,而不是我們熟悉的“C:\”這種形式對于C盤可以使用名稱“\??\C”或者“\Device\HarddiskVolum1”這種形式
    當程序結(jié)束時需要調(diào)用ZwClose來清理文件句柄這個函數(shù)的參數(shù)比較簡單,只是簡單的傳入文件句柄即可

    獲取和設置文件的相關信息

    可以下面兩個函數(shù)分別獲取和設置文件的相關信息

    NTSTATUS ZwQueryInformationFile(IN HANDLE FileHandle,OUT PIO_STATUS_BLOCK IoStatusBlock,OUT PVOID FileInformation,IN ULONG Length,IN FILE_INFORMATION_CLASS FileInformationClass);NTSTATUS ZwSetInformationFile(IN HANDLE FileHandle,OUT PIO_STATUS_BLOCK IoStatusBlock,IN PVOID FileInformation,IN ULONG Length,IN FILE_INFORMATION_CLASS FileInformationClass);

    其中FileInformationClass是一個枚舉值,根據(jù)這個值得不同F(xiàn)ileInformation可以被解析成不同的內(nèi)容。
    1. 當這個參數(shù)為FileStandardInformation時,使用結(jié)構(gòu)體FILE_STANDARD_INFORMATION

    typedef struct FILE_STANDARD_INFORMATION {LARGE_INTEGER AllocationSize; //為文件分配簇所占空間的大小LARGE_INTEGER EndOfFile;//距離文件結(jié)尾還有多少字節(jié),當文件指針位于文件頭時,這個值就是文件本身大小ULONG NumberOfLinks;//有多少個鏈接文件BOOLEAN DeletePending;//是否準備刪除BOOLEAN Directory;//是否為目錄 } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
  • 當這個參數(shù)為FileBasicInformation使用結(jié)構(gòu)體FILE_BASIC_INFORMATION
  • typedef struct FILE_BASIC_INFORMATION {LARGE_INTEGER CreationTime; //創(chuàng)建時間LARGE_INTEGER LastAccessTime;//上次訪問時間LARGE_INTEGER LastWriteTime;//上次寫文件時間LARGE_INTEGER ChangeTime;//上次修改時間ULONG FileAttributes;//文件屬性 } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

    其中時間參數(shù)是一個LARGE_INTEGER類型的整數(shù),代表從1601年到現(xiàn)在經(jīng)過多少個100ns。文件屬性參數(shù)如果為FILE_ATTRIBUTE_DIRECTORY表示這是一個目錄文件,FILE_ATTRIBUTE_NORMAL表示是一個普通文件,FILE_ATTRIBUTE_HIDDEN表示這是一個隱藏文件,FILE_ATTRIBUTE_SYSTEM表示這是一個系統(tǒng)文件,FILE_ATTRIBUTE_READONLY表示這是一個只讀文件
    3. 當這個參數(shù)為FileNameInformation時,使用結(jié)構(gòu)體FILE_NAME_INFORMATION

    typedef struct _FILE_NAME_INFORMATION {ULONG FileNameLength;//文件名長度WCHAR FileName[1];//文件名 } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
  • 當這個參數(shù)是FilePositionInformation時,使用結(jié)構(gòu)體FILE_POSITION_INFORMATION
  • typedef struct FILE_POSITION_INFORMATION {LARGE_INTEGER CurrentByteOffset;//當前文件指針的位置 } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;

    讀寫文件

    寫文件調(diào)用函數(shù)ZwCreateFile

    NTSTATUS ZwWriteFile(IN HANDLE FileHandle,//文件句柄IN HANDLE Event OPTIONAL,//時間對象一般給NULLIN PIO_APC_ROUTINE ApcRoutine OPTIONAL,//一般給NULLIN PVOID ApcContext OPTIONAL,//一般給NULLOUT PIO_STATUS_BLOCK IoStatusBlock,//記錄寫操作的狀態(tài)用里面的Information成員記錄實際寫了多少字節(jié)IN PVOID Buffer,//寫入文件中緩沖區(qū)的指針IN ULONG Length,//緩沖區(qū)中數(shù)據(jù)的長度IN PLARGE_INTEGER ByteOffset OPTIONAL,//從文件的多少地址開始寫IN PULONG Key OPTIONAL//一般給NULL);

    讀文件使用函數(shù)ZwReadFile

    NTSTATUS ZwReadFile(IN HANDLE FileHandle,//文件句柄IN HANDLE Event OPTIONAL,//一般給NULLIN PIO_APC_ROUTINE ApcRoutine OPTIONAL,//一般給NULLIN PVOID ApcContext OPTIONAL,//一般給NULLOUT PIO_STATUS_BLOCK IoStatusBlock, //讀取的字節(jié)數(shù)保存在結(jié)構(gòu)的成員Information中OUT PVOID Buffer,//緩沖區(qū)的指針IN ULONG Length,//緩沖區(qū)的長度IN PLARGE_INTEGER ByteOffset OPTIONAL,//從文件的多少位置開始讀IN PULONG Key OPTIONAL//一般給NULL);

    注冊表操作

    注冊表中有下面幾個概念:
    1. 注冊表項:注冊表項類似于目錄的概念,下面可以有子項或者注冊表的鍵-值對
    2. 注冊表子項:類似于子目錄的概念
    3. 鍵名:通過鍵名可以尋找到相應的鍵值
    4. 鍵值類別:每個鍵值在存儲的時候有不同的類型,相當于變量的類型,主要有字符串和整型
    5. 鍵值:鍵名下對應存儲的數(shù)據(jù)

    創(chuàng)建和關閉注冊表

    創(chuàng)建注冊表使用函數(shù)ZwCreateKey

    NTSTATUS ZwCreateKey(OUT PHANDLE KeyHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN ULONG TitleIndex,IN PUNICODE_STRING Class OPTIONAL,IN ULONG CreateOptions,OUT PULONG Disposition OPTIONAL);
  • KeyHandle:輸出一個注冊表對應項的句柄,以后針對這個項操作都是以這個句柄作為標示
  • DesiredAccess:訪問權(quán)限,一般都設置為KEY_ALL_ACCESS
  • ObjectAttributes:用法與文件操作中的用法相同
    其中應用層中注冊表項與內(nèi)核中注冊表項的對應關系如下:
  • 應用層中的子健內(nèi)核中的路徑
    HKEY_CLASSES_ROOT沒有對應的路徑
    HKEY_CURRENT_USER沒有簡單的對應路徑,但是可以求得
    HKEY_USERS\Registry\User
    HKEY_LOCAL_MACHINE\Registry\Machine

    4. TitleIndex:一般設置為0
    5. Class 一般給NULL
    6. CreateOptions:創(chuàng)建選項,一般給REG_OPTION_NON_VOLATILE
    7. Disposition:返回創(chuàng)建的狀態(tài),如果是REG_CREATED_NEW_KEY表示創(chuàng)建了一個新的注冊表項如果是REG_OPENED_EXISTING_KEY表示打開一個已有的注冊表項
    8. ### 添加、修改注冊表鍵
    注冊表中的鍵是類似與字典中的鍵值對,通過鍵名找到對應的值,鍵值的類型大致可以分為下面幾種

    分類描述
    REG_BINARY鍵值采用二進制存儲
    REG_SZ鍵值用寬字符串,以\0結(jié)尾
    REG_EXPAND_SZ與上面的REG_SZ相同,它是上面那個字符串的擴展字符
    REG_MULTI_SZ能夠存儲多個字符串,每個都以\0隔開
    REG_DWORD鍵值用4字節(jié)整型存儲(這個類型的數(shù)據(jù)在驅(qū)動中使用ULONG來替代)
    REG_QWORD鍵值用8字節(jié)存儲(這個用LONGLONG)

    用函數(shù)ZwSetValueKey可以添加和修改注冊表的一項內(nèi)容

    NTSTATUS ZwSetValueKey(IN HANDLE KeyHandle, //注冊表句柄IN PUNICODE_STRING ValueName,//要修改或者新建的鍵名IN ULONG TitleIndex OPTIONAL,//一般設置為0IN ULONG Type,//在上面的表中選擇一個IN PVOID Data,//鍵值IN ULONG DataSize//鍵值數(shù)據(jù)的大小);

    當傳入的鍵值不存在則創(chuàng)建一個新鍵值,否則就修改原來的鍵值

    查詢注冊表

    查詢注冊表使用函數(shù)ZwQueryValueKey

    NTSTATUS ZwQueryValueKey(IN HANDLE KeyHandle, //注冊表句柄IN PUNICODE_STRING ValueName,//注冊表鍵名IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,OUT PVOID KeyValueInformation,//接收返回信息的緩沖區(qū)IN ULONG Length,//緩沖區(qū)的大小OUT PULONG ResultLength//真實緩沖區(qū)的大小);

    使用這個函數(shù)時利用參數(shù)KeyValueInformationClass來指定接收數(shù)據(jù)的類型,根據(jù)這個值的不同,函數(shù)會返回不同的結(jié)構(gòu)體放到一個緩沖區(qū)中。一般這個值可取:KeyValueBasicInformation 返回注冊表項的基礎信息
    KeyValueFullInformation 返回注冊表的全部信息
    KeyValuePartialInformation 返回注冊表的部分信息
    一般情況下使用KeyValuePartialInformation查詢鍵值數(shù)據(jù)
    利用這個函數(shù)來查詢時一般也是采用兩次調(diào)用的方式,第一次返回數(shù)據(jù)所需緩沖,然后分配緩沖并進行第二次調(diào)用

    枚舉子項

    DDK提供了兩個函數(shù)用于這個功能

    NTSTATUS ZwQueryKey(IN HANDLE KeyHandle,//注冊表句柄IN KEY_INFORMATION_CLASS KeyInformationClass,//保存注冊表信息的結(jié)構(gòu)體的類型OUT PVOID KeyInformation,//返回查詢到信息的緩沖IN ULONG Length,//緩沖的大小OUT PULONG ResultLength//真正信息的大小);NTSTATUS ZwEnumerateKey(IN HANDLE KeyHandle,//句柄IN ULONG Index,//這個值是表示第幾個子項IN KEY_INFORMATION_CLASS KeyInformationClass,//查詢到的信息的結(jié)構(gòu)體OUT PVOID KeyInformation,//返回信息的緩沖IN ULONG Length,//緩沖長度OUT PULONG ResultLength//返回信息的長度);

    其中ZwQueryKey函數(shù)用于查詢某個注冊表項中有多少個子項,在調(diào)用這個函數(shù)時傳入的KeyInformationClass的值一般給KeyFullInformation,在這個結(jié)構(gòu)體中的SubKeys表示有多少個子項,而ZwEnumerateKey則是用于查詢各個子項中的具體內(nèi)容,通過指定Index表示我們要查詢該項中的第幾個子項,將KeyInformationClass填入KeyBasicInformation,這樣在結(jié)構(gòu)體的Name里面可以得到具體的注冊表子項的名稱

    枚舉子健

    枚舉子鍵的方法于上面的大致相同,首先利用ZwQueryKey查詢注冊表,然后取結(jié)構(gòu)體KeyFullInformation的成員Values,根據(jù)這個值在循環(huán)中依次調(diào)用函數(shù)ZwEnumerateValueKey,結(jié)構(gòu)體類填入 KeyValueBasicInformation查詢基本信息即可

    刪除子項

    刪除子項使用的內(nèi)核函數(shù)是ZwDeleteKey

    NTSTATUS ZwDeleteKey(IN HANDLE KeyHandle);

    這個函數(shù)只能刪除沒有子項的項目,如果有子項,則需要先刪除所有子項。

    其他注冊表函數(shù)

    為了簡化注冊表操作,DDK提供了另外一組以Rtl開頭的函數(shù),把之前的Zw函數(shù)進行了封裝,下面是這些函數(shù)與它們功能的對應關系

    函數(shù)名描述
    RtlCreateRegistryKey創(chuàng)建注冊表項
    RtlCheckRegistryKey查看注冊表中的某項是否存在
    RtlWriteRegistryValue寫注冊表
    RtlDeleteRegistryValue刪除注冊表的子鍵

    轉(zhuǎn)載于:https://www.cnblogs.com/lanuage/p/7725717.html

    總結(jié)

    以上是生活随笔為你收集整理的Windows内核函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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