⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rootkit 直接访问硬件之[三].txt

📁 利用rootkits 技术实现对硬件的操作的驱动程序源码及其详细说明文档
💻 TXT
📖 第 1 页 / 共 2 页
字号:
rootkit 直接访问硬件之[三]
作 者: combojiang
时 间: 2008-03-28,17:21
链 接: http://bbs.pediy.com/showthread.php?t=62081

关于ring3直接访问硬件的办法,前面已经介绍了2篇,本篇算是结束篇了。篇幅较长,大家慢慢阅读。高手飘过。
基本上我们能依据8条保护规则来进行访问的情况都概括了。还是跟前面一样,我们先贴出保护规则来。
(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访问。
回顾下保护模式中介绍:80386采用I/O特权级IPOL和I/O许可位图的方法来控制输入/输出,实现输入/输出保护.I/O许可位图位于任务状态段TSS中。I/O特权级IPOL就是EFLAGS寄存器中IOPL位。
我们先看看I/O许可位图,它位于任务状态段TSS中。我们可以在GDT中根据找到任务状态段描述符,根据这个描述符,我们可以找到TSS在内存中的位置。TSS是保存一个任务重要信息的特殊段。我们先看看其内存结构。
lkd> dt _ktss
nt!_KTSS
   +0x000 Backlink         : Uint2B
   +0x002 Reserved0        : Uint2B
   +0x004 Esp0             : Uint4B
   +0x008 Ss0              : Uint2B
   +0x00a Reserved1        : Uint2B
   +0x00c NotUsed1         : [4] Uint4B
   +0x01c CR3              : Uint4B
   +0x020 Eip              : Uint4B
   +0x024 EFlags           : Uint4B
   +0x028 Eax              : Uint4B
   +0x02c Ecx              : Uint4B
   +0x030 Edx              : Uint4B
   +0x034 Ebx              : Uint4B
   +0x038 Esp              : Uint4B
   +0x03c Ebp              : Uint4B
   +0x040 Esi              : Uint4B
   +0x044 Edi              : Uint4B
   +0x048 Es               : Uint2B
   +0x04a Reserved2        : Uint2B
   +0x04c Cs               : Uint2B
   +0x04e Reserved3        : Uint2B
   +0x050 Ss               : Uint2B
   +0x052 Reserved4        : Uint2B
   +0x054 Ds               : Uint2B
   +0x056 Reserved5        : Uint2B
   +0x058 Fs               : Uint2B
   +0x05a Reserved6        : Uint2B
   +0x05c Gs               : Uint2B
   +0x05e Reserved7        : Uint2B
   +0x060 LDT              : Uint2B
   +0x062 Reserved8        : Uint2B
   +0x064 Flags            : Uint2B
   +0x066 IoMapBase        : Uint2B
   +0x068 IoMaps           : [1] _KiIoAccessMap
   +0x208c IntDirectionMap  : [32] UChar
lkd> dt _KiIoAccessMap
nt!_KiIoAccessMap
   +0x000 DirectionMap     : [32] UChar
   +0x020 IoMap            : [8196] UChar

其中的IoMapBase就是I/O许可位图的在TSS段中的偏移位置。也就是说在TSS段中从这个位置开始就是I/O许可位图了。另外在这个结构中还有IoMaps.IoMap一项,这是个长度为8196字节的数组。在Windows 32位操作系统中,端口是由word类型来描述的,也就是说最大端口数量就是65536,即64k.由于每个端口使用一个bit位来描述,因此64k的端口占用字节数就是65536/8 = 8192字节。因此,我们完全可以使用IoMaps.IoMap[8196]作为我们I/O许可位图区域。从结构上看,IoMaps.IoMap位于tss段偏移0x88位置处。
也就是说,如果我们把I/O许可位图放到IoMaps.IoMap中,然后让 IoMapBase 和进程中的IopmOffset指向这个位置就行了。这个是我们的整体思路。

windows提供以下三个内核函数:
BOOLEAN Ke386QueryIoAccessMap(ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap);
BOOLEAN Ke386SetIoAccessMap(ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap);
BOOLEAN Ke386IoSetAccessProcess(PKPROCESS Process, ULONG MapNumber); 

其中第一个函数,是查询端口访问许可用的。第二个,第三个函数是用于设置tssI/O许可位图的, 我们可以分析下第二、第三个函数,来验证下我们的思路。

lkd> u Ke386SetIoAccessMap L 30
nt!Ke386SetIoAccessMap:
804f80fe 8bff            mov     edi,edi
804f8100 55              push    ebp
804f8101 8bec            mov     ebp,esp
804f8103 57              push    edi
804f8104 8b7d08          mov     edi,dword ptr [ebp+8]
804f8107 83ff01          cmp     edi,1
804f810a 7759            ja      nt!Ke386SetIoAccessMap+0x67 (804f8165)
804f810c 85ff            test    edi,edi
804f810e 7455            je      nt!Ke386SetIoAccessMap+0x67 (804f8165)
804f8110 53              push    ebx
804f8111 56              push    esi
804f8112 ff158c864d80    call    dword ptr [nt!_imp__KeRaiseIrqlToSynchLevel (804d868c)]
804f8118 8ad8            mov     bl,al
804f811a 3ea120f0dfff    mov     eax,dword ptr ds:[FFDFF020h]
804f8120 8bd0            mov     edx,eax
804f8122 b800f0dfff      mov     eax,0FFDFF000h
804f8127 69ff24200000    imul    edi,edi,2024h    ; edi = 2024h
804f812d 8b4040          mov     eax,dword ptr [eax+40h]  
804f8130 8b750c          mov     esi,dword ptr [ebp+0Ch]
804f8133 8dbc0764e0ffff  lea     edi,[edi+eax-1F9Ch]        
804f813a b900080000      mov     ecx,800h   ;这里奇怪,IOPM数组总长为2000h。
为什么拷贝一部分?
804f813f f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
804f8141 8b4204          mov     eax,dword ptr [edx+4] ; eax = CurrentThread
804f8144 8b4844          mov     ecx,dword ptr [eax+44h] ;ecx = CurrentProcess
804f8147 b800f0dfff      mov     eax,0FFDFF000h 
804f814c 668b4930        mov     cx,word ptr [ecx+30h] ;cx = IopmOffset
804f8150 8b4040          mov     eax,dword ptr [eax+40h] ;tss
804f8153 66894866        mov     word ptr [eax+66h],cx
804f8157 8acb            mov     cl,bl
804f8159 ff151c874d80    call    dword ptr [nt!_imp_KfLowerIrql (804d871c)]
804f815f 5e              pop     esi
804f8160 b001            mov     al,1
804f8162 5b              pop     ebx
804f8163 eb02            jmp     nt!Ke386SetIoAccessMap+0x69 (804f8167)
804f8165 32c0            xor     al,al
804f8167 5f              pop     edi
804f8168 5d              pop     ebp
804f8169 c20800          ret     8
804f816c cc              int     3
804f816d cc              int     3
804f816e cc              int     3
804f816f cc              int     3
804f8170 cc              int     3

上述代码中的一些重要偏移值解释如下:
1。0FFDFF000h 对应于KPCR, 用WINDBG看
lkd> !PCR
KPCR for Processor 0 at ffdff000:
    Major 1 Minor 1
  NtTib.ExceptionList: b2616c7c
      NtTib.StackBase: b2616df0
     NtTib.StackLimit: b2614000
   NtTib.SubSystemTib: 00000000
        NtTib.Version: 00000000
    NtTib.UserPointer: 00000000
        NtTib.SelfTib: 7ffde000

              SelfPcr: ffdff000
                 Prcb: ffdff120
                 Irql: 00000000
                  IRR: 00000000
                  IDR: ffffffff
        InterruptMode: 00000000
                  IDT: 8003f400
                  GDT: 8003f000
                  TSS: 80042000

        CurrentThread: 88fb6da8
           NextThread: 00000000
           IdleThread: 80552d20

            DpcQueue: 

2。看KPCR结构,ds:[FFDFF020h]对应于 Prcb,KPCR偏移0x40位置对应于 TSS 
lkd> dt _kpcr
nt!_KPCR
   +0x000 NtTib            : _NT_TIB
   +0x01c SelfPcr          : Ptr32 _KPCR
   +0x020 Prcb             : Ptr32 _KPRCB
   +0x024 Irql             : UChar
   +0x028 IRR              : Uint4B
   +0x02c IrrActive        : Uint4B
   +0x030 IDR              : Uint4B
   +0x034 KdVersionBlock   : Ptr32 Void
   +0x038 IDT              : Ptr32 _KIDTENTRY
   +0x03c GDT              : Ptr32 _KGDTENTRY
   +0x040 TSS              : Ptr32 _KTSS
   +0x044 MajorVersion     : Uint2B
   +0x046 MinorVersion     : Uint2B
   +0x048 SetMember        : Uint4B
   +0x04c StallScaleFactor : Uint4B
   +0x050 DebugActive      : UChar
   +0x051 Number           : UChar
   +0x052 Spare0           : UChar
   +0x053 SecondLevelCacheAssociativity : UChar
   +0x054 VdmAlert         : Uint4B
   +0x058 KernelReserved   : [14] Uint4B
   +0x090 SecondLevelCacheSize : Uint4B
   +0x094 HalReserved      : [16] Uint4B
   +0x0d4 InterruptMode    : Uint4B
   +0x0d8 Spare1           : UChar
   +0x0dc KernelReserved2  : [17] Uint4B
   +0x120 PrcbData         : _KPRCB

3。 看tss结构,偏移0x88处对应于IoMaps[0].IoMap,偏移0x66处,对应IoMapBase。
lkd> dt _ktss
nt!_KTSS
   +0x000 Backlink         : Uint2B
   +0x002 Reserved0        : Uint2B
   +0x004 Esp0             : Uint4B
   +0x008 Ss0              : Uint2B
   +0x00a Reserved1        : Uint2B
   +0x00c NotUsed1         : [4] Uint4B
   +0x01c CR3              : Uint4B
   +0x020 Eip              : Uint4B
   +0x024 EFlags           : Uint4B
   +0x028 Eax              : Uint4B
   +0x02c Ecx              : Uint4B
   +0x030 Edx              : Uint4B
   +0x034 Ebx              : Uint4B
   +0x038 Esp              : Uint4B
   +0x03c Ebp              : Uint4B
   +0x040 Esi              : Uint4B
   +0x044 Edi              : Uint4B
   +0x048 Es               : Uint2B
   +0x04a Reserved2        : Uint2B
   +0x04c Cs               : Uint2B
   +0x04e Reserved3        : Uint2B
   +0x050 Ss               : Uint2B
   +0x052 Reserved4        : Uint2B
   +0x054 Ds               : Uint2B
   +0x056 Reserved5        : Uint2B
   +0x058 Fs               : Uint2B
   +0x05a Reserved6        : Uint2B
   +0x05c Gs               : Uint2B
   +0x05e Reserved7        : Uint2B
   +0x060 LDT              : Uint2B
   +0x062 Reserved8        : Uint2B
   +0x064 Flags            : Uint2B
   +0x066 IoMapBase        : Uint2B
   +0x068 IoMaps           : [1] _KiIoAccessMap
   +0x208c IntDirectionMap  : [32] UChar
lkd> dt _KiIoAccessMap
nt!_KiIoAccessMap
   +0x000 DirectionMap     : [32] UChar
   +0x020 IoMap            : [8196] UChar

4。Prcb对应的_KPRCB,其偏移0x4字节对应于CurrentThread
lkd> dt _KPRCB
ntdll!_KPRCB
   +0x000 MinorVersion     : Uint2B
   +0x002 MajorVersion     : Uint2B
   +0x004 CurrentThread    : Ptr32 _KTHREAD
   +0x008 NextThread       : Ptr32 _KTHREAD
   +0x00c IdleThread       : Ptr32 _KTHREAD
   +0x010 Number           : Char
   +0x011 Reserved         : Char
   +0x012 BuildType        : Uint2B
   +0x014 SetMember        : Uint4B
   +0x018 CpuType          : Char
   +0x019 CpuID            : Char
   +0x01a CpuStep          : Uint2B
   +0x01c ProcessorState   : _KPROCESSOR_STATE
   +0x33c KernelReserved   : [16] Uint4B
   +0x37c HalReserved      : [16] Uint4B
   +0x3bc PrcbPad0         : [92] UChar
   +0x418 LockQueue        : [16] _KSPIN_LOCK_QUEUE
   +0x498 PrcbPad1         : [8] UChar
   +0x4a0 NpxThread        : Ptr32 _KTHREAD
   +0x4a4 InterruptCount   : Uint4B
   +0x4a8 KernelTime       : Uint4B
   +0x4ac UserTime         : Uint4B
   +0x4b0 DpcTime          : Uint4B
   +0x4b4 DebugDpcTime     : Uint4B
   +0x4b8 InterruptTime    : Uint4B
   +0x4bc AdjustDpcThreshold : Uint4B
   +0x4c0 PageColor        : Uint4B
   +0x4c4 SkipTick         : Uint4B
   +0x4c8 MultiThreadSetBusy : UChar
   +0x4c9 Spare2           : [3] UChar
   +0x4cc ParentNode       : Ptr32 _KNODE
   +0x4d0 MultiThreadProcessorSet : Uint4B
   +0x4d4 MultiThreadSetMaster : Ptr32 _KPRCB
   +0x4d8 ThreadStartCount : [2] Uint4B
   +0x4e0 CcFastReadNoWait : Uint4B
   +0x4e4 CcFastReadWait   : Uint4B
   +0x4e8 CcFastReadNotPossible : Uint4B
   +0x4ec CcCopyReadNoWait : Uint4B
   +0x4f0 CcCopyReadWait   : Uint4B
   +0x4f4 CcCopyReadNoWaitMiss : Uint4B

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -