忆杰的博客

忆杰的博客

内核中内存操作的一些函数

内核下面分配内存很简单. 我倒. 比3环下面还简单呢. 3环还需要调用两次函数, 0环更加方便.. 呵呵! 当然这只是使用上了. 内核中比用户态多了个后备列表内存(LookasideList),这翻译真是差劲..不过我看kmdkit里面也是这样翻译. 就将就着用吧! 还有的中文书籍好像根本就不翻译.. 估计也是不知道应该怎么翻译吧!

 

 

 

内核中还有个舒服的双向链表可以供使用. 估计是因为链表太常用了. 自己倒腾出来的链表每次写项目都改一次. 悲剧.. 还是系统直接提供好啊!这个双向链表也是非常容易使用的, 只是在遍历的时候我没搞明白. 咋个都不说遍历这个问题呢? 难道链表不需要遍历的么? 后来请教了杀哥才知道. 我倒还是需要自己写遍历函数. 不过挺简单, 这个就不算了!

这个后备列表内存, 也是比较好用. 使用也简单, 还有一些内存操作的函数, 这些函数在Win32下面也是有的, 所以直接划过..

<span style="font-family: courier new,courier,monospace">/*
	Windows内核下链表和后备列表操作!
	编译方法参见makefile.
*/
#include &lt;ntddk.h&gt;
#define ARRAY_NUMBER 50
#define BUFFER_SIZE 1024
#include &lt;ntstrsafe.h&gt;

typedef struct tagDATA {
	DWORD dwValue;
	LIST_ENTRY ListEntry;
}DATA, *PDATA;
//===========================================================================
//		内核中的链表使用. 非常舒服啊
#pragma code_seg( &quot;INIT&quot; )
VOID TestLinkList() {
	ULONG i;
	PDATA pData = NULL;
	PLIST_ENTRY pEntry;
	LIST_ENTRY ListHead;
	//初始化链表
	InitializeListHead( &amp;ListHead );

	//在链表从头部开始插入10个元素
	KdPrint(( &quot;\nBegin insert to link list Head!\n&quot; ));
	for( i = 0; i &lt;= 10; i++, pData = NULL ) {
		pData = (PDATA)ExAllocatePool( PagedPool, sizeof(DATA) );
		if ( !pData ) {
			KdPrint(( &quot;Memory Alloccation Error!\n&quot; ));
			return;
		}

		pData-&gt;dwValue = i;

		//在头部进行插入
		InsertHeadList( &amp;ListHead, &amp;pData-&gt;ListEntry );
	}
//---------------------------------------------------------------------------
	//从链表尾部中取出, 并显示
	KdPrint((&quot;\nBegin remove from link list Tail!\n&quot;));

	for( ;!IsListEmpty(&amp;ListHead); pData = NULL ) {

		pEntry = RemoveTailList( &amp;ListHead );

		//获取我们的数据指针
		pData = CONTAINING_RECORD( pEntry, DATA, ListEntry );
		if ( !pData ) {
			KdPrint(( &quot;Get Data Error!\n&quot; ));
			return;
		}

		KdPrint((&quot;%d\t&quot;,pData-&gt;dwValue ));
		ExFreePool( pData );
	}
//===========================================================================
	//在链表尾部插入10个元素
	KdPrint(( &quot;\nBegin insert to link list Tail!\n&quot; ));
	for( i = 0; i &lt;= 10; i++, pData = NULL ) {
		pData = (PDATA)ExAllocatePool( PagedPool, sizeof(DATA) );
		if ( !pData ) {
			KdPrint(( &quot;Memory Alloccation Error!\n&quot; ));
			return;
		}

		pData-&gt;dwValue = i;

		//在尾部进行插入
		InsertTailList( &amp;ListHead, &amp;pData-&gt;ListEntry  );
	}
//===========================================================================
	//遍历链表, 从头往后面遍历
	KdPrint(( &quot;\nTraverse the list!\n&quot; ));
	for( pEntry = ListHead.Flink; pEntry != &amp;ListHead; pEntry = pEntry-&gt;Flink, pData = NULL ) {

		//获取数据指针
		pData = CONTAINING_RECORD( pEntry,DATA, ListEntry );
		KdPrint(( &quot;%d\t&quot;, pData-&gt;dwValue ));
	}
//===========================================================================
	//从链表头部, 并显示
	KdPrint(( &quot;\nBegin remove from link list\n&quot;));

	for( ;!IsListEmpty(&amp;ListHead); pData = NULL ) {

		//从链表头部进行删除
		PLIST_ENTRY pEntry = RemoveHeadList( &amp;ListHead );

		//获取我们的数据指针
		pData = CONTAINING_RECORD(pEntry, DATA, ListEntry  );
		if ( !pData ) {
			KdPrint(( &quot;Get Data Error!\n&quot; ));
			return;
		}

		KdPrint((&quot;%d \t&quot;,pData-&gt;dwValue ));
		ExFreePool( pData );
	}
}
//===========================================================================
//		内核中的后备列表的使用.后备列表使用太简单了还没有kmdkit的例子号
#pragma code_seg( &quot;INIT&quot; )
VOID LookasideTest() {
	int i;
	PDATA MyDataArr[ARRAY_NUMBER] = {0};
	PAGED_LOOKASIDE_LIST PageLookaside;

	KdPrint(( &quot;Lookaside的使用!\n&quot; ));

	//初始化分页后备列表,还有一个非分页的..
	ExInitializePagedLookasideList( &amp;PageLookaside,NULL,NULL,0,sizeof(DATA),&#39;1234&#39;,0 );

	//模拟频繁申请内存
	for ( i=0; i &lt; ARRAY_NUMBER; i++ ) {
		MyDataArr[i] = (PDATA)ExAllocateFromPagedLookasideList( &amp;PageLookaside );

		RtlFillBytes( MyDataArr[i], sizeof(DATA), 0 );
		MyDataArr[i]-&gt;dwValue = i;
	}

	//模拟频繁回收内存
	for ( i = 0 ; i &lt; ARRAY_NUMBER; i++ ) {

		KdPrint(( &quot;%d\t&quot;, MyDataArr[i]-&gt;dwValue ));

		RtlZeroBytes( MyDataArr[i], sizeof(DATA) );
		ExFreeToPagedLookasideList( &amp;PageLookaside, MyDataArr[i] );
		MyDataArr[i] = NULL;
	}

	//删除Lookaside对象
	ExDeletePagedLookasideList( &amp;PageLookaside );
	KdPrint(( &quot;\nLookaside 使用完成!\n&quot; ));
}
//===========================================================================
	//内核中一些内存方面的函数使用, Win32下面也是有的, 差不多了
#pragma code_seg( &quot;INIT&quot; )
VOID RtlTest()
{
	PUCHAR pBuffer = NULL;
	PUCHAR pBuffer2 = NULL;
	ULONG ulRet;

	//分配分页内存, 并用0填充
	pBuffer = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
	RtlZeroMemory(pBuffer,BUFFER_SIZE);

	//分配分页内存, 并用0xAA填充
	pBuffer2 = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
	RtlFillMemory(pBuffer2,BUFFER_SIZE,0xAA);

	//内存拷贝
	RtlCopyMemory( pBuffer, pBuffer2,BUFFER_SIZE );

	//判断内存是否一致
	ulRet = RtlCompareMemory( pBuffer,pBuffer2, BUFFER_SIZE );
	if ( ulRet == BUFFER_SIZE )	{
		KdPrint((&quot;两块内存完全相等.\n&quot;));
	}else {
		KdPrint(( &quot;两块内存并不完全相等.\n&quot; ));
	}
}

NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzReg ) {

	TestLinkList();				//链表测试
	LookasideTest();			//后备列表内存测试
	RtlTest();				//常用内存函数测试
	return -1;
}
</span>

发表评论


Warning: Undefined variable $user_ID in /www/wwwroot/joenchen.com/wp-content/themes/agan/comments.php on line 66

您必须登录 才能进行评论。