五、隐藏服务:
普通情况下加载驱动需要 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”?自己试一下不就知道了:)
本文介绍了一种使用ZwLoadDriver函数隐秘加载驱动的方法,无需通过服务管理器注册,从而避免被常规工具检测到。
1537

被折叠的 条评论
为什么被折叠?



