定义字符串

内核中对字符串的操作没有stdio库里的那些函数,取而代之的是内核安全字符串,每个字符串是一个结构体。主要是利用几个内核API进行操作。

    RtlInitAnsiString(&ansi, char_string);
    RtlInitUnicodeString(&unicode, wchar_string);
    RtlUnicodeStringInit(&str, L"hello kernel");
// 这里网上说改变原字符串会影响新的,但是测试发现不会,比较迷惑

定义上差不多,可以采用普通的定义方式,也可以采用内核特有的定义方式。

        //typedef struct _UNICODE_STRING
        //{
        //    USHORT Length;
        //    USHORT MaxmumLength;
        //    PWSTR Buffer;
        //} UNICODE_STRING;

    // 定义内核字符串,其实都是结构体格式
    ANSI_STRING ansi;
    UNICODE_STRING unicode;
    UNICODE_STRING str;

    // 定义普通字符串
    char* char_string = "hello lyshark";
    wchar_t* wchar_string = (WCHAR*)"hello lyshark";

完整的测试代码如下,注意的是需要引用<ntstrsafe.h>这个库。

#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>

// 使用RtlUnicodeStringInit函数需要这个头文件,定义了内核安全字符串
#include <ntstrsafe.h>

NTSTATUS UseKernelString()
{

        //typedef struct _UNICODE_STRING
        //{
        //    USHORT Length;
        //    USHORT MaxmumLength;
        //    PWSTR Buffer;
        //} UNICODE_STRING;

    // 定义内核字符串,其实都是结构体格式
    ANSI_STRING ansi;
    UNICODE_STRING unicode;
    UNICODE_STRING str;

    // 定义普通字符串
    char* char_string = "hello lyshark";
    wchar_t* wchar_string = (WCHAR*)"hello lyshark";

    // 初始化字符串,相当于是把第二个参数的字符在复制到第一个参数,符合内核安全的格式
    RtlInitAnsiString(&ansi, char_string);
    RtlInitUnicodeString(&unicode, wchar_string);
    RtlUnicodeStringInit(&str, L"hello lyshark");

    // 长度除了unicode没显示不知道为啥,第一个是13,第三个26,符合预期
    DbgPrint("输出ANSI: %Z  |  %d\n", &ansi, ansi.Length);
    DbgPrint("输出WCHAR: %Z  |  %d \n", &unicode, unicode.Length);
    DbgPrint("输出字符串: %wZ  |  %d \n", &str, str.Length);

    // 改变原始字符串,不影响上面的初始化的字符串
    char_string[0] = 'A'; // char类型每个占用1字节
    char_string[1] = 'B';
    wchar_string[0] = (WCHAR)'A'; // wchar类型每个占用2字节
    wchar_string[2] = (WCHAR)'B';

    DbgPrint("输出ANSI: %Z \n", &ansi);
    DbgPrint("输出WCHAR: %Z \n", &unicode);
    DbgPrint("输出字符串: %wZ \n", &str);

    return STATUS_SUCCESS;
}

NTSTATUS unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver unload success..");
    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
    driver->DriverUnload = unload;
    DbgPrint("2.5 Hello World\n");
    if (UseKernelString())
    {
        DbgPrint("Call UseKernelString function succeed \n");
    }
    return STATUS_SUCCESS;
}

字符串操作

没有版权,随便复制,免费的知识应该共享 all right reserved,powered by Gitbook该文章修订时间: 2023-08-27 21:13:19

results matching ""

    No results matching ""