五、隐藏服務:
普通情況下加載驅動需要 OpenSCManager->CreateService->StartService,這樣驅動就會跑到服務管理器中去注冊一下自己,并且要隐藏這樣加載驅動的服務,不是不行,隻是太麻煩而且沒效率了。要hook一大堆的服務函數。不過在逆向IS的時候發現了一個不需要去服務管理器注冊而直接加載驅動的方法。就是使用ZwLoadDriver(這個函數通常是ring0中加載驅動時用,由于被Ntdll.dll導出,ring3就也能用了)進行直接加載。這樣就不用去服務管理器中注冊自己,并且這樣加載的驅動windows系統工具中的“系統資訊”檢視器也查不到你,更不用說那些什麼服務管理器之類的東東了。屢用不爽。下面介紹一下用法:
1、首先自己在系統資料庫的服務項中添加一個自己的服務名字項。
2、在自己添加的服務名字項中添加一些驅動資訊(其實就是手工實作CreateService()函數對系統資料庫的那些操作),這些資訊包括“ErrorControl”,“ImagePath”,“Start”,“Type”等等。你要手工設定這些鍵以及鍵值。
按上面設定完後,來看看ZwLoadDriver的原形:
NTSTATUS
ZwLoadDriver(
IN PUNICODE_STRING DriverServiceName );
下面的代碼給出了ZwLoadDriver的使用例子:
AnotherWayStartService( TCHAR * szDir )
{
HKEY RegKey;
HKEY hLicenses;
DWORD disp;
DWORD ErrorControl = NULL;
DWORD ProcessID;
DWORD Start = 3 ;
DWORD Type = 1 ;
LONG Regrt;
DWORD ZwLoadDriver;
DWORD RtlInitUnicodeString;
UNICODE_STRING RegService;
PCWSTR RegServicePath = L " /Registry/Machine/System/CurrentControlSet/Services/neverdeath " ;
TCHAR DriverFilePath[MAX_PATH] = " /??/ " ;
Regrt = RegOpenKeyEx (
HKEY_LOCAL_MACHINE,
" SYSTEM/CurrentControlSet/Services " ,
0 ,
KEY_CREATE_SUB_KEY + KEY_SET_VALUE,
& hLicenses );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
Regrt = RegCreateKeyEx (
hLicenses,
" neverdeath " ,
0 ,
"" ,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
& RegKey,
& disp );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
Regrt = RegOpenKeyEx (
HKEY_LOCAL_MACHINE,
" SYSTEM/CurrentControlSet/Services/neverdeath " ,
0 ,
KEY_CREATE_SUB_KEY + KEY_SET_VALUE,
& RegKey );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
Regrt = RegSetValueEx (
RegKey,
" ErrorControl " ,
NULL,
REG_DWORD,
( const unsigned char * )( & ErrorControl),
4 );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
strcat(DriverFilePath, szDir);
Regrt = RegSetValueEx (
RegKey,
" ImagePath " ,
NULL,
REG_EXPAND_SZ,
( const unsigned char * )( & DriverFilePath),
strlen( DriverFilePath ) );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
Regrt = RegSetValueEx (
RegKey,
" Start " ,
NULL,
REG_DWORD,
( const unsigned char * )( & Start),
4 );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
Regrt = RegSetValueEx (
RegKey,
" Type " ,
NULL,
REG_DWORD,
( const unsigned char * )( & Type),
4 );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
// 還記得前面隐藏程序時,我們程序ID是從系統資料庫中取的
// 下面就是把程序ID寫入系統資料庫,不會影響驅動的加載
ProcessID = GetCurrentProcessId();
Regrt = RegSetValueEx (
RegKey,
" ProcessID " ,
NULL,
REG_DWORD,
( const unsigned char * )( & ProcessID),
4 );
if ( Regrt != ERROR_SUCCESS )
{
return false ;
}
CloseHandle( RegKey );
ZwLoadDriver = (DWORD) GetProcAddress (
GetModuleHandle( " ntdll.dll " ),
" ZwLoadDriver " );
RtlInitUnicodeString = (DWORD) GetProcAddress(
GetModuleHandle( " ntdll.dll " ),
" RtlInitUnicodeString " );
_asm
{
pushad
push RegServicePath
lea edi, RegService
push edi
call RtlInitUnicodeString // 裝載UNICODE字元
lea edi, RegService
push edi
call ZwLoadDriver
popad
}
return true ;
}
請注意上面這段代碼中加載驅動時所使用的系統資料庫路徑格式是:
“//Registry//Machine//System//CurrentControlSet//Services//neverdeath”
而不是:
“HKEY_LOCAL_MACHINE//SYSTEM//CurrentControlSet//Services//neverdeath”
也許你已經想到了那麼解除安裝驅動會不會就是函數“ZwUnloadDriver”?自己試一下不就知道了:)