首页
社区
课程
招聘
[原创]rootkit ring3进ring0之门系列[一] -- 调用门
发表于: 2008-3-31 14:52 63819

[原创]rootkit ring3进ring0之门系列[一] -- 调用门

2008-3-31 14:52
63819

今天我们来谈谈保护模式下的调用门。从而开始了我们的门系列内容。
先谈谈程序转移.,程序转移分为两种: 近转移和远转移 ,其中近转移中又分为相对地址转移和绝对地址转移. 而远转移只有绝对地址转移.。可以通俗的讲,cs发生变化的转移称为远转移,cs不变的转移,我们称为近转移。例如:windows  ring3下cs是0x1b , ring0下cs通常是0x08.。 对于近转移,我们不需要进行特权级检查。由于windows是保护模式的操作系统,对于远转移如果跨层则需要进行特权级检查,看是否允许其调用。

为了在不同特权级的代码段之间进行控制访问,处理器特别提供了一组称为门描述符的描述符。我们可以通过这组门描述符中的任何一个进行远转移。门提供了受保护的间接调用,为任务内的特权转移提供了安全可靠的方法。

今天我们讲的调用门,就是这组门描述符中的一个。为了搞清楚调用门,我们需要看下调用门描述符的结构:

对应的结构体是:
    typedef struct
    {
        unsigned short  offset_0_15;
        unsigned short  selector;

        unsigned char    param_count : 4;
        unsigned char    some_bits   : 4;

        unsigned char    type        : 4;
        unsigned char    app_system  : 1;
        unsigned char    dpl         : 2;
        unsigned char    present     : 1;
   
        unsigned short  offset_16_31;
    } CALLGATE_DESCRIPTOR;

调用门描述符可以放在GDT、LDT中,但是不能放在IDT中。在WINDOWS XP中,没有LDT.
在这里,我们举例说明其在GDT中的情况。尽管windows提供了多种不同的描述符,但是每种描述符中都有present位代表该描述符是否存在。它在每个描述符中的位置都是一样的,因此我们可以根据这个present位来在GDT中找出一个空白位置,在这个位置里面添加我们自己定义的描述符。内核中GDT的位置,我们可以用WINDBG看下:
lkd> !PCR
KPCR for Processor 0 at ffdff000:
    Major 1 Minor 1
        NtTib.ExceptionList: b1fa5c7c
            NtTib.StackBase: b1fa5df0
           NtTib.StackLimit: b1fa2000
         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: 88899020
                 NextThread: 00000000
                 IdleThread: 80552d20

可以看到我本机GDT的位置是 GDT: 8003f000

调用门的工作原理如图所示。
首先进行特权检查
根据selector,在GDT中找出CS段的范围。
根据offset_0_15和offset_16_31求出段中的偏移。
跳转到地址中执行。

特权检查需要检查的内容包括:CPL,RPL,调用门DPL和目标段描述符DPL.

特权检查的规则:

最后简单介绍下demo的做法:
1)根据present位是否为0,我们遍历GDT中的表,找到一个present为0的位置。
2)在该位置添加调用门。
3)记下该位置对应的选择子。由于需要在ring3下调用,
    因此选择子CallGate_Sel = 索引值 or 0x03. 其中0x03代表我们设置的RPL.
4) 通过指令call FWORD ptr CallGate_Sel 执行调用门。

本例中,我们添加的调用门在gdt中的偏移值是0x48, 我们设置RPL = 3,因此对应的选择子应该是CallGate_Sel = 0x48 | 0x03 = 0x4b.

代码附上:
.386
.model flat, stdcall
option casemap:none

include myCallGate.inc
.const
CCOUNTED_UNICODE_STRING  "\\Device\\MYCALLGATE",g_usDeviceName,4
CCOUNTED_UNICODE_STRING  "\\??\\MYCALLGATE",g_usSymbolicLinkName,4

GDT_LIMIT  = 03ffh
GATE_TYPE  = 0ECH

.code
Ring0Fun proc
        pushad
        pushfd
        cli
        invoke DbgPrint, $CTA0("mycallgate function executed\n")
        ;add your code here, you can do anything if you like.
        sti
        popfd
        popad
        retf
Ring0Fun endp

AddCallGate proc FuncAddr:ULONG
    pushfd
    pushad
   
        push esi
        sgdt [esp-2]
        pop esi
       
        mov eax,8
        .while eax < GDT_LIMIT
             lea edx,[esi+eax]
             assume edx:ptr CALLGATE
             test [edx].GTYPE,80h
            .if ZERO?
               mov ebx,FuncAddr
               mov [edx].OFFSETL,bx
               mov [edx].SELECTOR,08h
               mov [edx].DCOUNT,0
               mov [edx].GTYPE,GATE_TYPE
               shr ebx,16
               mov [edx].OFFSETH,bx     
          .break
           .endif   
            assume edx:nothing
           add eax,8
        .endw
     
        popad
    popfd
        ret

AddCallGate endp

DispatchControl proc uses esi edi pDeviceObject:PDEVICE_OBJECT,pIrp:PIRP
       
        mov esi,pIrp
        assume esi:ptr _IRP
        mov [esi].IoStatus.Status ,STATUS_SUCCESS
        and [esi].IoStatus.Information,0
        invoke IoCompleteRequest,pIrp,0
        mov eax,[esi].IoStatus.Status
        assume esi:nothing
        ret

DispatchControl endp

DriverUnload proc pDriverObject:PDRIVER_OBJECT
       
        invoke IoDeleteSymbolicLink,addr g_usSymbolicLinkName
        mov eax,pDriverObject
        invoke IoDeleteDevice,(DRIVER_OBJECT PTR[eax]).DeviceObject
        ret

DriverUnload endp

DriverEntry proc pDriverObject:PDRIVER_OBJECT,pusRegistryPath:PUNICODE_STRING

    LOCAL status:NTSTATUS
    LOCAL pDeviceObject:PDEVICE_OBJECT
   
    mov status,STATUS_DEVICE_CONFIGURATION_ERROR
    invoke IoCreateDevice,pDriverObject,0,addr g_usDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,addr pDeviceObject
    .if eax == STATUS_SUCCESS
        invoke IoCreateSymbolicLink ,addr g_usSymbolicLinkName,addr g_usDeviceName
        .if eax == STATUS_SUCCESS            
                    mov eax,pDriverObject
                    assume eax:ptr DRIVER_OBJECT
                    mov ecx,IRP_MJ_MAXIMUM_FUNCTION + 1
                    .while ecx
                        dec ecx
                        mov [eax].MajorFunction[ecx * (sizeof PVOID)],offset DispatchControl
                    .endw
                    mov [eax].DriverUnload,offset DriverUnload
                    assume eax:nothing
                   invoke AddCallGate,offset Ring0Fun
            mov status,STATUS_SUCCESS
        .else
                invoke IoDeleteDevice,pDeviceObject
        .endif
    .endif
  
    mov eax,status
    ret

DriverEntry endp

end DriverEntry

最后友情提示:
    由于添加调用门的位置,我们事先并不知道,如果你想做的智能些的话,可以通过注册表,共享区,或者直接deviceiocontrol等等的方式通知ring3程序选择子是多少。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (51)
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
好文章
学习~
2008-3-31 16:35
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢楼主!!!!
2008-3-31 16:45
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
强啊,收藏。。。。。。。。。。。。。
2008-3-31 17:05
0
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
5
学习学习
2008-3-31 17:14
0
雪    币: 332
活跃值: (30)
能力值: ( LV12,RANK:460 )
在线值:
发帖
回帖
粉丝
6
正想看呢,就有了
2008-3-31 18:43
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
7
学习  膜拜。。。。。
2008-3-31 20:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
combojiang大虾的系列文章甚是经典啊。。
收藏ing。。。。
2008-4-1 09:35
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好文章,收藏了。另外我转到自己博客了,若是不妥,请mail告诉我
2008-4-2 13:41
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dem
10
经典的好东西啊,收藏了~
2008-4-2 19:21
0
雪    币: 334
活跃值: (22)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
不错不错呀~~支持lz
2008-4-8 22:26
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
12
好东西.
请问一下, 这个要用什么软体去Compiler ?
2008-5-2 10:01
0
雪    币: 235
活跃值: (23)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
masm+Kmd
2008-5-2 10:12
0
雪    币: 230
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
cool,很强大
2008-6-9 21:47
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
good !!
2008-6-9 23:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
学习 mark
2008-7-27 19:17
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
好文章!学习中!
2008-9-7 10:14
0
雪    币: 97697
活跃值: (200839)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
18
support.
2008-9-7 11:22
0
雪    币: 229
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
    模拜,,
2008-9-17 21:53
0
雪    币: 207
活跃值: (125)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
高手....
2008-10-8 18:46
0
雪    币: 207
活跃值: (125)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
绝对值得收藏.
2008-10-8 18:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
sys文件的编译环境能介绍一下吗?
2008-10-13 11:57
0
雪    币: 219
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
留位慢慢读.
2008-10-19 20:52
0
雪    币: 331
活跃值: (57)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
24
嘿嘿,单步call fword ptr [farcall]会蓝屏的!!
可以Anti-Debug哟……
2008-12-8 17:52
0
雪    币: 60
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
学习了 ]
2008-12-8 18:59
0
游客
登录 | 注册 方可回帖
返回
//