一 测试:
1 我的测试环境是:VMWare+W2KSP3,使用命令:net use e: //nulsvr/share
2 修改sys和dll文件使它们能输出LOG信息,发现每次开一个资源管理器,每刷新一次,都会引发DLL的NPGetConnection函数,查询的盘符从第1个可用的空盘符开始,如系统中只有一个C盘,那么就从D盘开始,直到Z盘;它向SYS发出一个IOCTL_NULMRX_GETCONN的查询,SYS在NulMRxDevFcbXXXControlFile函数的IOCTL_NULMRX_GETCONN操作码中响应,如果按上面的命令映射成了一个网络驱动器后,将会进入RDBSS_NTC_V_NETROOT这个判断,碰到正确的盘符时则返回成功,否则错误。
3 映射成功后,每刷新一次资源管理器,如果盘符正确,则会调用NulMRxQueryVolumeInformation函数,进入
case FileFsFullSizeInformation:
case FileFsSizeInformation:
目前对于这两个都空操作;
4 往里面拷贝文件时,会进入NulMRxQueryDirectory函数的case FileBothDirectoryInformation:,任何文件到里面都只能生成一个名为"."的文件,因为这是SYS返回的固定值,必须自定义它;
二 分析:
1 函数功能:
DriverEntry:驱动入口;RxRegisterMinirdr注册,调用NulMRxInitializeTables初始化各种操作的函数指针表;调用NulMRxReadRegistryParameters读取注册表值;NulMRxReadRegistryParameters:打开"//Registry//Machine//System//CurrentControlSet//Services//NulMRx//Parameters"键,如果失败,再查询“LogRate”子键的值;
NulMRxInitializeTables:初始化各种操作的函数指针;
NulMRxDevFcbXXXControlFile:操作类型分发函数;
IRP_MJ_FILE_SYSTEM_CONTROL:空操作;
IRP_MJ_DEVICE_CONTROL:定义了IOCTL_NULMRX_ADDCONN,IOCTL_NULMRX_DELCONN等供DLL调用的操作;
NulMRxCreateSrvCall:创建服务调用实例;
NulMRxFinalizeSrvCall:注销服务调用实例;
NulMRxQueryDirectory:查询目录信息;
NulMRxQueryVolumeInformation:查询卷信息;
NulMRxQueryFileInformation:查询文件信息;
NulMRxSetFileInformation:设置文件信息;
NulMRxRead:读
NulMRxWrite:写
NulMRxCompleteBufferingStateChangeRequest:空
NulMRxNotifyChangeDirectory:空
NulMRxLocks:空
NulMRxComputeNewBufferingState:空
NulMRxSetFileInformationAtCleanup:空
NulMRxStart:空;
NulMRxStop:空;
NulMRxUpdateNetRootState:空;
NulMRxUpdateNetRootState:空;
NulMRxFinalizeNetRoot:空;
NulMRxFinalizeVNetRoot:空;
NulMRxFlush:空;
NulMRxForcedClose:空;
NulMRxDeallocateForFcb:空
NulMRxDeallocateForFobx:空
NulMRxSetEaInformation:空
NulMRxQuerySecurityInformation:空
NulMRxSetSecurityInformation:空
NulMRxCreate:创建并打开,?;
NulMRxCloseSrvOpen:关闭,?
NulMRxQueryEaInformation:?
NulMRxCleanupFobx:?
NulMRxTruncate:?
NulMRxExtendFile:?
NulMRxShouldTryToCollapseThisOpen:?
NulMRxCollapseOpen:?
NulMRxExtractNetRootName:?
NulMRxCreateVNetRoot:?
NulMRxSrvCallWinnerNotify:?
2 源文件:
Devctrl.c: 只有一个函数NulMRxIoCtl(),注释上说是执行IOCTL操作,但函数内容是空的;
Devfcb.c:
NulMRxDevFcbXXXControlFile():处理所有的设备FCB操作,DLL通过DeviceIoControl发出的查询都在这个
函数中处理;
NulMRxCreateConnection():创建连接;
NulMRxDeleteConnection():注销连接
GetConnectionHandle():被调用的函数,通过CreateFile返回连接句柄;
DoCreateConnection():实际的创建操作;
DoDeleteConnection():实际的注销操作;
这几个函数的关系是:
1) NulMRxDevFcbXXXControlFile(): case IOCTL_NULMRX_ADDCONN: -> NulMRxCreateConnection(): ->
DoCreateConnection() -> GetConnectionHandle()
2) NulMRxDevFcbXXXControlFile(): case IOCTL_NULMRX_DELCONN: -> NulMRxDeleteConnection(): ->
DoDeleteConnection()
查看SYS打印的调试信息并没有发现ADDCONN和DELCONN调用,估计它们是在系统启动和关机时被调用的,所以看不到;
Downlvli.c:
NulMRxTruncateFile(): 截短文件;
NulMRxExtendFile(): 扩展文件;
目前这两个函数都是空操作;
Ea.c:EA的含义:Extended Attributes
NulMRxQueryEaInformation():查询文件的扩展属性;
NulMRxSetEaInformation():设置文件的扩展属性;
Fileinfo.c:执行文件/目录/卷的查询和更新函数;
NulMRxQueryDirectory():目录查询,目前只返回".";
NulMRxQueryVolumeInformation():卷查询,大部分都是空操作;
NulMRxQueryFileInformation():文件查询,大部分都是空操作;
NulMRxSetVolumeInformation():设置卷信息,空;
NulMRxSetFileInformation():设置文件信息,大部分都是空操作;
NulMRxSetFileInformationAtCleanup():在注销时设置文件信息,空;
Init.c:驱动入口及注销函数,包含DriverEntry,Unload等;
Locks.c:
NulMRxLocks():空;
NulMRxCompleteBufferingStateChangeRequest():空;
NulMRxFlush():空;
Netroot.c:创建或注销Net root;
NulMRxCreateVNetRoot():创建Net Root,并确认输入的名称是否"share"(不区分大小写),如果不是返回错误;
Notimpl.c:文件系统控制有关的函数,目前都是空操作;
Openclose.c:执行文件/目录的打开和关闭;
Read.c:处理网络的读请求,只有一个函数;
NulMRxRead(): 读入
Write.c:处理网络的写请求,只有一个函数;
NulMRxWrite():空
Rename.c:执行Rename操作;
NulMRxRename():空
Srvcall.c:
ExecuteCreateSrvCall():确认路径是否"/nulmrx/"(不区分大小写),如果不是返回错误;
Transprt.c:执行SMB连接请求的传输;
NulMRxInitializeTransport():空;
NulMRxUninitializeTransport():空;
3 每次只能显示一个文件是因为在NulMRxQueryDirectory中,case FileBothDirectoryInformation: 根据传入的RxContext->QueryDirectory.InitialQuery的值来判断,在第1次查询时此值为TRUE,返回成功;第2次此值为FALSE,返回STATUS_NO_MORE_FILES,所以不会再有下一次查询了;
三 DLL层
1 NPEnumResource被系统上层调用,返回该服务的名称,如NulMrx返回"Sample Network";