• 内核下枚举进程(一)进程活动链


    今天学会了一种在内核下枚举进程的方法,写下来与大家共享。用到了的是EPROCESS 结构,EPROCESS 是一个关于进程的结构,此结构很庞大,包括的内容非常丰富.由于此结构未文档化所以用windbg来查看
    输入dt _eprocess命令查看该结构如下:

    ntdll!_EPROCESS
       +0x000 Pcb              : _KPROCESS   //进程控制块儿
       +0x098 ProcessLock      : _EX_PUSH_LOCK
       +0x0a0 CreateTime       : _LARGE_INTEGER
       +0x0a8 ExitTime         : _LARGE_INTEGER
       +0x0b0 RundownProtect   : _EX_RUNDOWN_REF
       +0x0b4 UniqueProcessId  : Ptr32 Void    //进程ID
       +0x0b8 ActiveProcessLinks : _LIST_ENTRY //活动进程链,就是靠此结构才把所有的进程链接在一起的
       +0x0c0 ProcessQuotaUsage : [2] Uint4B
       +0x0c8 ProcessQuotaPeak : [2] Uint4B
       +0x0d0 CommitCharge     : Uint4B
       +0x0d4 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
       +0x0d8 CpuQuotaBlock    : Ptr32 _PS_CPU_QUOTA_BLOCK
       +0x0dc PeakVirtualSize  : Uint4B
       +0x0e0 VirtualSize      : Uint4B
       +0x0e4 SessionProcessLinks : _LIST_ENTRY
       +0x0ec DebugPort        : Ptr32 Void
       +0x0f0 ExceptionPortData : Ptr32 Void
       +0x0f0 ExceptionPortValue : Uint4B
       +0x0f0 ExceptionPortState : Pos 0, 3 Bits
       +0x0f4 ObjectTable      : Ptr32 _HANDLE_TABLE
       +0x0f8 Token            : _EX_FAST_REF
       +0x0fc WorkingSetPage   : Uint4B
       +0x100 AddressCreationLock : _EX_PUSH_LOCK
       +0x104 RotateInProgress : Ptr32 _ETHREAD
       +0x108 ForkInProgress   : Ptr32 _ETHREAD
       +0x10c HardwareTrigger  : Uint4B
       +0x110 PhysicalVadRoot  : Ptr32 _MM_AVL_TABLE
       +0x114 CloneRoot        : Ptr32 Void
       +0x118 NumberOfPrivatePages : Uint4B
       +0x11c NumberOfLockedPages : Uint4B
       +0x120 Win32Process     : Ptr32 Void
       +0x124 Job              : Ptr32 _EJOB
       +0x128 SectionObject    : Ptr32 Void
       +0x12c SectionBaseAddress : Ptr32 Void
       +0x130 Cookie           : Uint4B
       +0x134 Spare8           : Uint4B
       +0x138 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
       +0x13c Win32WindowStation : Ptr32 Void
       +0x140 InheritedFromUniqueProcessId : Ptr32 Void
       +0x144 LdtInformation   : Ptr32 Void
       +0x148 VdmObjects       : Ptr32 Void
       +0x14c ConsoleHostProcess : Uint4B
       +0x150 DeviceMap        : Ptr32 Void
       +0x154 EtwDataSource    : Ptr32 Void
       +0x158 FreeTebHint      : Ptr32 Void
       +0x160 PageDirectoryPte : _HARDWARE_PTE_X86
       +0x160 Filler           : Uint8B
       +0x168 Session          : Ptr32 Void
       +0x16c ImageFileName    : [15] UChar //进程名
       +0x17b PriorityClass    : UChar
       +0x17c JobLinks         : _LIST_ENTRY
       +0x184 LockedPagesList  : Ptr32 Void
       +0x188 ThreadListHead   : _LIST_ENTRY
       +0x190 SecurityPort     : Ptr32 Void
       +0x194 PaeTop           : Ptr32 Void
       +0x198 ActiveThreads    : Uint4B
       +0x19c ImagePathHash    : Uint4B
       +0x1a0 DefaultHardErrorProcessing : Uint4B
       +0x1a4 LastThreadExitStatus : Int4B
       +0x1a8 Peb              : Ptr32 _PEB //进程环境块
       +0x1ac PrefetchTrace    : _EX_FAST_REF
       +0x1b0 ReadOperationCount : _LARGE_INTEGER
       +0x1b8 WriteOperationCount : _LARGE_INTEGER
       +0x1c0 OtherOperationCount : _LARGE_INTEGER
       +0x1c8 ReadTransferCount : _LARGE_INTEGER
       +0x1d0 WriteTransferCount : _LARGE_INTEGER
       +0x1d8 OtherTransferCount : _LARGE_INTEGER
       +0x1e0 CommitChargeLimit : Uint4B
       +0x1e4 CommitChargePeak : Uint4B
       +0x1e8 AweInfo          : Ptr32 Void
       +0x1ec SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
       +0x1f0 Vm               : _MMSUPPORT
       +0x25c MmProcessLinks   : _LIST_ENTRY
       +0x264 HighestUserAddress : Ptr32 Void
       +0x268 ModifiedPageCount : Uint4B
       +0x26c Flags2           : Uint4B
       +0x26c JobNotReallyActive : Pos 0, 1 Bit
       +0x26c AccountingFolded : Pos 1, 1 Bit
       +0x26c NewProcessReported : Pos 2, 1 Bit
       +0x26c ExitProcessReported : Pos 3, 1 Bit
       +0x26c ReportCommitChanges : Pos 4, 1 Bit
       +0x26c LastReportMemory : Pos 5, 1 Bit
       +0x26c ReportPhysicalPageChanges : Pos 6, 1 Bit
       +0x26c HandleTableRundown : Pos 7, 1 Bit
       +0x26c NeedsHandleRundown : Pos 8, 1 Bit
       +0x26c RefTraceEnabled  : Pos 9, 1 Bit
       +0x26c NumaAware        : Pos 10, 1 Bit
       +0x26c ProtectedProcess : Pos 11, 1 Bit
       +0x26c DefaultPagePriority : Pos 12, 3 Bits
       +0x26c PrimaryTokenFrozen : Pos 15, 1 Bit
       +0x26c ProcessVerifierTarget : Pos 16, 1 Bit
       +0x26c StackRandomizationDisabled : Pos 17, 1 Bit
       +0x26c AffinityPermanent : Pos 18, 1 Bit
       +0x26c AffinityUpdateEnable : Pos 19, 1 Bit
       +0x26c PropagateNode    : Pos 20, 1 Bit
       +0x26c ExplicitAffinity : Pos 21, 1 Bit
       +0x270 Flags            : Uint4B
       +0x270 CreateReported   : Pos 0, 1 Bit
       +0x270 NoDebugInherit   : Pos 1, 1 Bit
       +0x270 ProcessExiting   : Pos 2, 1 Bit
       +0x270 ProcessDelete    : Pos 3, 1 Bit
       +0x270 Wow64SplitPages  : Pos 4, 1 Bit
       +0x270 VmDeleted        : Pos 5, 1 Bit
       +0x270 OutswapEnabled   : Pos 6, 1 Bit
       +0x270 Outswapped       : Pos 7, 1 Bit
       +0x270 ForkFailed       : Pos 8, 1 Bit
       +0x270 Wow64VaSpace4Gb  : Pos 9, 1 Bit
       +0x270 AddressSpaceInitialized : Pos 10, 2 Bits
       +0x270 SetTimerResolution : Pos 12, 1 Bit
       +0x270 BreakOnTermination : Pos 13, 1 Bit
       +0x270 DeprioritizeViews : Pos 14, 1 Bit
       +0x270 WriteWatch       : Pos 15, 1 Bit
       +0x270 ProcessInSession : Pos 16, 1 Bit
       +0x270 OverrideAddressSpace : Pos 17, 1 Bit
       +0x270 HasAddressSpace  : Pos 18, 1 Bit
       +0x270 LaunchPrefetched : Pos 19, 1 Bit
       +0x270 InjectInpageErrors : Pos 20, 1 Bit
       +0x270 VmTopDown        : Pos 21, 1 Bit
       +0x270 ImageNotifyDone  : Pos 22, 1 Bit
       +0x270 PdeUpdateNeeded  : Pos 23, 1 Bit
       +0x270 VdmAllowed       : Pos 24, 1 Bit
       +0x270 CrossSessionCreate : Pos 25, 1 Bit
       +0x270 ProcessInserted  : Pos 26, 1 Bit
       +0x270 DefaultIoPriority : Pos 27, 3 Bits
       +0x270 ProcessSelfDelete : Pos 30, 1 Bit
       +0x270 SetTimerResolutionLink : Pos 31, 1 Bit
       +0x274 ExitStatus       : Int4B
       +0x278 VadRoot          : _MM_AVL_TABLE
       +0x298 AlpcContext      : _ALPC_PROCESS_CONTEXT
       +0x2a8 TimerResolutionLink : _LIST_ENTRY
       +0x2b0 RequestedTimerResolution : Uint4B
       +0x2b4 ActiveThreadsHighWatermark : Uint4B
       +0x2b8 SmallestTimerResolution : Uint4B
       +0x2bc TimerResolutionStackRecord : Ptr32 _PO_DIAG_STACK_RECORD
    

     从上述结构中可以看出ActiveProcessLinks的偏移为0xb8,进程ID的偏移为0xb4,ImageFileName的偏移为0x16c
    接下来我们检查一下这些字段。
    输入命令 !process 0 0,得到结果如下:

    我们看到列出了所有进程的简略信息,包括进程名和进程ID。注意,进程后面的地址为此进程的EPROCESS结构的起始地址. 接下来拿services.exe来测试,
    输入 dt _eprocess 877efbe0 命令查看services.exed的EPROCESS结构,得到结果如下

    kd> dt _eprocess 877efbe0
    ntdll!_EPROCESS
       +0x000 Pcb              : _KPROCESS
       +0x098 ProcessLock      : _EX_PUSH_LOCK
       +0x0a0 CreateTime       : _LARGE_INTEGER 0x1d13e56`a5bfd1d5
       +0x0a8 ExitTime         : _LARGE_INTEGER 0x0
       +0x0b0 RundownProtect   : _EX_RUNDOWN_REF
       +0x0b4 UniqueProcessId  : 0x00000218 Void
       +0x0b8 ActiveProcessLinks : _LIST_ENTRY [ 0x87c162c8 - 0x871381f0 ]
       +0x0c0 ProcessQuotaUsage : [2] 0x1c24
       +0x0c8 ProcessQuotaPeak : [2] 0x39bc
       +0x0d0 CommitCharge     : 0x434
       ......
       +0x160 Filler           : 0
       +0x168 Session          : 0x8b8d9000 Void
       +0x16c ImageFileName    : [15]  "services.exe"
       +0x17b PriorityClass    : 0x2 ''
       +0x17c JobLinks         : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x184 LockedPagesList  : (null) 
       ......
    

     输入 dd 877efbe0 + b8命令查看 ActivePRocessLinks地址,得到结果如下:

    kd> dd 877efbe0+b8
    877efc98  87c162c8 871381f0 00001c24 0000c04c
    877efca8  000039bc 0000fab4 00000434 83f51c40
    877efcb8  00000000 02985000 0223a000 87c162f4
    877efcc8  87148614 00000000 8713f570 8e456de0
    877efcd8  890cd50f 000190b1 00000000 00000000
    877efce8  00000000 00000000 00000000 00000000
    877efcf8  0000033d 00000002 ffb07d50 00000000
    877efd08  8b6b8258 00c70000 374541f3 00000000
    

     可知下一个进程的ActiveProcessLinks指针存在于87c162c8处,我们要得到此进程EPROCESS结构,还得向前移动0xb8.让我们检查一下看对不对。
    输入命令 dt _eprocess 87c162c8-b8,结果如下:

    kd> dt _eprocess 87c162c8-b8
    ntdll!_EPROCESS
       +0x000 Pcb              : _KPROCESS
       +0x098 ProcessLock      : _EX_PUSH_LOCK
       +0x0a0 CreateTime       : _LARGE_INTEGER 0x1d13e56`a5e38679
       +0x0a8 ExitTime         : _LARGE_INTEGER 0x0
       +0x0b0 RundownProtect   : _EX_RUNDOWN_REF
       +0x0b4 UniqueProcessId  : 0x00000220 Void
       +0x0b8 ActiveProcessLinks : _LIST_ENTRY [ 0x87c11278 - 0x877efc98 ]
       +0x0c0 ProcessQuotaUsage : [2] 0x26cc
       +0x0c8 ProcessQuotaPeak : [2] 0x29f0
       .......
       +0x0f0 ExceptionPortState : 0y000
       +0x0f4 ObjectTable      : 0x89878490 _HANDLE_TABLE
       +0x0f8 Token            : _EX_FAST_REF
      
       +0x160 Filler           : 0
       +0x168 Session          : 0x8b8d9000 Void
       +0x16c ImageFileName    : [15]  "lsass.exe"
       ......
    

     可见符合先前的进程链顺序。接下来就用代码实现。

    环境为VS2013,建立WDM空项目,添加一个.c文件

    #include <ntddk.h>
    
    VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
    {
    	//UNREFERENCED_PARAMETER(pDriverObject);
    	KdPrint(("DrvierUnload Routine! 
    "));
    }
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvierObject, PUNICODE_STRING pRegistryPath)
    {
    	pDrvierObject->DriverUnload = DriverUnload;
    	
    	ULONG ulProcessName;
    	ULONG ulProcessID;
    
    	ANSI_STRING processName = { 0 };
    	char szName[0x100] = { 0 };
    	RtlInitEmptyAnsiString(&processName, szName, sizeof(szName));
    	
    	PEPROCESS pFirstEProcess = NULL;
    	PEPROCESS pEProcess = PsGetCurrentProcess(); 
    	pFirstEProcess = pEProcess;
    
    	while (1)
    	{
    		ulProcessID = *(ULONG *)((ULONG)pEProcess + 0xb4);
    		processName.Buffer = (PCHAR)((ULONG)pEProcess + 0x16c);
    		KdPrint(("ID:%d   ImageFileName:%s
    ", ulProcessID, processName.Buffer));
    
    		pEProcess = (PEPROCESS)(*(ULONG*)((ULONG)(pEProcess)+0xb8) - 0Xb8);
    
    		if (pEProcess == pFirstEProcess || *(LONG *)((LONG)pEProcess + 0xb4) < 0)
    			break;
    	}
    	
    	KdPrint(("enum process end
    "));
    
    	return STATUS_SUCCESS;
    }	
    

     编译选项为 win7 debug
    加载驱动后在DbgView中可以看到如下信息:
    内核下枚举进程 - Prairie - work labor and play

    至此,枚举已经成功 ,上述代码还可以所扩展,比如我们可以让特定的进程隐藏掉,方法就是让在进程在进程链表中”脱节“,有兴趣的读者可以自行研究。

  • 相关阅读:
    作业二 Git的安装与使用
    第一次作业
    字符串、文件操作,英文词频统计预处理
    了解大数据的特点、来源与数据呈现方式以及用Python写Mad Libs游戏
    第五次作业:结对项目-四则运算 “软件”之升级版
    第四次作业:个人项目-小学四则运算 “软件”之初版
    第3次作业:阅读《构建之法》1-5章
    分布式版本控制系统Git的安装与使用
    第一次作业-准备
    字符串操作,英文词频统计预处理
  • 原文地址:https://www.cnblogs.com/priarieNew/p/9756234.html
Copyright © 2020-2023  润新知