[资料] http://www.cppblog.com/sleepwom/archive/2009/10/24/99375.html
继 HOOK SSDT Hide Process (七)
用 HOOK SSDT Hide Process (七) 的代码虽然隐藏了进程,但会导致在 taskmgr.exe 全部进程看不到
而且运行一段时间后, taskmgr.exe 就会非法关闭
Q:
今天突然发现,如果 taskmgr.exe 中选中了 'Show processes from all users' 选项,还是可以看到其它进程的(taskmgr.exe成功隐藏),但为什么不选中就所以进程看不到?这么鬼异的问题估计要OD下 taskmgr.exe 才知道
为了一查究竟,我把 MyZwQuerySystemInformation 修改成如下的代码
用 HOOK SSDT Hide Process (七) 的代码虽然隐藏了进程,但会导致在 taskmgr.exe 全部进程看不到
而且运行一段时间后, taskmgr.exe 就会非法关闭
Q:
今天突然发现,如果 taskmgr.exe 中选中了 'Show processes from all users' 选项,还是可以看到其它进程的(taskmgr.exe成功隐藏),但为什么不选中就所以进程看不到?这么鬼异的问题估计要OD下 taskmgr.exe 才知道
为了一查究竟,我把 MyZwQuerySystemInformation 修改成如下的代码
NTSTATUS MyZwQuerySystemInformation(IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength) // 定义自己的Hook函数
{
NTSTATUS rc;
UNICODE_STRING process_name;
RtlInitUnicodeString( & process_name, L " taskmgr.exe " );
rc = (OldZwQuerySystemInformation) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (NT_SUCCESS(rc))
{
if ( 5 == SystemInformationClass)
{
struct _SYSTEM_PROCESSES * curr = ( struct _SYSTEM_PROCESSES * )SystemInformation;
struct _SYSTEM_PROCESSES * prev = NULL;
// if(curr->NextEntryDelta)
// curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta);
while (curr)
{
KdPrint(( " ProcessName:%wZ NextEntryDelta:%d \n " , & curr -> ProcessName, curr -> NextEntryDelta));
if (curr -> NextEntryDelta)
curr = (_SYSTEM_PROCESSES * )((ULONG)curr + curr -> NextEntryDelta);
else
curr = NULL;
} // while(curr)
UnHook();
} // if(5 == SystemInformationClass)
} // if(NT_SUCCESS(rc))
// KdPrint(("HookZwQuerySystemInformation is Succeessfully. \n"));
return rc;
}
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength) // 定义自己的Hook函数
{
NTSTATUS rc;
UNICODE_STRING process_name;
RtlInitUnicodeString( & process_name, L " taskmgr.exe " );
rc = (OldZwQuerySystemInformation) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (NT_SUCCESS(rc))
{
if ( 5 == SystemInformationClass)
{
struct _SYSTEM_PROCESSES * curr = ( struct _SYSTEM_PROCESSES * )SystemInformation;
struct _SYSTEM_PROCESSES * prev = NULL;
// if(curr->NextEntryDelta)
// curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta);
while (curr)
{
KdPrint(( " ProcessName:%wZ NextEntryDelta:%d \n " , & curr -> ProcessName, curr -> NextEntryDelta));
if (curr -> NextEntryDelta)
curr = (_SYSTEM_PROCESSES * )((ULONG)curr + curr -> NextEntryDelta);
else
curr = NULL;
} // while(curr)
UnHook();
} // if(5 == SystemInformationClass)
} // if(NT_SUCCESS(rc))
// KdPrint(("HookZwQuerySystemInformation is Succeessfully. \n"));
return rc;
}
在 DebugView 中显示的内容如下:
Entry Hook Function
!
Entry Hook()
KeServiceDescriptorTable -> ServiceTableBase is : 0x804e2d20
OldZwQuerySystemInformation is : 0x8057cc27
MyZwQuerySystemInformation is : 0xf8f0c080
Leave DriverEntry !
ProcessName:( null ) NextEntryDelta: 248
ProcessName:System NextEntryDelta: 3528
ProcessName:smss.exe NextEntryDelta: 400
ProcessName:csrss.exe NextEntryDelta: 912
ProcessName:winlogon.exe NextEntryDelta: 1304
ProcessName:services.exe NextEntryDelta: 1176
ProcessName:lsass.exe NextEntryDelta: 1360
ProcessName:vmacthlp.exe NextEntryDelta: 280
ProcessName:svchost.exe NextEntryDelta: 1360
ProcessName:svchost.exe NextEntryDelta: 656
ProcessName:svchost.exe NextEntryDelta: 3664
ProcessName:svchost.exe NextEntryDelta: 464
ProcessName:svchost.exe NextEntryDelta: 1104
ProcessName:explorer.exe NextEntryDelta: 920
ProcessName:spoolsv.exe NextEntryDelta: 848
ProcessName:VMwareService.exe NextEntryDelta: 416
ProcessName:VMwareTray.exe NextEntryDelta: 280
ProcessName:VMwareUser.exe NextEntryDelta: 536
ProcessName:ctfmon.exe NextEntryDelta: 272
ProcessName:wscntfy.exe NextEntryDelta: 272
ProcessName:alg.exe NextEntryDelta: 584
ProcessName:cmd.exe NextEntryDelta: 264
ProcessName:conime.exe NextEntryDelta: 272
ProcessName:DriverMonitor.exe NextEntryDelta: 608
ProcessName:notepad.exe NextEntryDelta: 272
ProcessName:taskmgr.exe NextEntryDelta: 400
ProcessName:Dbgview.exe NextEntryDelta: 0
Unhook leave !
Entry Hook()
KeServiceDescriptorTable -> ServiceTableBase is : 0x804e2d20
OldZwQuerySystemInformation is : 0x8057cc27
MyZwQuerySystemInformation is : 0xf8f0c080
Leave DriverEntry !
ProcessName:( null ) NextEntryDelta: 248
ProcessName:System NextEntryDelta: 3528
ProcessName:smss.exe NextEntryDelta: 400
ProcessName:csrss.exe NextEntryDelta: 912
ProcessName:winlogon.exe NextEntryDelta: 1304
ProcessName:services.exe NextEntryDelta: 1176
ProcessName:lsass.exe NextEntryDelta: 1360
ProcessName:vmacthlp.exe NextEntryDelta: 280
ProcessName:svchost.exe NextEntryDelta: 1360
ProcessName:svchost.exe NextEntryDelta: 656
ProcessName:svchost.exe NextEntryDelta: 3664
ProcessName:svchost.exe NextEntryDelta: 464
ProcessName:svchost.exe NextEntryDelta: 1104
ProcessName:explorer.exe NextEntryDelta: 920
ProcessName:spoolsv.exe NextEntryDelta: 848
ProcessName:VMwareService.exe NextEntryDelta: 416
ProcessName:VMwareTray.exe NextEntryDelta: 280
ProcessName:VMwareUser.exe NextEntryDelta: 536
ProcessName:ctfmon.exe NextEntryDelta: 272
ProcessName:wscntfy.exe NextEntryDelta: 272
ProcessName:alg.exe NextEntryDelta: 584
ProcessName:cmd.exe NextEntryDelta: 264
ProcessName:conime.exe NextEntryDelta: 272
ProcessName:DriverMonitor.exe NextEntryDelta: 608
ProcessName:notepad.exe NextEntryDelta: 272
ProcessName:taskmgr.exe NextEntryDelta: 400
ProcessName:Dbgview.exe NextEntryDelta: 0
Unhook leave !
接着再做一个尝试,如果直接把第二个线程的信息的 NextEntryDelta 改为0 , 是不是 taskmgr.exe 就会只显示一条线程?
NTSTATUS MyZwQuerySystemInformation(IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength) // 定义自己的Hook函数
{
NTSTATUS rc;
UNICODE_STRING process_name;
RtlInitUnicodeString( & process_name, L " taskmgr.exe " );
rc = (OldZwQuerySystemInformation) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (NT_SUCCESS(rc))
{
if ( 5 == SystemInformationClass)
{
struct _SYSTEM_PROCESSES * curr = ( struct _SYSTEM_PROCESSES * )SystemInformation;
struct _SYSTEM_PROCESSES * prev = NULL;
if (curr -> NextEntryDelta)
{
curr -> NextEntryDelta = 0 ;
}
// curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta);
/*
while(curr)
{
KdPrint(("ProcessName:%wZ NextEntryDelta:%d \n", &curr->ProcessName, curr->NextEntryDelta));
if(curr->NextEntryDelta)
curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta);
else
curr = NULL;
}// while(curr)
*/
// UnHook();
} // if(5 == SystemInformationClass)
} // if(NT_SUCCESS(rc))
// KdPrint(("HookZwQuerySystemInformation is Succeessfully. \n"));
return rc;
}
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength) // 定义自己的Hook函数
{
NTSTATUS rc;
UNICODE_STRING process_name;
RtlInitUnicodeString( & process_name, L " taskmgr.exe " );
rc = (OldZwQuerySystemInformation) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (NT_SUCCESS(rc))
{
if ( 5 == SystemInformationClass)
{
struct _SYSTEM_PROCESSES * curr = ( struct _SYSTEM_PROCESSES * )SystemInformation;
struct _SYSTEM_PROCESSES * prev = NULL;
if (curr -> NextEntryDelta)
{
curr -> NextEntryDelta = 0 ;
}
// curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta);
/*
while(curr)
{
KdPrint(("ProcessName:%wZ NextEntryDelta:%d \n", &curr->ProcessName, curr->NextEntryDelta));
if(curr->NextEntryDelta)
curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta);
else
curr = NULL;
}// while(curr)
*/
// UnHook();
} // if(5 == SystemInformationClass)
} // if(NT_SUCCESS(rc))
// KdPrint(("HookZwQuerySystemInformation is Succeessfully. \n"));
return rc;
}
情况还是 taskmgr.exe 中选中了 'Show processes from all users' 选项,就会显示一条 System Idle Process 线程,如果不选中
'Show processes from all users' 这个选项,那么 Taskmgr.exe 的列表就会显示为空
于是,加多几句代码
if
(curr
->
NextEntryDelta)
{
KdPrint(( " SystemInformationLength:%d \n " , SystemInformationLength));
curr -> NextEntryDelta = 0 ;
memset(( void * )((ULONG)curr + curr -> NextEntryDelta), 0x00 , SystemInformationLength - curr -> NextEntryDelta);
}
{
KdPrint(( " SystemInformationLength:%d \n " , SystemInformationLength));
curr -> NextEntryDelta = 0 ;
memset(( void * )((ULONG)curr + curr -> NextEntryDelta), 0x00 , SystemInformationLength - curr -> NextEntryDelta);
}
此时,无论有无选中 'Show Process From all users'选项,所有进程都不显示在 taskmgr.exe 了
另外还发现两个现象
Q1. taskmgr.exe 调用 ZwQuerySystemInformation 时,ReturnLength 指针总是传 NULL
Q2. taskmgr.exe 调用 ZwQuerySystemInformation 时,SystemInformationLength 总是传 0x6000
难道 taskmgr.exe 并不是通过 NextEntryData 这个值来定位到下个进程的信息的?