五、隐藏服务:
普通情况下加载驱动需要 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的使用例子:
请注意上面这段代码中加载驱动时所使用的注册表路径格式是:
“//Registry//Machine//System//CurrentControlSet//Services//neverdeath”
而不是:
“HKEY_LOCAL_MACHINE//SYSTEM//CurrentControlSet//Services//neverdeath”
也许你已经想到了那么卸载驱动会不会就是函数“ZwUnloadDriver”?自己试一下不就知道了:)
普通情况下加载驱动需要 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 ;
}
{
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”?自己试一下不就知道了:)