Rootkit技术之内核钩子原理[2]
作者:admin 日期:2010-04-10
Rootkit技术之内核钩子原理[1]
作者:admin 日期:2010-04-10
我们知道,应用程序总是离不开系统内核所提供的服务,比如它要使用内存的时候,只要跟操作系统申请就行了,而不用自己操心哪里有空闲的内存空间等问题,实际上,这些问题是由操作系统的内核来代劳的。站在黑客的角度讲,如果能够控制内核,实际上就是控制了内核之上的各种应用程序。本文将向您介绍如何建立内核级钩子来控制操作系统向上提供的各种低级功能。有了内核级钩子,我们不但能够控制、监视其他程序并过滤有关数据,还能用其实现Rootkit本身及其它程序的隐形。
本文首先回顾系统调用表和内存保护方面的知识,然后讲解如何实现内核钩子,最后对一些重要的内核函数进行了简要的说明。
一、系统调用表
本文首先回顾系统调用表和内存保护方面的知识,然后讲解如何实现内核钩子,最后对一些重要的内核函数进行了简要的说明。
一、系统调用表
内核中API与进程、线程和模块的监测
作者:admin 日期:2010-02-26
驱动开发中应该注意的事项
作者:admin 日期:2010-02-08
1. 一定不要在没有标注 I/O 请求数据包 (IRP) 挂起 (IoMarkIrpPending) 的情况下通过调度例程返回 STATUS_PENDING。
2. 一定不要通过中断服务例程 (ISR) 调用 KeSynchronizeExecution。 它会使系统死锁。
3. 一定不要将 DeviceObject->Flags 设置为 DO_BUFFERED_IO 和 DO_DIRECT_IO。 它会扰乱系统并最终导致致命错误。 而且,一定不要在 DeviceObject->Flags 中设置 METHOD_BUFFERED、METHOD_NEITHER、METHOD_IN_DIRECT 或 METHOD_OUT_DIRECT,因为这些值只在定义 IOCTL 时使用。
4. 一定不要通过页面缓冲池分配调度程序对象。 如果这样做,将会偶尔导致系统故障检测 (Bugcheck)。
5. 当运行于 IRQL >= DISPATCH_LEVEL 时,一定不要通过页面缓冲池分配内存,或访问页面缓冲池中的内存。 这是一个致命错误。
2. 一定不要通过中断服务例程 (ISR) 调用 KeSynchronizeExecution。 它会使系统死锁。
3. 一定不要将 DeviceObject->Flags 设置为 DO_BUFFERED_IO 和 DO_DIRECT_IO。 它会扰乱系统并最终导致致命错误。 而且,一定不要在 DeviceObject->Flags 中设置 METHOD_BUFFERED、METHOD_NEITHER、METHOD_IN_DIRECT 或 METHOD_OUT_DIRECT,因为这些值只在定义 IOCTL 时使用。
4. 一定不要通过页面缓冲池分配调度程序对象。 如果这样做,将会偶尔导致系统故障检测 (Bugcheck)。
5. 当运行于 IRQL >= DISPATCH_LEVEL 时,一定不要通过页面缓冲池分配内存,或访问页面缓冲池中的内存。 这是一个致命错误。
一个八年没发现的Linux内核bug
作者:admin 日期:2010-02-04
存在于网络工作socket初始化中的一个Linux内核bug可以使攻击者获得root权限而造成损害。安全漏洞存在于所有2.4和2.5系列的内核,这种情况很可能自2001年以来就存在了。
Bug的原因是socket初始化里一个错误的函数执行导致了一个空指针废弃。指针本应该将函数指向一个预定义的存根例程(stub routine),但是一些协议却没有将这些指针初始化。
受影响的协议的列表是相当长:AppleTalk,IPX,X.25,Irda,Bluetooth,ISDN,AX25和IUCV ,但是有可能还有更多。
Bug的原因是socket初始化里一个错误的函数执行导致了一个空指针废弃。指针本应该将函数指向一个预定义的存根例程(stub routine),但是一些协议却没有将这些指针初始化。
受影响的协议的列表是相当长:AppleTalk,IPX,X.25,Irda,Bluetooth,ISDN,AX25和IUCV ,但是有可能还有更多。
安装linux后的内核调优
作者:admin 日期:2010-02-04
在Linux中监视IO性能
作者:admin 日期:2010-02-04
Linux内核进行压力测试
作者:admin 日期:2010-02-04
Linux 标准测试的设计过程
自动软件测试让您可以在一段时间内运行相同的测试,从而确保您所比较的内容具备真正的可比性。在本文中,Linux Test Project 团队的成员们分享了他们对 Linux? 内核进行压力所使用的测试的方法、原理以及脚本和工具。
在对 Linux 内核版本稳定性的测试中,需要明确地声明并证明为什么版本是稳定的或者是不稳定的。然而还没有被证明和证实当前现有的系统范围内的压力测试可以测试 Linux 内核整体上的稳定性。本文给出了一个创建系统范围内 Linux 压力测试并证明其结果正确性的方法。不同的 Linux 开发者、用户和发行版本会使用他们自己的方法来测试内核的稳定性。不过,关于他们决定运行哪些测试、覆盖的代码、达到的压力级别等的基础信息都没有发布,这就大大降低了结果的价值。
自动软件测试让您可以在一段时间内运行相同的测试,从而确保您所比较的内容具备真正的可比性。在本文中,Linux Test Project 团队的成员们分享了他们对 Linux? 内核进行压力所使用的测试的方法、原理以及脚本和工具。
在对 Linux 内核版本稳定性的测试中,需要明确地声明并证明为什么版本是稳定的或者是不稳定的。然而还没有被证明和证实当前现有的系统范围内的压力测试可以测试 Linux 内核整体上的稳定性。本文给出了一个创建系统范围内 Linux 压力测试并证明其结果正确性的方法。不同的 Linux 开发者、用户和发行版本会使用他们自己的方法来测试内核的稳定性。不过,关于他们决定运行哪些测试、覆盖的代码、达到的压力级别等的基础信息都没有发布,这就大大降低了结果的价值。
分析linux内核的idle的知识
作者:admin 日期:2010-02-04
Linux系统越来越受到电脑用户的欢迎,于是很多人开始学习Linux时,学习linux,你可能会遇到linux内核问题,这里将介绍linux内核中idle知识,在这里拿出来和大家分享一下。
1. idle是什么
简单的说idle是一个进程,其pid号为 0。其前身是系统创建的第一个进程,也是唯一一个没有通过fork()产生的进程。在smp系统中,每个处理器单元有独立的一个运行队列,而每个运行队列上又有一个idle进程,即有多少处理器单元,就有多少idle进程。系统的空闲时间,其实就是指idle进程的"运行时间"。既然是idle是进程,那我们来看看idle是如何被创建,又具体做了哪些事情?
1. idle是什么
简单的说idle是一个进程,其pid号为 0。其前身是系统创建的第一个进程,也是唯一一个没有通过fork()产生的进程。在smp系统中,每个处理器单元有独立的一个运行队列,而每个运行队列上又有一个idle进程,即有多少处理器单元,就有多少idle进程。系统的空闲时间,其实就是指idle进程的"运行时间"。既然是idle是进程,那我们来看看idle是如何被创建,又具体做了哪些事情?
rootkit编程
作者:admin 日期:2009-12-22
一.先说几句与技术无关的话。
现在很多人对rootkit认识不够,可以说空白。而此愚文的目的就是让菜鸟认识rootkit→了解rootkit。也让一些想研究它的人把这篇文章当作一个参考或是入门级的指导。文章中介绍的rootkit的隐藏方法只是一部分。还有很多技术没有提到,另外还有一些未公开的技术。有些地方我未引用代码,因为不想占用过多的篇幅。以免有玩弄代码的嫌疑,不过写完以后还是觉得代码太多,请个位见谅。一-三的内容适合菜鸟看,也许第四部分之后对很多人来说都有些意义吧。如果高手不幸看到了,请准备好,不要吐到屏幕上或身上。
以往的文章写的比较乱,而且格式不公正,这样的形式写文章也是第一次。以前文章中引用代码和文字也没有详细说明,再此也对作者表示谦意。感谢XX提的这个建议。
今天是9月11号,庆祝一下童童的生日。顺便为911事件中的遇难者祈祷。同时也感谢MGF病毒的作者指点。
*************************
现在很多人对rootkit认识不够,可以说空白。而此愚文的目的就是让菜鸟认识rootkit→了解rootkit。也让一些想研究它的人把这篇文章当作一个参考或是入门级的指导。文章中介绍的rootkit的隐藏方法只是一部分。还有很多技术没有提到,另外还有一些未公开的技术。有些地方我未引用代码,因为不想占用过多的篇幅。以免有玩弄代码的嫌疑,不过写完以后还是觉得代码太多,请个位见谅。一-三的内容适合菜鸟看,也许第四部分之后对很多人来说都有些意义吧。如果高手不幸看到了,请准备好,不要吐到屏幕上或身上。
以往的文章写的比较乱,而且格式不公正,这样的形式写文章也是第一次。以前文章中引用代码和文字也没有详细说明,再此也对作者表示谦意。感谢XX提的这个建议。
今天是9月11号,庆祝一下童童的生日。顺便为911事件中的遇难者祈祷。同时也感谢MGF病毒的作者指点。
*************************
任务门,调用门,中断门,陷阱门
作者:admin 日期:2009-11-24
IRP结构
作者:admin 日期:2009-11-09
IRP 是 I/O request packet 的缩写,即 I/O 请求包。驱动与驱动之间通过 IRP 进行通信。而使用驱动的应用层调用的 CreatFile,ReadFile,WriteFile,DeviceIoControl 等函数,说到底也是使用 IRP 和驱动进行通信。
可以这么看这个IRP,这首先是一个定义好的数据结构,里面含有一个叫IO_STACK_LOCATION 结构组成的数组,每个元素是一个IO_STACK_LOCATION 结构,这个结构组成的数组的数量是有你irp包所在的驱动的层数决定的,如果此是所处的驱动程序的层数是2,也就是说下边还有一个驱动程序,数组就有两个IO_STACK_LOCATION 结构,可以用函数PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );得到此时所处驱动的IO_STACK_LOCATION 结构
[img]http://photo.hexun.com/p/2005/0715/2272/b_37F41840B9EB111B.jpg[/img]
此为一个IRP的整体结构,其中的Tail部分分为三部分组成,如下图:
可以这么看这个IRP,这首先是一个定义好的数据结构,里面含有一个叫IO_STACK_LOCATION 结构组成的数组,每个元素是一个IO_STACK_LOCATION 结构,这个结构组成的数组的数量是有你irp包所在的驱动的层数决定的,如果此是所处的驱动程序的层数是2,也就是说下边还有一个驱动程序,数组就有两个IO_STACK_LOCATION 结构,可以用函数PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );得到此时所处驱动的IO_STACK_LOCATION 结构
[img]http://photo.hexun.com/p/2005/0715/2272/b_37F41840B9EB111B.jpg[/img]
此为一个IRP的整体结构,其中的Tail部分分为三部分组成,如下图:
Windows内核初窥
作者:admin 日期:2009-11-08
每天我们都在使用Windows系统学习、编程、听音乐、玩游戏,Windows的操作想来是很熟练了,可是你又对Windows到底了解多少呢?本系列的目的,就是让你对Windows系统有个更直观、更清楚、更彻底的认识。虽然我们大多数人看不到Windows的源码,对其内存调度算法这种最深层次的技术内幕不能明窥,但是我们可以做到比现在知道的更多,了解这些之后你会发现在Windows上面开发会轻车熟路,任何木马病毒到了你机器上不过只会成为你的试验品。
鉴于Windows 9X内核早已淘汰,技术过时,在此不予讨论。主要是针对Windows2000(Windows 5.0)以后版本,尤以2000为主。要知道xp是Windows 5.1版本,2003也才是5.2版本。那么,对于本系列提到Windows OS技术,统指Windows 5.X技术。
一、直观认识Windows
鉴于Windows 9X内核早已淘汰,技术过时,在此不予讨论。主要是针对Windows2000(Windows 5.0)以后版本,尤以2000为主。要知道xp是Windows 5.1版本,2003也才是5.2版本。那么,对于本系列提到Windows OS技术,统指Windows 5.X技术。
一、直观认识Windows
突破windows nt 内核进程监视限制
作者:admin 日期:2009-11-08
Windows NT内核分析
作者:admin 日期:2009-11-08
GDT详解(全局描述符表)
作者:admin 日期:2009-10-21
在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table)。
为什么要有GDT?我们首先考虑一下在Real Mode下的编程模型:
在Real Mode下,我们对一个内存地址的访问是通过Segment:Offset的方式来进行的,其中Segment是一个段的Base Address,一个Segment的最大长度是64 KB,这是16-bit系统所能表示的最大长度。而Offset则是相对于此Segment Base Address的偏移量。Base Address+Offset就是一个内存绝对地址。由此,我们可以看出,一个段具备两个因素:Base Address和Limit(段的最大长度),而对一个内存地址的访问,则是需要指出:使用哪个段?以及相对于这个段Base Address的Offset,这个Offset应该小于此段的Limit。当然对于16-bit系统,Limit不要指定,默认为最大长度64KB,而 16-bit的Offset也永远不可能大于此Limit。我们在实际编程的时候,使用16-bit段寄存器CS(Code Segment),DS(Data Segment),SS(Stack Segment)来指定Segment,CPU将段积存器中的数值向左偏移4-bit,放到20-bit的地址线上就成为20-bit的Base Address。
到了Protected Mode,内存的管理模式分为两种,段模式和页模式,其中页模式也是基于段模式的。也就是说,Protected Mode的内存管理模式事实上是:纯段模式和段页式。进一步说,段模式是必不可少的,而页模式则是可选的——如果使用页模式,则是段页式;否则这是纯段模式。
既然是这样,我们就先不去考虑页模式。对于段模式来讲,访问一个内存地址仍然使用Segment:Offset的方式,这是很自然的。由于 Protected Mode运行在32-bit系统上,那么Segment的两个因素:Base Address和Limit也都是32位的。IA-32允许将一个段的Base Address设为32-bit所能表示的任何值(Limit则可以被设为32-bit所能表示的,以2^12为倍数的任何指),而不象Real Mode下,一个段的Base Address只能是16的倍数(因为其低4-bit是通过左移运算得来的,只能为0,从而达到使用16-bit段寄存器表示20-bit Base Address的目的),而一个段的Limit只能为固定值64 KB。另外,Protected Mode,顾名思义,又为段模式提供了保护机制,也就说一个段的描述符需要规定对自身的访问权限(Access)。所以,在Protected Mode下,对一个段的描述则包括3方面因素:[Base Address, Limit, Access],它们加在一起被放在一个64-bit长的数据结构中,被称为段描述符。这种情况下,如果我们直接通过一个64-bit段描述符来引用一个段的时候,就必须使用一个64-bit长的段积存器装入这个段描述符。但Intel为了保持向后兼容,将段积存器仍然规定为16-bit(尽管每个段积存器事实上有一个64-bit长的不可见部分,但对于程序员来说,段积存器就是16-bit的),那么很明显,我们无法通过16-bit长度的段积存器来直接引用64-bit的段描述符。
为什么要有GDT?我们首先考虑一下在Real Mode下的编程模型:
在Real Mode下,我们对一个内存地址的访问是通过Segment:Offset的方式来进行的,其中Segment是一个段的Base Address,一个Segment的最大长度是64 KB,这是16-bit系统所能表示的最大长度。而Offset则是相对于此Segment Base Address的偏移量。Base Address+Offset就是一个内存绝对地址。由此,我们可以看出,一个段具备两个因素:Base Address和Limit(段的最大长度),而对一个内存地址的访问,则是需要指出:使用哪个段?以及相对于这个段Base Address的Offset,这个Offset应该小于此段的Limit。当然对于16-bit系统,Limit不要指定,默认为最大长度64KB,而 16-bit的Offset也永远不可能大于此Limit。我们在实际编程的时候,使用16-bit段寄存器CS(Code Segment),DS(Data Segment),SS(Stack Segment)来指定Segment,CPU将段积存器中的数值向左偏移4-bit,放到20-bit的地址线上就成为20-bit的Base Address。
到了Protected Mode,内存的管理模式分为两种,段模式和页模式,其中页模式也是基于段模式的。也就是说,Protected Mode的内存管理模式事实上是:纯段模式和段页式。进一步说,段模式是必不可少的,而页模式则是可选的——如果使用页模式,则是段页式;否则这是纯段模式。
既然是这样,我们就先不去考虑页模式。对于段模式来讲,访问一个内存地址仍然使用Segment:Offset的方式,这是很自然的。由于 Protected Mode运行在32-bit系统上,那么Segment的两个因素:Base Address和Limit也都是32位的。IA-32允许将一个段的Base Address设为32-bit所能表示的任何值(Limit则可以被设为32-bit所能表示的,以2^12为倍数的任何指),而不象Real Mode下,一个段的Base Address只能是16的倍数(因为其低4-bit是通过左移运算得来的,只能为0,从而达到使用16-bit段寄存器表示20-bit Base Address的目的),而一个段的Limit只能为固定值64 KB。另外,Protected Mode,顾名思义,又为段模式提供了保护机制,也就说一个段的描述符需要规定对自身的访问权限(Access)。所以,在Protected Mode下,对一个段的描述则包括3方面因素:[Base Address, Limit, Access],它们加在一起被放在一个64-bit长的数据结构中,被称为段描述符。这种情况下,如果我们直接通过一个64-bit段描述符来引用一个段的时候,就必须使用一个64-bit长的段积存器装入这个段描述符。但Intel为了保持向后兼容,将段积存器仍然规定为16-bit(尽管每个段积存器事实上有一个64-bit长的不可见部分,但对于程序员来说,段积存器就是16-bit的),那么很明显,我们无法通过16-bit长度的段积存器来直接引用64-bit的段描述符。
反汇编驱动常用结构体
作者:admin 日期:2009-10-03
Another way to HOOK in the kernel (内核钩子的另一种方法)
作者:admin 日期:2009-09-30
Writer:yykingking
Rk always use HOOK important functions to hide something , and some ARK first recover these hookers ( common by harddisk files) and then call the function.
And this is another way to HOOK in the kernel by DRX register. About the DRX register ,you can google it, there should be much info. So i only post some simple code next because of my poor english, if you know chinese, you can get the comment.
Rk always use HOOK important functions to hide something , and some ARK first recover these hookers ( common by harddisk files) and then call the function.
And this is another way to HOOK in the kernel by DRX register. About the DRX register ,you can google it, there should be much info. So i only post some simple code next because of my poor english, if you know chinese, you can get the comment.