rootkit直接访问硬件之一 ----修改IOPL

今天我们一起来探索下如何实现ring3程序直接访问硬件。这部分内容跟windows保护模式中的I/O保护部分有直接的关系。

我们来看看Windows系统I/O访问保护的方法:

80386采用 I/O特权级IPOL I/O许可位图 的方法来控制输入/输出,实现输入/输出保护.

I/O许可位图位于 任务状态段TSS中。 I/O特权级IPOL就是EFLAGS寄存器中IOPL位。

采用的保护规则 是:

(1)若CPL<=IOPL,则直接转步骤(8);

(2)取得I/O位图开始偏移;

(3)计算I/O地址对应位所在字节在I/O许可位图内的偏移;

(4)计算位偏移以形成屏蔽码值,即计算I/O地址对应位在字节中的第几位;

(5)把字节偏移加上位图开始偏移,再加1,所得值与TSS界限比较,若越界,则产生出错码为0的通用保护故障;

(6)若不越界,则从位图中读对应字节及下一个字节;

(7)把读出的两个字节与屏蔽码进行与运算,若结果不为0表示检查未通过,则产生出错码为0的通用保护故障;

(8)进行I/O访问。

其中windows中IOPL值是为0,从第一条规则我们可以了解到为什么ring0下可以直接访问I/O了,因为ring0中CPL = 0 ,完全满足第一条。而ring3下CPL = 3 ,第一条不能满足。

我们知道每个任务使用各自的EFLAGS值和拥有自己的TSS,所以每个任务可以有不同的IOPL。所以想在ring3下访问I/O,最简单的方法当然是修改当前进程IOPL的值为3了。

根据前面了解到 IPOL就是EFLAGS寄存器中IOPL位,所以我们尝试下修改eflags寄存器看看。如图:

 我们写段代码看看:

#include "stdio.h"

int main(int argc, char* argv[])

{

  _asm

  {

    pushfd

    pop eax   

    or eax,0x3000  //设置iopl = 3

    push eax

    popfd

    pushfd   //看看修改后的效果

    pop eax  //eflags寄存器的值保存到eax中

  }

  return 0;

}

通过上面代码,我们发现不能直接修改eflags中iopl的值。呵呵,继续想办法吧。

每个Windows进程都有一个相对应的执行体进程(EPROCESS),EPROCESS不仅包括了进程的许多属性,还包扩了许多指向其他数据结构的指针,其中包含了大量有用的信息. 

为了找出思路,我们还是先看看进程eprocess吧。

lkd> dt _eprocess

ntdll!_EPROCESS

   +0x000 Pcb              : _KPROCESS

   +0x06c ProcessLock      : _EX_PUSH_LOCK

   +0x070 CreateTime       : _LARGE_INTEGER

   +0x078 ExitTime         : _LARGE_INTEGER

   +0x080 RundownProtect   : _EX_RUNDOWN_REF

   +0x084 UniqueProcessId  : Ptr32 Void

   +0x088 ActiveProcessLinks : _LIST_ENTRY

   +0x090 QuotaUsage       : [3] Uint4B

   +0x09c QuotaPeak        : [3] Uint4B

   +0x0a8 CommitCharge     : Uint4B

   +0x0ac PeakVirtualSize  : Uint4B

   +0x0b0 VirtualSize      : Uint4B

   +0x0b4 SessionProcessLinks : _LIST_ENTRY

   +0x0bc DebugPort        : Ptr32 Void

   +0x0c0 ExceptionPort    : Ptr32 Void

   +0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE

   +0x0c8 Token            : _EX_FAST_REF

   +0x0cc WorkingSetLock   : _FAST_MUTEX

   +0x0ec WorkingSetPage   : Uint4B

   +0x0f0 AddressCreationLock : _FAST_MUTEX

   +0x110 HyperSpaceLock   : Uint4B

   +0x114 ForkInProgress   : Ptr32 _ETHREAD

   +0x118 HardwareTrigger  : Uint4B

   +0x11c VadRoot          : Ptr32 Void

   +0x120 VadHint          : Ptr32 Void

   +0x124 CloneRoot        : Ptr32 Void

   +0x128 NumberOfPrivatePages : Uint4B

   +0x12c NumberOfLockedPages : Uint4B

   +0x130 Win32Process     : Ptr32 Void

   +0x134 Job              : Ptr32 _EJOB

   +0x138 SectionObject    : Ptr32 Void

   +0x13c SectionBaseAddress : Ptr32 Void

   +0x140 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK

   +0x144 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY

   +0x148 Win32WindowStation : Ptr32 Void

   +0x14c InheritedFromUniqueProcessId : Ptr32 Void

   +0x150 LdtInformation   : Ptr32 Void

   +0x154 VadFreeHint      : Ptr32 Void

   +0x158 VdmObjects       : Ptr32 Void

   +0x15c DeviceMap        : Ptr32 Void

   +0x160 PhysicalVadList  : _LIST_ENTRY

   +0x168 PageDirectoryPte : _HARDWARE_PTE_X86

   +0x168 Filler           : Uint8B

   +0x170 Session          : Ptr32 Void

   +0x174 ImageFileName    : [16] UChar

   +0x184 JobLinks         : _LIST_ENTRY

   +0x18c LockedPagesList  : Ptr32 Void

   +0x190 ThreadListHead   : _LIST_ENTRY

   +0x198 SecurityPort     : Ptr32 Void

   +0x19c PaeTop           : Ptr32 Void

   +0x1a0 ActiveThreads    : Uint4B

   +0x1a4 GrantedAccess    : Uint4B

   +0x1a8 DefaultHardErrorProcessing : Uint4B

   +0x1ac LastThreadExitStatus : Int4B

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值