zoukankan      html  css  js  c++  java
  • 《Windows内核安全与驱动开发》 3.2 内存与链表

    《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

    《Windows内核安全与驱动开发》 3.2 内存与链表

    1. 尝试生成一个链表头并将其初始化。

     

    2. 尝试向内存中申请两个链表结点,并且初始化该结点,将该结点插入到链表中,其数据结构如下。

    typedef struct {
        LIST_ENTRY list_entry;
        INT id;
    }StuInfo,*PStuInfo;

    3. 遍历“问题2”中生成的链表,并调用 DbgPrint 打印出来。

    4. 将问题2中的链表清空(并释放内存),最后判断该链表是否为空。

    5. 有几种删除链表结点的方法。

    6. 遍历链表时,如果 LIST_ENTRY 成员不在开头,应该如何操作?


    答案

    1. 尝试生成一个链表头并将其初始化。

    // 定义并初始化链表头
    LIST_ENTRY my_list_entry;
    InitializeListHead(&my_list_entry);

    2. 尝试向内存中申请两个链表结点,并且初始化该结点,将该结点插入到链表中,其数据结构如下。

    //
    // 向内存中申请一个结点,并插入到链表中。
    //
    PStuInfo pStu1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo),MEN_NAME);
    if (!pStu1) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    pStu1->id = 123;
    InsertHeadList(&my_list_entry, (PLIST_ENTRY) pStu1);
    
    PStuInfo pStu2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo), MEN_NAME);
    if (!pStu2) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    pStu2->id = 456;
    InsertHeadList(&my_list_entry, (PLIST_ENTRY)pStu2);

    3. 遍历“问题2”中生成的链表,并调用 DbgPrint 打印出来

    //
    // 遍历链表
    //
    for (PLIST_ENTRY p = my_list_entry.Flink; p != &my_list_entry; p = p->Flink) {
        DbgPrint("%d
    ", ((PStuInfo)p)->id);
    }

    4. 将问题2中的链表清空(并释放内存),最后判断该链表是否为空。

    //
    // 全部删除链表
    //
    PLIST_ENTRY p;
    
    while (!IsListEmpty(&my_list_entry)) {
        p = RemoveHeadList(&my_list_entry); // 获取被移除链表元素
        ExFreePool((PStuInfo)p);
    
    }
    
    // 判断链表是否为空
    if (IsListEmpty(&my_list_entry)) {
        DbgPrint("链表已空
    ");
    }
    else {
        DbgPrint("链表未空
    ");
    }

    5. 三种方法,移除链表头(RemoveHeadList);移除链表尾(RemoveTailList);移除中间元素(RemoveEntryList)。

    6. 使用一个宏 CONTAINING_RECORD.

    完整代码:

     1 #include <ntifs.h>
     2 #define MEN_NAME 'abc'
     3 // 定义链表结构
     4 typedef struct {
     5     LIST_ENTRY list_entry;
     6     INT id;
     7 }StuInfo,*PStuInfo;
     8 
     9 
    10 
    11 //提供一个卸载函数,让程序能卸载,如果没有这个函数,驱动将不能卸载。
    12 VOID UnDriver(PDRIVER_OBJECT driver)
    13 {
    14     KdPrint(("卸载驱动成功"));
    15 }
    16 //入口函数,相当于main。
    17 NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
    18 {
    19     // 定义并初始化链表头
    20     LIST_ENTRY my_list_entry;
    21     InitializeListHead(&my_list_entry);
    22     
    23     //
    24     // 向内存中申请一个结点,并插入到链表中。
    25     //
    26     PStuInfo pStu1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo),MEN_NAME);
    27     if (!pStu1) {
    28         return STATUS_INSUFFICIENT_RESOURCES;
    29     }
    30     pStu1->id = 123;
    31     InsertHeadList(&my_list_entry, (PLIST_ENTRY) pStu1);
    32 
    33     PStuInfo pStu2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo), MEN_NAME);
    34     if (!pStu2) {
    35         return STATUS_INSUFFICIENT_RESOURCES;
    36     }
    37     pStu2->id = 456;
    38     InsertHeadList(&my_list_entry, (PLIST_ENTRY)pStu2);
    39 
    40     //
    41     // 遍历链表
    42     //
    43     for (PLIST_ENTRY p = my_list_entry.Flink; p != &my_list_entry; p = p->Flink) {
    44         DbgPrint("%d
    ", ((PStuInfo)p)->id);
    45     }
    46 
    47     //
    48     // 全部删除链表
    49     //
    50     PLIST_ENTRY p;
    51 
    52     while (!IsListEmpty(&my_list_entry)) {
    53         p = RemoveHeadList(&my_list_entry); // 获取被移除链表元素
    54         ExFreePool((PStuInfo)p);
    55 
    56     }
    57 
    58     // 判断链表是否为空
    59     if (IsListEmpty(&my_list_entry)) {
    60         DbgPrint("链表已空
    ");
    61     }
    62     else {
    63         DbgPrint("链表未空
    ");
    64     }
    65 
    66     driver->DriverUnload = UnDriver;
    67     return STATUS_SUCCESS;
    68 }
  • 相关阅读:
    centos7 安装nginx
    mysql
    MySQL的架构体系
    Redis实战之基础入门5种数据类型
    常用的接口限流算法
    大型分布式电商系统架构有哪些
    PHP内存管理机制
    MySQL索引查询原理
    Nginx的骚操作你知道多少?
    使用illuminate/html 提示: Call to undefined method IlluminateFoundationApplication::bindShared()
  • 原文地址:https://www.cnblogs.com/onetrainee/p/11993810.html
Copyright © 2011-2022 走看看