当前位置: 代码迷 >> 综合 >> 《Windows内核安全与驱动编程》-第十章-磁盘的过滤学习-day4
  详细解决方案

《Windows内核安全与驱动编程》-第十章-磁盘的过滤学习-day4

热度:57   发布时间:2023-12-04 05:43:27.0

10.3.6 bitmap 的作用和分析

? 在之前我们多次看到了bitmap,但是却一直不知道它是什么,它的作用是干嘛。接下来我们去看,但是具体的bitmap 的实现很复杂,如果没有特殊兴趣的话,可以只看它的接口说明,而不管具体的实现过程。

? 顾名思义,bitmap就是一个位图。它实际上是一些内存块,这些内存块的每一位用来标识一个磁盘上的最小访问单位,一般情况下是一个扇区。每一位可以被设置或者清除,用来标识这个扇区的两种对应状态。

? 因为我们要对磁盘进行还原,所以需要将数据存储到其他地方。所以bitmap上的每一位对应一个扇区,有多少个扇区就有多少个位。这个位为0则表示:这个位所对应的扇区的数据没有被存储到其他的地方。这个位为1则表示:这个位对应的扇区的数据被存储到其他地方了。

? bitmap的生命周期,为这次保护系统启动直到系统重启。我们在读写数据的时候,根据bitmap的位为0还是1,来判断从哪里读或者写到哪里去。而重启之后,所有的bitmap位都归零,这时无论什么操作都不会到转存处拿数据,也就达到了去保护的功能。

? 之所以说bitmap是一些内存块而不是一个连续的内存,是因为在涉及bitmap的时候考虑到它所表示的位图可能对应着很大一块磁盘区域,即使是用1位来表示512字节的数据也有可能是很大的一片内存空间。所以在设计bitmap的时候需要按需分配内存。只有在用到的时候才去对应分配,这样就可以达到节约空间的目的。

首先来看bitmap的数据结构。

typedef unsigned char tBitmap;typedef struct _DP_BITMAP_
{
    //这个卷中的每个扇区有多少字节,这同样也说明了bitmap中一个位所对应的字节数unsigned long sectorSize; //每个byte里面有几个bit,一般情况下是8unsigned long byteSize; //每个块是多大byte,unsigned long regionSize;//这个bitmap总共有多少个块unsigned long regionNumber;//这个块对应了多少个实际的byte,这个数字应该是sectorSize*byteSize*regionSizeunsigned long regionReferSize;//这个bitmap对应了多少个实际的byte,这个数字应该是sectorSize*byteSize*regionSize*regionNumber__int64 bitmapReferSize;//指向bitmap存储空间的指针tBitmap** Bitmap; //用于存取bitmap的锁void* lockBitmap; 
} DP_BITMAP, * PDP_BITMAP;

? 这里在开头可以看到,将 char 重命名为 tBitmap,然后在最后创建了一个 tBitmap ** Bitmap 的指针元素,实际上等效于 **char ****。这样做,是希望我们将 Bitmap看做一个指针数组。这个数组共有 regionSize个元素,每个元素就是一个指向内存块的指针。这些指针首先指向空的内存块(并不是实际上的,只是指针为空)。看一下初始化bitmap的代码。

NTSTATUS DPBitmapInit(DP_BITMAP **     bitmap,unsigned long       sectorSize,unsigned long       byteSize,unsigned long       regionSize,unsigned long       regionNumber)
{int i = 0;DP_BITMAP * myBitmap = NULL;NTSTATUS status = STATUS_SUCCESS;//检查参数,以免使用了错误的参数导致发生处零错等错误if (NULL == bitmap || 0 == sectorSize ||0 == byteSize || 0 == regionSize  || 0 == regionNumber){return STATUS_UNSUCCESSFUL;}__try{//分配一个bitmap结构,这是无论如何都要分配的,这个结构相当于一个bitmap的handle	if (NULL == (myBitmap = (DP_BITMAP*)DPBitmapAlloc(0, sizeof(DP_BITMAP)))){status = STATUS_INSUFFICIENT_RESOURCES;__leave;}//清空结构memset(myBitmap, 0, sizeof(DP_BITMAP));//根据参数对结构中的成员进行赋值myBitmap->sectorSize = sectorSize;myBitmap->byteSize = byteSize;myBitmap->regionSize = regionSize;myBitmap->regionNumber = regionNumber;myBitmap->regionReferSize = sectorSize * byteSize * regionSize;myBitmap->bitmapReferSize = (__int64)sectorSize * (__int64)byteSize * (__int64)regionSize * (__int64)regionNumber;//分配出regionNumber那么多个指向region的指针,这是一个指针数组if (NULL == (myBitmap->Bitmap = (tBitmap **)DPBitmapAlloc(0, sizeof(tBitmap*) * regionNumber))){status = STATUS_INSUFFICIENT_RESOURCES;__leave;}//清空指针数组memset(myBitmap->Bitmap, 0, sizeof(tBitmap*) * regionNumber);* bitmap = myBitmap;status = STATUS_SUCCESS;}__except(EXCEPTION_EXECUTE_HANDLER){status = STATUS_UNSUCCESSFUL;}if (!NT_SUCCESS(status)){if (NULL != myBitmap){DPBitmapFree(myBitmap);}* bitmap = NULL;}return status;
}

? 可以看出,这里使用了 DPBitmapAlloc 来分配内存,但是在后续中,使用了许多接口,并且较为复杂,鉴于实际应用性不强,本人目前感觉学习意义不大,所以停止对该章的学习。

明日计划

从明天开始慢慢啃文件系统的过滤与监控吧,似乎还挺有意思的。

  相关解决方案