SnowGuard 之 检测隐藏进程篇

SnowGuard目的是能够代替PatchGuard工作,没有加密没有算法,基于原理基本上详见PatchGuard源码。

Baklib
狐白 最后一次编辑 接近 3 年前
333
  1. 0x4 类型 1 进程列表损坏
  2. 0x5 类型 2 进程列表损坏
  3. 0x1A 类型 3 进程列表损坏
  4. 0x1B 类型 4 进程列表损坏
通过蓝屏代码我们可以得知 PatchGuard至少使用了4种方法检测隐藏进程
那么在内核中枚举进程的方法也寥寥无几
第一种是遍历双向链表,这个没什么好说的 [KiProcessListHead,PsActiveProcessHead]
kd> dt _eprocess ActiveProcessLinks nt!_EPROCESS +0x188 ActiveProcessLinks : _LIST_ENTRY kd> dt _KPROCESS ProcessListEntry nt!_KPROCESS +0x0e0 ProcessListEntry : _LIST_ENTRY
kd> dt _eprocess 0xFFFFFA8018DC7040 nt!_EPROCESS +0x000 Pcb : _KPROCESS +0x160 ProcessLock : _EX_PUSH_LOCK +0x168 CreateTime : _LARGE_INTEGER 0x01d7fbe0`57b15375 +0x170 ExitTime : _LARGE_INTEGER 0x0 +0x178 RundownProtect : _EX_RUNDOWN_REF +0x180 UniqueProcessId : 0x00000000`00000004 Void +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`1938fc88 - 0xfffff800`02c1e940 ] +0x198 ProcessQuotaUsage : [2] 0 +0x1a8 ProcessQuotaPeak : [2] 0 +0x1b8 CommitCharge : 0x26 +0x1c0 QuotaBlock : 0xfffff800`02bfbe40 _EPROCESS_QUOTA_BLOCK +0x1c8 CpuQuotaBlock : (null) +0x1d0 PeakVirtualSize : 0xb01000 +0x1d8 VirtualSize : 0x443000 +0x1e0 SessionProcessLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ] +0x1f0 DebugPort : (null) +0x1f8 ExceptionPortData : (null) +0x1f8 ExceptionPortValue : 0 +0x1f8 ExceptionPortState : 0y000 +0x200 ObjectTable : 0xfffff8a0`000017f0 _HANDLE_TABLE +0x208 Token : _EX_FAST_REF +0x210 WorkingSetPage : 0 +0x218 AddressCreationLock : _EX_PUSH_LOCK +0x220 RotateInProgress : (null) +0x228 ForkInProgress : (null) +0x230 HardwareTrigger : 0 +0x238 PhysicalVadRoot : 0xfffffa80`18e7b7f0 _MM_AVL_TABLE +0x240 CloneRoot : (null) +0x248 NumberOfPrivatePages : 0xc +0x250 NumberOfLockedPages : 0x40 +0x258 Win32Process : (null) +0x260 Job : (null) +0x268 SectionObject : (null) +0x270 SectionBaseAddress : (null) +0x278 Cookie : 0 +0x27c UmsScheduledThreads : 0 +0x280 WorkingSetWatch : (null) +0x288 Win32WindowStation : (null) +0x290 InheritedFromUniqueProcessId : (null) +0x298 LdtInformation : (null) +0x2a0 Spare : (null) +0x2a8 ConsoleHostProcess : 0 +0x2b0 DeviceMap : 0xfffff8a0`00008bc0 Void +0x2b8 EtwDataSource : (null) +0x2c0 FreeTebHint : 0x000007ff`fffe0000 Void +0x2c8 FreeUmsTebHint : 0x00000000`7710f000 Void +0x2d0 PageDirectoryPte : 0 +0x2d8 Session : (null) +0x2e0 ImageFileName : [15] "System" +0x2ef PriorityClass : 0x2 '' +0x2f0 JobLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ] +0x300 LockedPagesList : (null) +0x308 ThreadListHead : _LIST_ENTRY [ 0xfffffa80`18dc7f78 - 0xfffffa80`19e99488 ] +0x318 SecurityPort : (null) +0x320 Wow64Process : (null) +0x328 ActiveThreads : 0x5c +0x32c ImagePathHash : 0 +0x330 DefaultHardErrorProcessing : 5 +0x334 LastThreadExitStatus : 0n0 +0x338 Peb : (null) +0x340 PrefetchTrace : _EX_FAST_REF +0x348 ReadOperationCount : _LARGE_INTEGER 0x10 +0x350 WriteOperationCount : _LARGE_INTEGER 0x2 +0x358 OtherOperationCount : _LARGE_INTEGER 0x1d1 +0x360 ReadTransferCount : _LARGE_INTEGER 0x37e0038 +0x368 WriteTransferCount : _LARGE_INTEGER 0x10200 +0x370 OtherTransferCount : _LARGE_INTEGER 0x11ff +0x378 CommitChargeLimit : 0 +0x380 CommitChargePeak : 0x59 +0x388 AweInfo : (null) +0x390 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO +0x398 Vm : _MMSUPPORT +0x428 MmProcessLinks : _LIST_ENTRY [ 0xfffffa80`1938ff28 - 0xfffff800`02bf7aa8 ] +0x438 ModifiedPageCount : 0x226e +0x43c Flags2 : 0x1c02d800 +0x43c JobNotReallyActive : 0y0 +0x43c AccountingFolded : 0y0 +0x43c NewProcessReported : 0y0 +0x43c ExitProcessReported : 0y0 +0x43c ReportCommitChanges : 0y0 +0x43c LastReportMemory : 0y0 +0x43c ReportPhysicalPageChanges : 0y0 +0x43c HandleTableRundown : 0y0 +0x43c NeedsHandleRundown : 0y0 +0x43c RefTraceEnabled : 0y0 +0x43c NumaAware : 0y0 +0x43c ProtectedProcess : 0y1 +0x43c DefaultPagePriority : 0y101 +0x43c PrimaryTokenFrozen : 0y1 +0x43c ProcessVerifierTarget : 0y0 +0x43c StackRandomizationDisabled : 0y1 +0x43c AffinityPermanent : 0y0 +0x43c AffinityUpdateEnable : 0y0 +0x43c PropagateNode : 0y0 +0x43c ExplicitAffinity : 0y0 +0x43c Spare1 : 0y0 +0x43c ForceRelocateImages : 0y0 +0x43c DisallowStrippedImages : 0y0 +0x43c LowVaAccessible : 0y0 +0x43c RestrictIndirectBranchPrediction : 0y1 +0x43c AddressPolicyFrozen : 0y1 +0x43c MemoryDisambiguationDisable : 0y1 +0x440 Flags : 0x14040800 +0x440 CreateReported : 0y0 +0x440 NoDebugInherit : 0y0 +0x440 ProcessExiting : 0y0 +0x440 ProcessDelete : 0y0 +0x440 Wow64SplitPages : 0y0 +0x440 VmDeleted : 0y0 +0x440 OutswapEnabled : 0y0 +0x440 Outswapped : 0y0 +0x440 ForkFailed : 0y0 +0x440 Wow64VaSpace4Gb : 0y0 +0x440 AddressSpaceInitialized : 0y10 +0x440 SetTimerResolution : 0y0 +0x440 BreakOnTermination : 0y0 +0x440 DeprioritizeViews : 0y0 +0x440 WriteWatch : 0y0 +0x440 ProcessInSession : 0y0 +0x440 OverrideAddressSpace : 0y0 +0x440 HasAddressSpace : 0y1 +0x440 LaunchPrefetched : 0y0 +0x440 InjectInpageErrors : 0y0 +0x440 VmTopDown : 0y0 +0x440 ImageNotifyDone : 0y0 +0x440 PdeUpdateNeeded : 0y0 +0x440 VdmAllowed : 0y0 +0x440 CrossSessionCreate : 0y0 +0x440 ProcessInserted : 0y1 +0x440 DefaultIoPriority : 0y010 +0x440 ProcessSelfDelete : 0y0 +0x440 SetTimerResolutionLink : 0y0 +0x444 ExitStatus : 0n259 +0x448 VadRoot : _MM_AVL_TABLE +0x488 AlpcContext : _ALPC_PROCESS_CONTEXT +0x4a8 TimerResolutionLink : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ] +0x4b8 RequestedTimerResolution : 0 +0x4bc ActiveThreadsHighWatermark : 0x5d +0x4c0 SmallestTimerResolution : 0 +0x4c8 TimerResolutionStackRecord : (null) +0x4d0 SequenceNumber : 1 +0x4d8 CreateInterruptTime : 0x521f797 +0x4e0 CreateUnbiasedInterruptTime : 0x521f797 +0x4e8 SecurityDomain : 0 +0x4f0 HighestUserAddress : (null) kd> dx -id 0,0,fffffa8018dc7040 -r1 (*((ntkrnlmp!_LIST_ENTRY *)0xfffffa8018dc71c8)) (*((ntkrnlmp!_LIST_ENTRY *)0xfffffa8018dc71c8)) [Type: _LIST_ENTRY] [+0x000] Flink : 0xfffffa801938fc88 [Type: _LIST_ENTRY *] [+0x008] Blink : 0xfffff80002c1e940 [Type: _LIST_ENTRY *] kd> !object 0xfffffa801938fc88-0x188 Object: fffffa801938fb00 Type: (fffffa8018d4aa20) Process ObjectHeader: fffffa801938fad0 (new version) HandleCount: 1 PointerCount: 22 kd> dt _eprocess fffffa801938fb00 nt!_EPROCESS +0x000 Pcb : _KPROCESS +0x160 ProcessLock : _EX_PUSH_LOCK +0x168 CreateTime : _LARGE_INTEGER 0x01d7fbe0`57b3b4d5 +0x170 ExitTime : _LARGE_INTEGER 0x0 +0x178 RundownProtect : _EX_RUNDOWN_REF +0x180 UniqueProcessId : 0x00000000`000000fc Void +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`199e2708 - 0xfffffa80`18dc71c8 ] +0x198 ProcessQuotaUsage : [2] 0x5e0 +0x1a8 ProcessQuotaPeak : [2] 0x1870 +0x1b8 CommitCharge : 0x5e +0x1c0 QuotaBlock : 0xfffff800`02bfbe40 _EPROCESS_QUOTA_BLOCK +0x1c8 CpuQuotaBlock : (null) +0x1d0 PeakVirtualSize : 0x116f000 +0x1d8 VirtualSize : 0x3e4000 +0x1e0 SessionProcessLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ] +0x1f0 DebugPort : (null) +0x1f8 ExceptionPortData : (null) +0x1f8 ExceptionPortValue : 0 +0x1f8 ExceptionPortState : 0y000 +0x200 ObjectTable : 0xfffff8a0`007c0450 _HANDLE_TABLE +0x208 Token : _EX_FAST_REF +0x210 WorkingSetPage : 0x2a3ce +0x218 AddressCreationLock : _EX_PUSH_LOCK +0x220 RotateInProgress : (null) +0x228 ForkInProgress : (null) +0x230 HardwareTrigger : 0 +0x238 PhysicalVadRoot : (null) +0x240 CloneRoot : (null) +0x248 NumberOfPrivatePages : 0x49 +0x250 NumberOfLockedPages : 0 +0x258 Win32Process : (null) +0x260 Job : (null) +0x268 SectionObject : 0xfffff8a0`007c0680 Void +0x270 SectionBaseAddress : 0x00000000`47f30000 Void +0x278 Cookie : 0x7d38b7df +0x27c UmsScheduledThreads : 0 +0x280 WorkingSetWatch : (null) +0x288 Win32WindowStation : (null) +0x290 InheritedFromUniqueProcessId : 0x00000000`00000004 Void +0x298 LdtInformation : (null) +0x2a0 Spare : (null) +0x2a8 ConsoleHostProcess : 0 +0x2b0 DeviceMap : 0xfffff8a0`00008bc0 Void +0x2b8 EtwDataSource : (null) +0x2c0 FreeTebHint : 0x000007ff`fffde000 Void +0x2c8 FreeUmsTebHint : 0x00000001`00000000 Void +0x2d0 PageDirectoryPte : 0 +0x2d8 Session : (null) +0x2e0 ImageFileName : [15] "smss.exe" +0x2ef PriorityClass : 0x2 '' +0x2f0 JobLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ] +0x300 LockedPagesList : (null) +0x308 ThreadListHead : _LIST_ENTRY [ 0xfffffa80`1938f778 - 0xfffffa80`198dff78 ] +0x318 SecurityPort : (null) +0x320 Wow64Process : (null) +0x328 ActiveThreads : 2 +0x32c ImagePathHash : 0x1dcd0eb1 +0x330 DefaultHardErrorProcessing : 1 +0x334 LastThreadExitStatus : 0n0 +0x338 Peb : 0x000007ff`fffd3000 _PEB +0x340 PrefetchTrace : _EX_FAST_REF +0x348 ReadOperationCount : _LARGE_INTEGER 0x1 +0x350 WriteOperationCount : _LARGE_INTEGER 0x0 +0x358 OtherOperationCount : _LARGE_INTEGER 0x34 +0x360 ReadTransferCount : _LARGE_INTEGER 0x2000 +0x368 WriteTransferCount : _LARGE_INTEGER 0x0 +0x370 OtherTransferCount : _LARGE_INTEGER 0x4b0 +0x378 CommitChargeLimit : 0 +0x380 CommitChargePeak : 0x6e +0x388 AweInfo : (null) +0x390 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO +0x398 Vm : _MMSUPPORT +0x428 MmProcessLinks : _LIST_ENTRY [ 0xfffffa80`199e29a8 - 0xfffffa80`18dc7468 ] +0x438 ModifiedPageCount : 0x1d +0x43c Flags2 : 0x800d000 +0x43c JobNotReallyActive : 0y0 +0x43c AccountingFolded : 0y0 +0x43c NewProcessReported : 0y0 +0x43c ExitProcessReported : 0y0 +0x43c ReportCommitChanges : 0y0 +0x43c LastReportMemory : 0y0 +0x43c ReportPhysicalPageChanges : 0y0 +0x43c HandleTableRundown : 0y0 +0x43c NeedsHandleRundown : 0y0 +0x43c RefTraceEnabled : 0y0 +0x43c NumaAware : 0y0 +0x43c ProtectedProcess : 0y0 +0x43c DefaultPagePriority : 0y101 +0x43c PrimaryTokenFrozen : 0y1 +0x43c ProcessVerifierTarget : 0y0 +0x43c StackRandomizationDisabled : 0y0 +0x43c AffinityPermanent : 0y0 +0x43c AffinityUpdateEnable : 0y0 +0x43c PropagateNode : 0y0 +0x43c ExplicitAffinity : 0y0 +0x43c Spare1 : 0y0 +0x43c ForceRelocateImages : 0y0 +0x43c DisallowStrippedImages : 0y0 +0x43c LowVaAccessible : 0y0 +0x43c RestrictIndirectBranchPrediction : 0y0 +0x43c AddressPolicyFrozen : 0y1 +0x43c MemoryDisambiguationDisable : 0y0 +0x440 Flags : 0x144c2841 +0x440 CreateReported : 0y1 +0x440 NoDebugInherit : 0y0 +0x440 ProcessExiting : 0y0 +0x440 ProcessDelete : 0y0 +0x440 Wow64SplitPages : 0y0 +0x440 VmDeleted : 0y0 +0x440 OutswapEnabled : 0y1 +0x440 Outswapped : 0y0 +0x440 ForkFailed : 0y0 +0x440 Wow64VaSpace4Gb : 0y0 +0x440 AddressSpaceInitialized : 0y10 +0x440 SetTimerResolution : 0y0 +0x440 BreakOnTermination : 0y1 +0x440 DeprioritizeViews : 0y0 +0x440 WriteWatch : 0y0 +0x440 ProcessInSession : 0y0 +0x440 OverrideAddressSpace : 0y0 +0x440 HasAddressSpace : 0y1 +0x440 LaunchPrefetched : 0y1 +0x440 InjectInpageErrors : 0y0 +0x440 VmTopDown : 0y0 +0x440 ImageNotifyDone : 0y1 +0x440 PdeUpdateNeeded : 0y0 +0x440 VdmAllowed : 0y0 +0x440 CrossSessionCreate : 0y0 +0x440 ProcessInserted : 0y1 +0x440 DefaultIoPriority : 0y010 +0x440 ProcessSelfDelete : 0y0 +0x440 SetTimerResolutionLink : 0y0 +0x444 ExitStatus : 0n259 +0x448 VadRoot : _MM_AVL_TABLE +0x488 AlpcContext : _ALPC_PROCESS_CONTEXT +0x4a8 TimerResolutionLink : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ] +0x4b8 RequestedTimerResolution : 0 +0x4bc ActiveThreadsHighWatermark : 4 +0x4c0 SmallestTimerResolution : 0 +0x4c8 TimerResolutionStackRecord : (null) +0x4d0 SequenceNumber : 2 +0x4d8 CreateInterruptTime : 0x52458f7 +0x4e0 CreateUnbiasedInterruptTime : 0x52458f7 +0x4e8 SecurityDomain : 0 +0x4f0 HighestUserAddress : 0x000007ff`ffff0000 Void
第二种是PspCidTable,需要枚举三页表
kd> dq PspCidTable fffff800`02c1e988 fffff8a0`000048c0 00000000`00000000 fffff800`02c1e998 ffffffff`8000001c 00000000`00000101 fffff800`02c1e9a8 ffffffff`800002e0 ffffffff`80000024 fffff800`02c1e9b8 00000000`00000000 00000000`00000113 fffff800`02c1e9c8 00000000`00000000 00000000`00000000 fffff800`02c1e9d8 fffff800`02b85400 00000000`00000000 fffff800`02c1e9e8 00000000`00000000 00000000`00000000 fffff800`02c1e9f8 00000000`00000000 00000000`00000008
  第三种是HandleTableListHead,老样子遍历双向链表
kd> dt _eprocess ObjectTable nt!_EPROCESS +0x200 ObjectTable : Ptr64 _HANDLE_TABLE kd> dt _HANDLE_TABLE nt!_HANDLE_TABLE +0x000 TableCode : Uint8B +0x008 QuotaProcess : Ptr64 _EPROCESS +0x010 UniqueProcessId : Ptr64 Void +0x018 HandleLock : _EX_PUSH_LOCK +0x020 HandleTableList : _LIST_ENTRY +0x030 HandleContentionEvent : _EX_PUSH_LOCK +0x038 DebugInfo : Ptr64 _HANDLE_TRACE_DEBUG_INFO +0x040 ExtraInfoPages : Int4B +0x044 Flags : Uint4B +0x044 StrictFIFO : Pos 0, 1 Bit +0x048 FirstFreeHandle : Uint4B +0x050 LastFreeHandleEntry : Ptr64 _HANDLE_TABLE_ENTRY +0x058 HandleCount : Uint4B +0x05c NextHandleNeedingPool : Uint4B +0x060 HandleCountHighWatermark : Uint4B kd> dt _HANDLE_TABLE QuotaProcess nt!_HANDLE_TABLE +0x008 QuotaProcess : Ptr64 _EPROCESS kd> dt _HANDLE_TABLE HandleTableList nt!_HANDLE_TABLE +0x020 HandleTableList : _LIST_ENTRY
至此常用的枚举就这些了,那么PG是怎么检测的呢
kd> dt _KPROCESS nt!_KPROCESS +0x000 Header : _DISPATCHER_HEADER +0x018 ProfileListHead : _LIST_ENTRY +0x028 DirectoryTableBase : Uint8B +0x030 ThreadListHead : _LIST_ENTRY +0x040 ProcessLock : Uint8B +0x048 Affinity : _KAFFINITY_EX +0x070 ReadyListHead : _LIST_ENTRY +0x080 SwapListEntry : _SINGLE_LIST_ENTRY +0x088 ActiveProcessors : _KAFFINITY_EX +0x0b0 AutoAlignment : Pos 0, 1 Bit +0x0b0 DisableBoost : Pos 1, 1 Bit +0x0b0 DisableQuantum : Pos 2, 1 Bit +0x0b0 ActiveGroupsMask : Pos 3, 4 Bits +0x0b0 ReservedFlags : Pos 7, 25 Bits +0x0b0 ProcessFlags : Int4B +0x0b4 BasePriority : Char +0x0b5 QuantumReset : Char +0x0b6 Visited : UChar +0x0b7 Unused3 : UChar +0x0b8 ThreadSeed : [4] Uint4B +0x0c8 IdealNode : [4] Uint2B +0x0d0 IdealGlobalNode : Uint2B +0x0d2 Flags : _KEXECUTE_OPTIONS +0x0d3 Unused1 : UChar +0x0d4 Unused2 : Uint4B +0x0d8 Unused4 : Uint4B +0x0dc StackCount : _KSTACK_COUNT +0x0e0 ProcessListEntry : _LIST_ENTRY +0x0f0 CycleTime : Uint8B +0x0f8 KernelTime : Uint4B +0x0fc UserTime : Uint4B +0x100 InstrumentationCallback : Ptr64 Void +0x108 LdtFreeSelectorHint : Uint2B +0x10a LdtTableLength : Uint2B +0x108 Spare2 : [4] UChar +0x110 LdtSystemDescriptor : _KGDTENTRY64 +0x120 LdtBaseAddress : Ptr64 Void +0x128 LdtProcessLock : _KGUARDED_MUTEX +0x110 UserDirectoryTableBase : Uint8B +0x118 AddressPolicy : UChar +0x119 Spare3 : [71] UChar
PG可能会在每个进程Visited标志位设置一个随机数。
PG 类型 4 进程列表损坏 可能就是组合检测
SnowGuard检测隐藏进程是先遍历ActiveProcessLinks 给每个进程Visited设置值
之后使用PspCidTable去检测枚举进程的Visited,一旦发现Visited没有值,则可能存在ActiveProcessLinks断链
之后依次类推继续使用 HandleTableListHead ProcessListEntry 检测进程标志位,最后清除标志位即可。
参数1 2则是随机数,参数三是进程PID,参数四[对应]PG蓝屏
最后就是 或许你可以设置Visited标志位,PatchGuard就不会去检测你的隐藏进程了?