Posted on 2009-10-28 14:38
S.l.e!ep.¢% 阅读(326)
评论(0) 编辑 收藏 引用 所属分类:
RootKit
继
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 修改成如下的代码
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;
}
在 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!
接着再做一个尝试,如果直接把第二个线程的信息的 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;
}
情况还是 taskmgr.exe 中选中了 'Show processes from all users' 选项,就会显示一条 System Idle Process 线程,如果不选中
'Show processes from all users' 这个选项,那么 Taskmgr.exe 的列表就会显示为空
curr
->NextEntryDelta = 0; 那为何不把 curr 之后的数全部置为 0x00 ?
于是,加多几句代码
if(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 这个值来定位到下个进程的信息的?