用VXD技术实现的文件系统保护程序示例.docx
- 文档编号:16369326
- 上传时间:2023-07-12
- 格式:DOCX
- 页数:35
- 大小:147.85KB
用VXD技术实现的文件系统保护程序示例.docx
《用VXD技术实现的文件系统保护程序示例.docx》由会员分享,可在线阅读,更多相关《用VXD技术实现的文件系统保护程序示例.docx(35页珍藏版)》请在冰点文库上搜索。
用VXD技术实现的文件系统保护程序示例
用VXD技术实现的文件系统保护程序示例
要对Windows9x操作系统下的文件进行保护,只能通过驱动级开发来实现。
通常情况下是写一个InstallableFileSystemHook(IFSH,可安装文件系统挂钩程序)加载在系统中,然后在其中监控系统的文件操作。
当发现系统在作你希望监控的操作时,进行你需要的操作(此时系统并没有进行实际的操作,你赶在了系统操作之前)。
进行此项开发需要相应平台的IFSkit(可安装文件系统开发包),Windows9x的在它们的DDK中已经包含,但WindowsNT和Windows2000的IFSkit需要向微软购买(目前估价$6000,国内好象还没有,你自己找吧,看运气了)。
现在大部分杀毒软件号称的虚拟机技术就是我们将要介绍的基于IFS(可安装文件系统,下同)的文件系统操作技术。
不同的是它们是在文件操作之前检查一下特征码,看有没有感染病毒,而我们所要作的是检查一下该文件是否允许存取,对它们作相应的保护。
下面我们以一个用于指定的文件的操作保护的程序为例介绍一下这种技术。
我们把它设计成为对磁盘(逻辑盘)、具体文件作相应保护的工具。
为了简化起见,我们只启用了防删除保护。
同样的原理你也可以自己扩充功能。
完整的源代码可以从以下网址下载:
并且在不断发展更新中,欢迎时常访问本站并更新你的代码。
本套程序包括后台VXD驱动程序和前台程序两个部分。
本程序开发环境如下:
Windows98第二版
VC++6.0专业版
VTOOLSD3.0(DRIVERSTUDIO2.0中自带的)
一、后台VXD程序的生成和编写
我们用VXD辅助开发工具VTOOLSD3.0版本来生成程序框架。
1.设置一般选项
打开vtoolsd的QuickVxd后将设备参数页作如下设置:
其中在设备名框中输入的”FILHOOK”将作为生成的设备名出现在系统中,你可以用Vtoolsd自带的vxdviewer查看系统中加载的驱动程序,如果你已经成功加载此驱动程序,你将看到如下图所示的画面:
证明已经加载入系统中。
2.程序入口方式设置
一般情况下,我们在windows9x下加载的VXD驱动程序都必需使用”ProtectedMode”保护模式方式。
关于详细的说明,请参阅本专栏前面的文章中的介绍。
3.必需响应的系统消息
由于我们的驱动程序要求必需能动态加载,而且能够响应win32应用程序的控制,并与Win32前台程序交互作用,所以必需响应系统的如下三个消息(由操作系统的虚拟机管理器VMM发给我们的驱动程序的系统通知消息):
SYS_DYNAMIC_DEVICE_EXIT:
驱动程序动态卸载通知消息
SYS_DYNAMIC_DEVICE_INIT:
驱动程序动态加载通知消息
W32_DEVICEIOCONTROL:
WIN32设备输入输出控制消息(由win32前台程序发给VXD驱动程序的消息)
生成框架后,我们再加入自己的代码。
第一部分:
实现文件定义。
//-mainmoduleforVxDFILEHOOK
#defineDEVICE_MAIN
#include"filehook.h"
Declare_Virtual_Device(FILEHOOK)//VXD设备名
#undefDEVICE_MAIN
//此处为我们加入的控制消息定义,注意,这里的消息不是windows消息,而是由DeviceIoControl函数发给VXD的消息。
#defineREMOVE_DRV100//删除在保护列表中的一个驱动器
#defineREMOVE_FILE101//删除在文件列表中的一个文件
#defineREMOVE_DIR102//删除在目录列表中的一个目录名
#defineADD_DIR103//添加要保护的目录名到列表中
#defineADD_DRV104//添加要保护的驱动器到列表中
#defineADD_FILE105//添加要保护的文件名到列表中
#defineSTARTP106//启动保护
#defineSTOPP107//停止保护
#definePREAD10//读保护
#definePDELETE11//删除保护,目前我们只实现此保护
#definePWRITE12//写保护
#definePALL13//保护所有的操作
#definePCREATE14//禁止创建文件
由于时间关系,我们只实现了文件删除保护和驱动器删除保护。
其它的保护只是响应不同的系统操作类型而已。
(目录操作保护和文件操作保护机理不同,另文探讨)
FilehookVM:
:
FilehookVM(VMHANDLEhVM):
VVirtualMachine(hVM){}
FilehookThread:
:
FilehookThread(THREADHANDLEhThread):
VThread(hThread){}
BOOLFilehookDevice:
:
OnSysDynamicDeviceInit()
{
PrevHook=IFSMgr_InstallFileSystemApiHook(MyIfsHook);//安装文件系统挂钩回调函数
//初始化数据成员
FILE=DIR=NULL;
//将目录和文件列表指针初始化为NULL,实际上,文件名和目录列表都是一个单链表,你也可以用hash表等来实现。
ENDFILE=FILE;//初始化尾指针
ENDFILE->Next=NULL;//将尾指针的下一个元素指针初始化为NULL
ENDDIR=DIR;
ENDDIR->Next=NULL;
for(inti=0;i<26;i++)
DRIVER[i].iIsIn=0;
//将驱动器列表初始化,此时表时没有驱动器,当加入驱动器时,只需要将相应的元素的iIsIn域置为1即可。
//以下代码打开日志文件,调用的是Ring0级的文件i/o函数,当然,此时的日志很简单,只记录了什么文件被保护,什么文件被企图删除
WORDpAction;
BYTEpError;
:
:
logfile=R0_OpenCreateFile(true,"",OPEN_ACCESS_WRITEONLY,ATTR_NORMAL,ACTION_IFNOTEXISTS_CREATE|ACTION_IFEXISTS_TRUNCATE,R0_NO_CACHE,&pAction,&pError);
//logfile为全局日志文件句柄
:
:
WriteLog(logfile,"开始记录");
returnTRUE;
}
BOOLFilehookDevice:
:
OnSysDynamicDeviceExit()//动态卸载事件响应函数
{
//删除动态分配的内存,这些内存是在前台程序加入文件或目录到保护列表时动态分配的
FT*temp;//临时指针变量
while(FILE!
=NULL)//文件列表
{
temp=:
:
FILE;
:
:
FILE=:
:
FILE->Next;
deletetemp;
}
while(DIR!
=NULL)//目录列表
{
temp=:
:
DIR;
:
:
DIR=:
:
DIR->Next;
deletetemp;
}
:
:
WriteLog(logfile,"正常结束运行!
");//记入日志
WORDpError;
R0_CloseFile(logfile,&pError);//关闭日志文件
IFSMgr_RemoveFileSystemApiHook(MyIfsHook);//卸载文件挂钩回调用函数
returnTRUE;
}
DWORDFilehookDevice:
:
OnW32DeviceIoControl(PIOCTLPARAMSpDIOCParams)//前台控制消息响应函数
{
switch(pDIOCParams->dioc_IOCtlCode)//检查操作类型,这些消息是在前面定义的
{
caseADD_FILE:
//添加文件
FT*file,*pfile;
pfile=(FT*)pDIOCParams->dioc_InBuf;//生成一个FT类型的指针并指向传递过来的内存区域
WriteLog(logfile,"添加文件");//记入日志,当然在正式发行时可以去掉,这里是为了调试方便
WriteLog(logfile,pfile->PathName);//记录添加的文件名,可以和前台的对比,看有没有误传,这里也是为了调试方便
file=newFT;//分配内存
if(file!
=NULL)
{
memcpy(file,pfile,sizeof(FT));//将传递过来的内存块保存下来,以下代码是典型的链表操作
if(:
:
FILE==NULL)//如果是列表中的第一个文件
:
:
FILE=file;
else//接下来的文件
:
:
ENDFILE->Next=file;
file->Next=NULL;
ENDFILE=file;
}
break;
caseADD_DIR:
//添加目录,与上面的代码类似
FT*dir,*pdir;//目录和文件实际上相似,所以用相同的结构定义
pdir=(FT*)pDIOCParams->dioc_InBuf;
dir=newFT;
if(dir!
=NULL)
{
memcpy(dir,pdir,sizeof(FT));
if(:
:
DIR==NULL)
:
:
DIR=dir;
else
:
:
ENDDIR->Next=dir;
dir->Next=NULL;
:
:
ENDDIR=dir;
}
break;
caseADD_DRV:
//添加驱动器,将相应的元素的iIsIn设为1即可;如:
如果加入的是A盘,就将下标为0的元素的iIsIn设为1,依次类推。
DT*driver;//DT和FT都是结构
driver=(DT*)pDIOCParams->dioc_InBuf;//取得传入的参数
if(driver->iIsIn>='A'&&driver->iIsIn<='Z')//检查传入的参数合法性,只允许A-Z字符传入。
{
DRIVER[driver->iIsIn-'A'].iIsIn=1;//将相应的置1
DRIVER[driver->iIsIn-'A'].iProtype=driver->iProtype;
}
break;
default:
break;
}
return0;
}
int_cdeclMyIfsHook(pIFSFuncpfn,intfn,intDrive,intResType,intCodePage,pioreqpir)
//挂钩回调函数
{
_QWORDresult;//取文件名时的返回值域,详见vtoolsd的帮助
unsignedchar*path;//取得的路径指针
ints;
char*action;//调试用变量,配合dout函数你可以在DriverMonitor中看到它的值
switch(fn)
{
caseIFSFN_OPEN:
action="打开文件";
/*
path=(unsignedchar*)malloc(pir->ir_ppath->pp_totalLength+3);
if(path!
=NULL)
{
path[0]=Drive+'A'-1;
path[1]=':
';
UniToBCSPath(path+2,pir->ir_ppath->pp_elements,pir->ir_ppath->pp_totalLength,BCS_OEM,&result);
strcpy(FileName,(char*)path);
free(path);
}
else
action="分配内存失败!
";
*/
break;
caseIFSFN_READ:
action="读取文件";
break;
caseIFSFN_WRITE:
action="写出文件";
break;
caseIFSFN_RENAME:
action="更名文件";
break;
caseIFSFN_DELETE:
action="删除文件";
path=(unsignedchar*)malloc(pir->ir_ppath->pp_totalLength+3);
if(path!
=NULL)
{
path[0]=Drive+'A'-1;
path[1]=':
';
UniToBCSPath(path+2,pir->ir_ppath->pp_elements,pir->ir_ppath->pp_totalLength,BCS_OEM,&result);//取得文件路径,并将用unicode表示的文件路径名转换为C语言风格的字符串,由Vtoolsd提供的例程。
strcpy(FileName,(char*)path);
for(inti=0;i<26;i++)//判断是否驱动器保护
if(DRIVER[Drive-1].iIsIn!
=0)
{
WriteLog(logfile,"由于该驱动器保护,以下文件不能被删除:
");
WriteLog(logfile,FileName);
return0;
}
FT*temp;
for(temp=FILE;temp!
=NULL;temp=FILE->Next)//判断是不是在操作受保护的文件
//注意:
一般情况下的删除操作只是将文件改名放到回收站中,所以得不到保护。
这里保护的只是直接按住shift键后删除的文件。
如果要保护放到加收站中的文件,需要监视文件更名操作,并且首先要得知回收站文件夹的路径。
{
if(!
strcmp(temp->PathName,(constchar*)path))//是的话就保护
{
WriteLog(logfile,"由于保护以下文件不能被删除!
");
WriteLog(logfile,temp->PathName);
return0;//直接返回就行了,这样其它的ifshook函数就得不到动作的机会,包括操作系统的API函数。
}
}
free(path);
}
else
action="分配内存失败!
";
break;
caseIFSFN_DIR:
action="目录操作";
break;
}
//如果在Drivermoniter中监视的话可以
return(*PrevHook)(pfn,fn,Drive,ResType,CodePage,pir);//传给下一个hook函数
}
头文件定义:
//FILEHOOK.h-includefileforVxDFILEHOOK
#include
#defineDEVICE_CLASSFilehookDevice
#defineFILEHOOK_DeviceIDUNDEFINED_DEVICE_ID
#defineFILEHOOK_Init_OrderUNDEFINED_INIT_ORDER
#defineFILEHOOK_Major1
#defineFILEHOOK_Minor0
classFilehookDevice:
publicVDevice
{
public:
virtualBOOLOnSysDynamicDeviceInit();
virtualBOOLOnSysDynamicDeviceExit();
virtualDWORDOnW32DeviceIoControl(PIOCTLPARAMSpDIOCParams);
//intFilehookDevice:
:
MyIfsHook(pIFSFuncpfn,intfn,intDrive,intResType,intCodePage,pioreqpir);
};
classFilehookVM:
publicVVirtualMachine
{
public:
FilehookVM(VMHANDLEhVM);
};
classFilehookThread:
publicVThread
{
public:
FilehookThread(THREADHANDLEhThread);
};
//------------------------------------------------------------以上代码为vtoolsd自动生成代码
int_cdeclMyIfsHook(pIFSFuncpfn,intfn,intDrive,intResType,intCodePage,pioreqpir);
//------------------------------------------------------------
ppIFSFileHookFuncPrevHook;//保存以前的钩子函数的变量
charFileName[512];
//------------------------------------------------------------
char*GetResTypeString(intrestype)//读取操作的文件系统类型
{
switch(restype)
{
caseIFSFH_RES_UNC:
return"IFSFH_RES_UNC";
caseIFSFH_RES_NETWORK:
return"IFSFH_RES_NETWORK";
caseIFSFH_RES_LOCAL:
return"IFSFH_RES_LOCAL";
caseIFSFH_RES_CFSD:
return"IFSFH_RES_CFSD";
caseIFSFH_RES_NETWORK+IFSFH_RES_UNC:
return"IFSFH_RES_NETWORK(UNC)";
caseIFSFH_RES_LOCAL+IFSFH_RES_UNC:
return"IFSFH_RES_LOCAL(UNC)";
caseIFSFH_RES_CFSD+IFSFH_RES_UNC:
return"IFSFH_RES_CFSD(UNC)";
default:
return"Unknown";
}
}
//-----------------------------------------------------------
voidWriteLog(HANDLElogfile,char*log)//日志记载函数
{
WORDpError;
staticintlogoffset=0;//记录日志文件的偏移量,R0级的文件函数实际上是文件中断调用的简单封装。
chartemp[512];
strcpy(temp,log);
temp[strlen(log)]='\r';
temp[strlen(log)+1]='\n';
temp[strlen(log)+2]='\0';
R0_WriteFile(true,logfile,temp,strlen(temp),logoffset,&pError);//调用ring0级写文件函数
logoffset+=strlen(temp);
}
//-----------------------------------------------------------
typedefstructFile_Type//FT文件类型定义
{
shortintDriver;
charPathName[512];
structFile_Type*Next;
shortintiProType;//保护类型
}FT;//文件项
FT*DIR,*ENDDIR;//保护目录列表头指针
FT*FILE,*ENDFILE;//保护文件列表头指针
typedefstructDriver_Type//驱动器类型定义
{
shortintiIsIn;
shortintiProtype;//保护类型
}DT;
DTDRIVER[26];//要保护的驱动器
HANDLElogfile;
重要提示:
在作文件读、写操作时请不要再作取文件名的操作,此时由于这些操作的连续性,将导致使机重资源急剧消耗,大部分情况下将导致蓝屏死机。
//------------------------------------------------------
以下为前台程序
在程序中添加三个对话框,分别添加目录,添加文件名,添加驱动器。
目录添加对话框的头文件(类定义部分)
//--------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//CAddDirdialog
classCAddDir:
publicCDialog
{
//Construction
public:
CAddDir(CWnd*pParent=NULL);//standardconstructor
//DialogData
//{{AFX_DATA(CAddDir)
enum{IDD=IDD_DIALOG2};
CStringm_dir;//添加一个数据成员,和一个编辑框关联
//}}AFX_DATA
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAddDir)
public:
protected:
virtualvoidDoDataExchange(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VXD 技术 实现 文件系统 保护 程序 示例