(四)、在驱动中使用链表和快查表

一、链表

1、代码

#include <ntddk.h>


typedef struct _MyLink
{
    LIST_ENTRY ListEntry;
    int number;
} MyLink,*pMyLink;

void LinkTest()
{
    LIST_ENTRY List_Head;
    InitializeListHead(&List_Head);//初始化链表//
    int i = 1;
    for ( i = 1; i <= 10; i++)
    {
        pMyLink pLink = (pMyLink)ExAllocatePool(PagedPool, sizeof(MyLink));
        pLink->number = i;
        InsertHeadList(&List_Head, &pLink->ListEntry);    //头插//
    }
    while (!IsListEmpty(&List_Head))
    {
        PLIST_ENTRY pGet = RemoveHeadList(&List_Head);
        
        pMyLink pdata = CONTAINING_RECORD(pGet, MyLink, ListEntry);////可以返回基地址//
        DbgPrint("%d\n", pdata->number);
        ExFreePool(pdata);

    }

}


VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("驱动xie载\n");
}


NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{

    DbgPrint("加载\n");
    LinkTest();
    driver->DriverUnload = Unload;

    return STATUS_SUCCESS;
}

2、实验

0
 
 

二、快查表

1、基本概念

快查表又称后备链表,只有内核可以使用
 
0
windows内核空间十分庞大,如果我们频繁申请内存,操作系统就会在可用内存中反复寻找找到可用内存页,这样会降低系统效率,使内存出现大量空洞。
快查表是一组是事先分配的相同尺寸的内存块,这些块有些在使用,有些没被使用。当有内存分配请求的时候,系统会遍历这个列表寻找最近的未分配的块。
如果未分配的块找到了,分配请求就很快被满足了。否则系统必须从分页或不分页内存池去分配。

2、所用函数

0
 
左边带N的函数是分配非分页内存的函数,右边是分配分页内存的函数

3、代码

//打错了,应该是LookAsideList//
#include<ntddk.h>

typedef struct _MYDATA
{
    int num;
}MYDATA,*pMYDATA;


VOID UnLoad(PDRIVER_OBJECT driver)
{
    DbgPrint("driver unLoad\n");
}

VOID testLookSide()
{
    PAGED_LOOKASIDE_LIST LookAsideList;
    ExInitializePagedLookasideList(&LookAsideList,NULL,NULL,0,sizeof(MYDATA),'ASDF',0);    //初始化分页的快查表//分配一些符合条件的内存块//微软要求单引号,但双引号貌似也可以//
    pMYDATA pdata[100] = { NULL };
    for (int i = 0; i < 100; i++)
    {
        pdata[i] = ExAllocateFromPagedLookasideList(&LookAsideList);//从快查链表中分配出来//
        pdata[i]->num = i;
    }
    DbgPrint("分页快查表测试\n");
    for (int i = 0; i < 100; i++)
    {    
        //DbgPrint("..........\n");
        DbgPrint("%p\n", pdata[i]);

        ExFreeToPagedLookasideList(&LookAsideList, pdata[i]);//
    }

    ExDeletePagedLookasideList(&LookAsideList);//删除后备链表//
}


NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg_path)
{
    DbgPrint("driver Load\n");
    
    driver->DriverUnload = UnLoad;
    testLookSide();
    return STATUS_SUCCESS;
}

4、验证

0
 
posted @ 2022-04-03 23:18  TLSN  阅读(84)  评论(0编辑  收藏  举报