YJX_Driver_034_内存管理相关内核API

1、

内存管理相关内核API
  A、RtlCopyMemory,RtlCopyBytes和RtlMoveMemory
  C、RtlZeroMemory和RtlFillMemory
  D、RtlEqualMemory
  E、ExAllocatePool和 ExFreePool
  F、重载new和delete操作符

 

【225】下面是从MSDN里面,复制出来的函数的说明

RtlCopyMemory // 宏memcpy
//把地址Source开始的长度为Length这块内存数据 复制到Destination
VOID RtlCopyMemory(
  __in VOID UNALIGNED *Destination, IA64 表示逐字节对齐 #pragma packed(1) byte
  __in const VOID UNALIGNED *Source,
  __in SIZE_T Length  // 以byte为单位
);

  【310】"UNALIGNED" 表示 不对其的一个方式,它也是一个宏。它一般表示 在32位的系统下面 相当于是一个空宏;在64位平台 及一些其他的平台下面,它表示 比如说 IA64的平台下面 表示逐字节对齐(有点像 前面学过的 "#pragma packed(1)")。【505】也就是说,相当于 其实这个指针("VOID UNALIGNED *Destination")的话有点相当于byte*,我是这样理解的

    ZC: 自己再看看 这个宏的定义到底是啥...  个人理解,偏向于 不管什么平台都是相当于 byte*。

    ZC: 网上查到:“若 Itanium 处理器生成对齐错误,则它访问未对齐数据,并且,每次处理错误会降低性能。 使用 __unaligned 修饰符使该处理器一次读取数据的字节和避免错误。 ”。也就是说,未使用__unaligned的时候,若 指针指向的数据/结构体等 位于非对齐位置,则 Itanium处理器处理它们的时候 会生成对齐错误?这里的对齐指的是  类似 CPU/OS内核 所指定的 内存4K对齐?

【950】

RtlCopyBytes
VOID RtlCopyBytes(
  __in PVOID Destination,
  __in const VOID *Source,
  __in SIZE_T Length
);

  ZC: RtlCopyBytes 和 RtlCopyMemory,区别是啥?

  ZC: 貌似RtlCopyBytes已经deprecated,应该使用 RtlCopyMemory代替RtlCopyBytes 。

【1015】

RtlMoveMemory // 重叠内存 A B C D p1=AD p2=BC
// 宏memmove
VOID RtlMoveMemory(
  __in VOID UNALIGNED *Destination,
  __in const VOID UNALIGNED *Source,
  __in SIZE_T Length  // 以byte为单位
);

  【1560】其实像 Rtl??? 这种函数,它大多数 是通过宏 来引用一些内部的导出函数来实现的。用宏 保证了最大的兼容性,∵它正在不同平台 它的实现方法可能不一样。

    ZC: 貌似讲的有点错,用函数包一层照样可以保证兼容性,用宏而不用函数的原因 应该是 宏是编译时确定的 比函数少一次 函数调用的过程(压栈弹栈) 更省函数执行的时间。

【1625】

RtlZeroMemory // 清零内存块,清零长度为Length
VOID RtlZeroMemory(
  __in VOID UNALIGNED *Destination,
  __in SIZE_T Length  // 以byte为单位
);

【1740】

RtlFillMemory // 用字符fill 填充Destination 填充长度为Length
VOID RtlFillMemory(
  __in VOID UNALIGNED *Destination,
  __in SIZE_T Length,
  __in UCHAR Fill
);

【1985】

RtlEqualMemory // 比较内存块source1和Source2 长度为Length这个范围内是否相等
LOGICAL RtlEqualMemory(
  __in const VOID *Source1,
  __in const VOID *Source2,
  __in SIZE_T Length
);

RtlCompareMemory
SIZE_T RtlCompareMemory(
  __in const VOID *Source1,
  __in const VOID *Source2,
  __in SIZE_T Length
);

  RtlEqualMemory 和 RtlCompareMemory 是一样的作用.

  【2050】RtlEqualMemory 实际上调用了 RtlCompareMemory

  【2400】RtlEqualMemory 通过一个宏 比较 RtlCompareMemory的返回值和参数Length 是否相等。(ZC: 也就是说 RtlEqualMemory实际上通过宏 对RtlCompareMemory进行了简单的包装)

  ZC: MSDN上查到,RtlEqualMemory 的返回值 实际上就是 TRUE(非0?/>0?) 和 FALSE(0)

  ZC: MSDN上查到,RtlCompareMemory 的功能为: 从Source1&Source2的第一个byte开始比较 是否相等,逐byte比较,一旦遇到不相等 就停止比较,返回值为 2块内存中相等的byte数。

【2455】

ExAllocatePool
PVOID ExAllocatePool(
  __in POOL_TYPE PoolType,
  __in SIZE_T NumberOfBytes
);

ExFreePool
VOID ExFreePool(
  __in PVOID P
);

  【2555】

The POOL_TYPE enumeration type specifies the type of system memory to allocate.
Syntax
Copy
typedef enum _POOL_TYPE {
  NonPagedPool = 0, //不分页
  PagedPool = 1, //分页
  NonPagedPoolMustSucceed = 2, //指定分配 非分页内存,要求必须成功。
  DontUseThisType = 3, //未指定,留给系统使用
  NonPagedPoolCacheAligned = 4,//非分页内存,要求内存边界对齐。
  PagedPoolCacheAligned = 5,//分页内存,要求内存边界对齐。
  NonPagedPoolCacheAlignedMustS = 6 //指定分配 非分页内存,要求内存边界对齐,要求必须成功。
} POOL_TYPE;

    【2580】用的最多的是 NonPagedPool 和 PagedPool,后面这些 我都没有用过。当然后面的注释 是我通过翻译它的相关的MSDN的说明给出的一些解释

    【2670】NonPagedPoolMustSucceed 非分页必须成功,若不成功 可能会报一个错误,我也没有实际的运用过

 

【2760】通过一段代码,看一下 刚才讲的这些函数的功能

【2785】“重载new和delete操作符”  【2810】这个 重载 有点 难以理解,虽然我也使用过它 但是对它的理解也不是很深刻,等一下 我也说一下我的看法

【2865】看一下 一段代码

【2945】复制 第33课 的代码,头文件 加入到 驱动里面

 

【3035】首先,重载 new和delete操作符

  【3055】不重载它的话,使用new/delete会报错(ZC: 那就别用好了,干嘛非得用...)

  【3105】注释掉 new和delete操作符的重载

    【3225】此时使用new 会报错。ZC: 注意这里 "new"后面还输入参数"PagedPool"

    ZC: 注意到,这里的源码文件是 .CPP,C语言中能 重载new和delete操作符 吗?貌似不能...

 

【3385】分配内核内存

【3451】宏UNALIGNED 的定义,出现了3个地方可供选择,选择了ntdef.h。

  【3515】若是在64位平台下,UNALIGNED64 被定义为 __unaligned;若不是64位平台 UNALIGNED64 被定义为 空宏

  【3600】大致的了解,若是上面这些条件/平台之一的话,UNALIGNED 被定义为 __unaligned,若不是的话 UNALIGNED和UNALIGNED64 被定义为 空。不去管它,只做大致的了解。

  ZC: __unaligned 又如何解释?

  【3720】若 UNALIGNED 被定义为 __unaligned 的话,就表示 要求是逐字节的读取。

【4080】填充内存

【4185】内存复制

【4280】可以 手动的加一个断点("__asm int 3")

2、

 

重载new和delete操作符
//重载new
void * __cdecl operator new(size_t size, POOL_TYPE PoolType=PagedPool)
{
  KdPrint(("global operator new\n"));
  KdPrint(("Allocate size :%d\n",size));
  return ExAllocatePool(PagedPool,size);
}

//重载delete
void __cdecl operator delete(void* pointer)
{
  KdPrint(("Global delete operator\n"));
  ExFreePool(pointer);
}

 

#define RtlCopyBytes RtlCopyMemory
#define RtlZeroBytes RtlZeroMemory
#define RtlFillBytes RtlFillMemory

Constants
NonPagedPool
Nonpaged pool, which is nonpageable system memory. Nonpaged pool can be accessed from any IRQL, but it is a scarce resource and drivers should allocate it only when necessary.
The system can allocate buffers larger than PAGE_SIZE from nonpaged pool only in multiples of PAGE_SIZE. Requests for buffers larger than PAGE_SIZE, but not a PAGE_SIZE multiple, waste nonpageable memory.
PagedPool
Paged pool, which is pageable system memory. Paged pool can only be allocated and accessed at IRQL < DISPATCH_LEVEL.
NonPagedPoolMustSucceed
This value is for internal use only, and is allowed only during system startup. Drivers must not specify this value at times other than system startup, because a "must succeed" request crashes the system if the requested memory size is unavailable.
DontUseThisType
Reserved for system use.
NonPagedPoolCacheAligned
Nonpaged pool, aligned on processor cache boundaries. This value is for internal use only.
PagedPoolCacheAligned
Paged pool, aligned on processor cache boundaries. This value is for internal use only.
NonPagedPoolCacheAlignedMustS
This value is for internal use only, and is allowed only during system startup. It is the cache-aligned equivalent of NonPagedPoolMustSucceed.
Remarks
When the system allocates a buffer from pool memory of PAGE_SIZE or greater, it aligns the buffer on a page boundary. Memory requests smaller than PAGE_SIZE are not necessarily aligned on page boundaries, but these requests always fit within a single page and are aligned on an 8-byte boundary.
Requirements
Header Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)

__unaligned 关键字会让指针逐字节读取
#pragma packed(1)

 

转载于:https://www.cnblogs.com/debugskill/p/5373950.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值