Windows驱动
+ -

Windows内核驱动中使用new和delete

2021-07-01 330 1

在Windows驱动中如果要分配内存,我们使用的ExAllocatePoolWithTag,ExAllocatePool,而释放内存时使用的是ExAllocatePoolWithTag和ExFreePool函数。

我们知道,在内核中其实不是不能用C++,而是使用时有很大的限制。如果稍不留神,就会掉进坑里,这时问题其实是很难查的,所以一般情况下我们直接使用C语言编程。但随着驱动的复杂和微软为了加速音视频等,应用层的接口全部换成了COM接口,这样直接导致了驱动就必须直接使用C++来编程。

使用C++编程,首先要解决的一个问题就是内存的分配与释放,这时就必须解决的是new和delete运算符的重载。

这里我们提供一段示例代码,分别实现了new new[],delete,delete[]的重载。


#pragma code_seg("PAGE")

//
// New and delete operators
//
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
    __drv_reportError("Must succeed pool allocations are forbidden. "
            "Allocation failures cause a system crash"))
void* __cdecl operator new(size_t Size, POOL_TYPE PoolType)
{
    PAGED_CODE();

    Size = (Size != 0) ? Size : 1;

    void* pObject = ExAllocatePoolWithTag(PoolType, Size, BDDTAG);

#if DBG
    if (pObject != NULL)
    {
        RtlFillMemory(pObject, Size, 0xCD);
    }
#endif // DBG

    return pObject;
}

_When_((PoolType & NonPagedPoolMustSucceed) != 0,
    __drv_reportError("Must succeed pool allocations are forbidden. "
            "Allocation failures cause a system crash"))
void* __cdecl operator new[](size_t Size, POOL_TYPE PoolType)
{
    PAGED_CODE();

    Size = (Size != 0) ? Size : 1;

    void* pObject = ExAllocatePoolWithTag(PoolType, Size, BDDTAG);

#if DBG
    if (pObject != NULL)
    {
        RtlFillMemory(pObject, Size, 0xCD);
    }
#endif // DBG

    return pObject;
}

void __cdecl operator delete(void* pObject)
{
    PAGED_CODE();

    if (pObject != NULL)
    {
        ExFreePool(pObject);
    }
}

void __cdecl operator delete[](void* pObject)
{
    PAGED_CODE();

    if (pObject != NULL)
    {
        ExFreePool(pObject);
    }
}

其实从代码来看,new和delete运算符的重载只是对ExAllocatePoolWithTag和ExFreePool函数的包装,其本质还是调用的是Windows内核提供的内存分配和释放函数。

new使用示例:

BASIC_DISPLAY_DRIVER* pBDD = new(NonPagedPoolNx) BASIC_DISPLAY_DRIVER(pPhysicalDeviceObject);
if (pBDD == NULL)
{
    BDD_LOG_LOW_RESOURCE0("pBDD failed to be allocated");
    return STATUS_NO_MEMORY;
}

delete使用示例:

BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
if (pBDD)
{
   delete pBDD;
   pBDD = NULL;
}

调式模式下堆内存的0xcdcdcdcd

这里说明一下,在dbg模式下,将分配的内存全部置为0xcd,这和应用层在调试模式下堆的内存初始化为致。
0xcd其实这里是int指令的指令,再配合一个cd,就变成了int cd,说明直接行的是中断0xcd,这样CPU执行到此处就会出现中断异常。这和栈上的0xcc,int3的原理一致。
这里附一段相关反汇编指令代码:

00CC0100 CC                   int         3  
00CC0101 CD 05                int         5  
00CC0103 CD CD                int         0CDh  
00CC0105 CD CD                int         0CDh

新代码


void* __cdecl operator new(size_t size)
{
    return ExAllocatePoolWithTag(NonPagedPool, size, 'yTag');
}

void __cdecl operator delete(void* p,size_t a)
{
    ExFreePool(p);
}

void* __cdecl operator new[](size_t size)
{
    return ExAllocatePoolWithTag(NonPagedPool, size, 'yTag');
}

void __cdecl operator delete[](void* p)
{
    ExFreePool(p);
}

class CBase
{
public:
    int a;
};


   CBase* p = (CBase*)new CBase();  //operator new(size_t size)
   p->a = 10;
   delete p; //void __cdecl operator delete(void* p,size_t a)

0 篇笔记 写笔记

Windows内核驱动中使用newdelete
在Windows驱动中如果要分配内存,我们使用的ExAllocatePoolWithTag,ExAllocatePool,而释放内存时使用的是ExAllocatePoolWithTag和ExFreePool函数。我们知道,在内核中其实不是不能用C++,而是使用时有很大的限制。如果稍不留神,就会掉进......
DevCon dp_delete命令
从本地 (驱动程序) 中删除 OEM 驱动程序包的第三方。 此命令将删除 INF 文件、PNF 文件和关联的目录文件 (.cat) 。devcon [-f] dp_delete inf-f 即使设备当时正在使用驱动程序包,此参数也删除该驱动程序包。Inf INF 文件的 OEM*.inf 文件名......
删除锁IO_REMOVE_LOCK与STATUS_DELETE_PENDING
删除锁IO_REMOVE_LOCK很少见,但很重要。其结构体定义为:typedef struct _IO_REMOVE_LOCK { IO_REMOVE_LOCK_COMMON_BLOCK Common;#if DBG IO_REMOVE_LOCK_DBG_BLOCK Dbg;......
Windows系统USB驱动的断电异常处理STATUS_NO_SUCH_DEVICE
USB设备除非特殊需要,一般都是系统自带。所以我们根据不用开发相应的驱动,就算是我们要搞自定义的USB设备,微软也贴心的帮我们搞了一个WinUSB,只我们的的固件按照某定的要求,也可以实现自定义通讯。所以从上面的来看,没有什么特殊的地方要我们开发Windows系统的USB驱动。不过有的时候就是那么奇......
总线驱动IRP的中止AbortIrp
AbortIrp用于驱动即将卸载,但系统这时又下发了一个功能驱动过来。这时我们需要中止它,系统通过我们Abort它的状态也许不再下发功能IRP了。对于总线驱动,IRP一般分为三类:第一种是通用的功能IRP,如IRP_MJ_CLOSEIRP_MJ_CREATEIRP_MJ_DEVICE_CO......
C/C++技巧 临时大内存代替malloc/new
例如在某一函数中,需要频繁地申请数申请不定长数据内存,这样代码中大量充斥着很多的new ,delet或malloc,free。这样造成的结果就是实际功能没写多少,就不停地申请,判断,释放这样的操作了,严重地影响了我们写代码的流程。不爽啊!一般win32应用栈只有1M,故临时数据有限,而且随着函数......
STATUS_DELETE_PENDING
STATUS_DELETE_PENDING的官方解释为:A non-close operation has been requested of a file object that has a delete pending.这里指在进行文件操作时,出现了一种情况:请求对一个文件对象执行非关闭操作,......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!