五、隐藏服务:
普通情况下加载驱动需要 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”?自己试一下不就知道了:)