加载windows内核模块的又一个方法
加载驱动比较常规的方法是先后调用openSCmanager()/CreateService()/StartService()等API,这里介绍的是rootkit migbot中展现的一种方法,使用了MS未公开的API。该方法不需要创建注册表键就可以将driver加载入系统中,有利于rootkit的隐藏。下边展示一下这种技术:
编写一个内核模块sxg.sys:
#include <ntddk.h> NTSTATUS DriverEntry(PDRIVER_OBJECT obj, PUNICODE_STRING reg){ DbgPrint("DriverEntry..."); return STATUS_SUCCESS; }
|
编写loader:
#include <stdio.h> #include <windows.h>
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;
typedef long NTSTATUS; #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef NTSTATUS (__stdcall *ZWSETSYSTEMINFORMATION)( DWORD SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength );
typedef VOID (__stdcall *RTLINITUNICODESTRING)( PUNICODE_STRING DestinationString, PCWSTR SourceString );
ZWSETSYSTEMINFORMATION ZwSetSystemInformation; RTLINITUNICODESTRING RtlInitUnicodeString;
typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE { UNICODE_STRING ModuleName; } SYSTEM_LOAD_AND_CALL_IMAGE, *PSYSTEM_LOAD_AND_CALL_IMAGE;
#define SystemLoadAndCallImage 38
int main() { SYSTEM_LOAD_AND_CALL_IMAGE GregsImage; WCHAR daPath[] = L"\\??\\D:\\sxg.sys"; NTSTATUS status; RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress( GetModuleHandle("ntdll.dll"), "RtlInitUnicodeString"); if (NULL == RtlInitUnicodeString) { printf("Failed to get RtlInitUnicodeString\r\n"); return -1; } ZwSetSystemInformation = (ZWSETSYSTEMINFORMATION)GetProcAddress( GetModuleHandle("ntdll.dll"), "ZwSetSystemInformation"); if (NULL == ZwSetSystemInformation) { printf("Failed to get ZwSetSystemInformation\r\n"); return -1; }
RtlInitUnicodeString(&(GregsImage.ModuleName), daPath); status = ZwSetSystemInformation(SystemLoadAndCallImage, &GregsImage, sizeof(SYSTEM_LOAD_AND_CALL_IMAGE)); if(!NT_SUCCESS(status)){ printf("Failed to load sys\r\n");return -1;} else printf("driver loaded!\n"); return 0; }
|
通过debugger可看到,“DriverEntry...”字样被打印出来,说明驱动已被加载。这种方法将驱动映像加载到了可分页的内存区域,对于内核模块来说,这是非常危险的,需要在驱动中将代码拷贝到不可分页内存区域之后再执行其他功能,不然蓝屏重启的概率很大很大。另外一点就是,通过这种方法加载的内核模块无法动态卸载,只能等到重启之后了。本测试在windows xp sp3上测试的。
song.xian-guang#hotmail.com
http://sxg.cublog.cn
http://blog.chinaunix.net/u/8754/showart_1953096.html
阅读(3196) | 评论(0) | 转发(0) |