以前看某些文章的时候,知道可以利用“活动进程链”隐藏或者检测进程。对于如何定位活动进程链一直没搞清楚,在看Rootkit那本书上说,通过PsGetCurrentProcess函数可以获得EPROCESS,但是书中解释的很模糊,一直没看明白。
今天利用WinDbg查看了各个结构,终于把疑问搞清楚了。
PsGetCurrentProcessº¯Êý·´»ã±àºóÊÇÕâÑù£º
lkd> u nt!PsGetCurrentProcess
nt!PsGetCurrentProcess:
8052b52c 64a124010000 mov eax,dword ptr fs:[00000124h]
8052b532 8b4044 mov eax,dword ptr [eax+44h]
8052b535 c3 ret
ÔÚÓû§Ä£Ê½Ï£¬FSÖ¸ÏòTEB½á¹¹£¬¶øÔÚÄÚºËģʽÏÂFSÈ´Ö¸ÏòKPCR£¨Kernel's Processor Control Region£©½á¹¹¡£ÄÇô¿ÉÒÔ¿´µ½FS:[0x120]´¦¾ÍÊÇKPRCB£¨Kernel's Processor Cotrol Block£©½á¹¹£¨¿´ÏÂͼºìÉ«¸ßÁÁ´¦£©
lkd> dt nt!_kpcr
nt!_KPCR
+0x000 NtTib : _NT_TIB
+0x01c SelfPcr : Ptr32 _KPCR
+0x020 Prcb : Ptr32 _KPRCB
+0x024 Irql : UChar
+0x028 IRR : Uint4B
+0x02c IrrActive : Uint4B
+0x030 IDR : Uint4B
+0x034 KdVersionBlock : Ptr32 Void
+0x038 IDT : Ptr32 _KIDTENTRY
+0x03c GDT : Ptr32 _KGDTENTRY
+0x040 TSS : Ptr32 _KTSS
+0x044 MajorVersion : Uint2B
+0x046 MinorVersion : Uint2B
+0x048 SetMember : Uint4B
+0x04c StallScaleFactor : Uint4B
+0x050 DebugActive : UChar
+0x051 Number : UChar
+0x052 Spare0 : UChar
+0x053 SecondLevelCacheAssociativity : UChar
+0x054 VdmAlert : Uint4B
+0x058 KernelReserved : [14] Uint4B
+0x090 SecondLevelCacheSize : Uint4B
+0x094 HalReserved : [16] Uint4B
+0x0d4 InterruptMode : Uint4B
+0x0d8 Spare1 : UChar
+0x0dc KernelReserved2 : [17] Uint4B
+0x120 PrcbData : _KPRCB
Õ¹¿ªKPRCB½á¹¹¼ÌÐø¹Û²ì¿ÉÒÔ¿´µ½FS:[0x124]Ö¸ÏòÁËKTHREAD½á¹¹
lkd> dt nt!_kprcb
nt!_KPRCB
+0x000 MinorVersion : Uint2B
+0x002 MajorVersion : Uint2B
+0x004 CurrentThread : Ptr32 _KTHREAD
+0x008 NextThread : Ptr32 _KTHREAD
+0x00c IdleThread : Ptr32 _KTHREAD
......本结构更多成员省略
继续查看KTHREAD结构可以看到KTHREAD+0x44处成员就是KPROCESS指针
lkd> dt nt!_kthread -v -r
Matched nt!_KTHREAD
nt!_KTHREAD
struct _KTHREAD, 73 elements, 0x1c0 bytes
+0x000 Header : struct _DISPATCHER_HEADER, 6 elements, 0x10 bytes
+0x000 Type : UChar
+0x001 Absolute : UChar
+0x002 Size : UChar
+0x003 Inserted : UChar
+0x004 SignalState : Int4B
+0x008 WaitListHead : struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x000 Flink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x004 Blink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x010 MutantListHead : struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x000 Flink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x000 Flink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x004 Blink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x004 Blink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x000 Flink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x004 Blink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x018 InitialStack : Ptr32 to Void
+0x01c StackLimit : Ptr32 to Void
+0x020 Teb : Ptr32 to Void
+0x024 TlsArray : Ptr32 to Void
+0x028 KernelStack : Ptr32 to Void
+0x02c DebugActive : UChar
+0x02d State : UChar
+0x02e Alerted : [2] UChar
+0x030 Iopl : UChar
+0x031 NpxState : UChar
+0x032 Saturation : Char
+0x033 Priority : Char
+0x034 ApcState : struct _KAPC_STATE, 5 elements, 0x18 bytes
+0x000 ApcListHead : [2] struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x000 Flink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x004 Blink : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
+0x010 Process : Ptr32 to struct _KPROCESS, 29 elements, 0x6c bytes
至此,我们已经搞清了PsGetCurrentProcess的流程
通过查DDK DOC发现MS对PsGetCurrentProcess函数是这样描述的:
PsGetCurrentProcess returns a pointer to the process of the current thread.
PEPROCESS
PsGetCurrentProcess(
);
该函数的返回值是EPROCESS指针。但是我们分析的结果是函数的返回值是KPROCESS的指针。
这样的话难道PsGetCurrentProcess 函数返回值既是EPROCESS的指针又是KPROCESS的指针?
带着疑问我们继续往下看:
lkd> dt nt!_eprocess
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER
+0x078 ExitTime : _LARGE_INTEGER
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId : Ptr32 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY
可以看到EPROCESS的第一个成员就是KPROCESS,这样我们就明白了为什么PsGetCurrentProcess 函数返回值既是EPROCESS的地址又是KPROCESS的地址了。在EPROCESS偏移0x84是进程的PID,偏移0x88(我的系统是XP SP2)就是我们要找的活动进程链了。
以上是我今天学习的一些收获,如果大家认为有哪些不对的地方,请指正。
posted on 2007-08-24 09:25
margin 阅读(1276)
评论(0) 编辑 收藏 引用