任务段与任务门

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

任务段与任务门

索引:

1.任务段

2.如何加载一个段寄存器和取出段寄存器

3.TSS的作用(在Windows操作系统上)

4.如何查看TSS段内容

5.构造TSS门并进行提权

6.使用int3指令断下观察esp的实验(出现一个elfags标志位的坑)

7.int3断下时,如果不回复eflags寄存器,其就会卡死

8.任务门的作用(在Windows操作系统上)

9.任务门实验

解答:

1.  任务段

   任务段是系统段的一种,Windows操作系统只运行一个(启动时就已经确定)
    

    查看对应的任务段的属性,当切换进执行程序时,其会将任务段属性改为繁忙,
    可以看出下表红色的位置。
    

tr 寄存器表示当前的任务段,我们可以使用windbg 的 dg指令解析该段

  

2. 如何加载一个段寄存器和取出段寄存器
    加载段寄存器 load (零环)
    mov ax,0x28
    ltr ax
    取出段寄存器 store (三环)
    str dword ds:[0x12345678]
    获取gdt:  sgdt (三环)  加载gdt: lgdt (零环)
 获取idt: sidt ……………

 3. TSS的作用(在Windows操作系统上)
    线程切换时,一次保存多个寄存器。
    注意:是线程切换,不是进程切换,进程切换还要替换整个环境远不止寄存器那么多!!

4. 如何查看TSS段内的内容
    TSS的地址就是TSS段描述符描述的基地址,因此我们通过 dg tr 查看其Base为 80042000。
    对于查看TSS段,有一个单独的指令。
    dt _KTSS base_address
    效果如下图(此时没用到,之后线程切换会有新的效果)

  

 5. 构造tss门并进行提权
  1)实验代码

        // test.cpp : Defines the entry point for the console application.
        //

        #include "stdafx.h"
        #include "windows.h"

        DWORD iTSS[26];
        DWORD ESP0[0x1000];
        DWORD ESP3[0x1000];

        DWORD dwESP;
        DWORD dwCS;
        DWORD dwCR3;

        _declspec(naked) void Call(){
            _asm{

                mov dwESP,ESP;
                mov ax,cs;
                mov dwCS,eax;

                iretd;
            }
        }
        int main(int argc, char* argv[])
        {
            memset(iTSS,0,sizeof(iTSS));
            memset(ESP0,0,sizeof(ESP0));
            memset(ESP3,0,sizeof(ESP3));

            dwESP = 0;
            dwCS = 0;
            dwCR3 = 0;

            iTSS[1] = (DWORD)(ESP0+0x900);    // ESP
            iTSS[2] = 0x10;                    // SS0
            iTSS[8] = (DWORD)Call;            // EIP
            iTSS[14] = (DWORD)(ESP3+0x900); // ESP3
            iTSS[18] = 0x23;    // ES
            iTSS[19] = 0x08;    // CS
            iTSS[20] = 0x10;    // SS
            iTSS[21] = 0x23;    // DS
            iTSS[22] = 0x30;    // FS

            printf("iTSS:%x ESP3:%x ESP0:%x\n",iTSS,(ESP3+0x900),(ESP0+0x900));
            printf("input cr3:");
            scanf("%x",&dwCR3);
            iTSS[7] = dwCR3;        // cr3

            char buf[6] = {0,0,0,0,0x48,0};
            _asm{
                call fword ptr buf;
            }
            printf("ESP:%x CS:%x\n",dwESP,dwCS);
            return 0;
            return 0;
}

  2)查看TSS的内存地址,然后来修改任务门的偏移量(注意之前为函数地址,但任务门是一次性替换全部寄存器,因此函数地址在tss的eip中)。

    

     0x48偏移处构造,windbg指令 eq 8003f048 0000e943`2c680068

  3)使用 !process 0 0 找到对应的CR3(物理页处),然后输入进去。

    

   4)可以看到其直接使用了三环的esp(虽然我们权限是零环,但它并没有使用零环esp,而是直接替换目录中的esp)。

    

 

 6. 使用int3指令断下观察esp的实验(出现一个eflags标志位的坑)

    //

    #include "stdafx.h"
    #include "windows.h"

    DWORD iTSS[26];
    DWORD ESP0[0x1000];
    DWORD ESP3[0x1000];

    DWORD dwESP;
    DWORD dwCS;
    DWORD dwCR3;

    _declspec(naked) void Call(){
        _asm{
            int 3;

            mov dwESP,ESP;
            mov ax,cs;
            mov dwCS,eax;

            // reset the NT flag in eflags register
            pushfd;
            pop eax;
            or eax,0x4000;
            push eax;
            popfd;

            iretd;
        }
    }
    int main(int argc, char* argv[])
    {
        memset(iTSS,0,sizeof(iTSS));
        memset(ESP0,0,sizeof(ESP0));
        memset(ESP3,0,sizeof(ESP3));
        VirtualLock(iTSS),0x2000);
        VirtualLock(ESP0),0x2000);
        VirtualLock(ESP3),0x2000);
        dwESP = 0;
        dwCS = 0;
        dwCR3 = 0;

        iTSS[1] = (DWORD)(ESP0+0x900);    // ESP
        iTSS[2] = 0x10;                    // SS0
        iTSS[8] = (DWORD)Call;            // EIP
        iTSS[14] = (DWORD)(ESP3+0x900); // ESP3
        iTSS[18] = 0x23;    // ES
        iTSS[19] = 0x08;    // CS
        iTSS[20] = 0x10;    // SS
        iTSS[21] = 0x23;    // DS
        iTSS[22] = 0x30;    // FS

        printf("iTSS:%x ESP3:%x ESP0:%x\n",iTSS,(ESP3+0x900),(ESP0+0x900));
        printf("input cr3:");
        scanf("%x",&dwCR3);
        iTSS[7] = dwCR3;        // cr3

        char buf[6] = {0,0,0,0,0x48,0};
        _asm{
            call fword ptr buf;
        }
        printf("ESP:%x CS:%x\n",dwESP,dwCS);
        return 0;
        return 0;
    }

  

7. int 3 断下时,如果不恢复eflags寄存器,其就会卡死。
    因为当进行TSS跳转时,其会将老的TSS保存在新的TSS头部(上面我们看到),当我们使用iretd返回时,其不是像中断那样根据返回地址,而是根据TSS段选择子找旧的TSS段内存,然后将里面的寄存器全部加载进去。
    而INT 3 会清空 VM、NT、IF、TF四个位,其中NT表示嵌套任务段(nested task),如果清空,其就认为不存在任务段嵌套,直接像常规那样,根据返回地址返回,此时就会出错。
    因此就会存在下面一段代码来修改elfags寄存器中的NT位。
    // reset the NT flag in eflags register
    pushfd;
    pop eax;
    or eax,0x4000;
    push eax;
 popfd;

8. 任务门的作用
    

  当CPU出现双重错误,其就会通过任务门,调到08到中断去。

  任务门在IDT表中,触发同样适用 int 0x20;

9. 任务门实验

    //

    #include "stdafx.h"
    #include <stdlib.h>
    #include <windows.h>
    #include <memory.h>
    DWORD iTSS[26];
    DWORD ESP0[0x1000];
    DWORD ESP3[0x1000];

    DWORD dwESP;
    DWORD dwCS;
    DWORD dwCR3;

    _declspec(naked) void Call(){
        _asm{
            //int 3;

            mov dwESP,ESP;
            mov ax,cs;
            mov dwCS,eax;

            // reset the NT flag in eflags register
            /*
            pushfd;
            pop eax;
            or eax,0x4000;
            push eax;
            popfd;
            */
            iretd;
        }
    }
    int main(int argc, char* argv[])
    {
        memset(iTSS,0,sizeof(iTSS));
        memset(ESP0,0,sizeof(ESP0));
        memset(ESP3,0,sizeof(ESP3));
        VirtualLock(iTSS,28);
        VirtualLock(ESP0,0x1000);
        VirtualLock(ESP3,0x1000);
        dwESP = 0;
        dwCS = 0;
        dwCR3 = 0;

        iTSS[1] = (DWORD)(ESP0+0x900);    // ESP
        iTSS[2] = 0x10;                    // SS0
        iTSS[8] = (DWORD)Call;            // EIP
        iTSS[14] = (DWORD)(ESP3+0x900); // ESP3
        iTSS[18] = 0x23;    // ES
        iTSS[19] = 0x08;    // CS
        iTSS[20] = 0x10;    // SS
        iTSS[21] = 0x23;    // DS
        iTSS[22] = 0x30;    // FS

        printf("iTSS:%x ESP3:%x ESP0:%x\n",iTSS,(ESP3+0x900),(ESP0+0x900));
        printf("input cr3:");
        scanf("%x",&dwCR3);
        iTSS[7] = dwCR3;        // cr3

        char buf[6] = {0,0,0,0,0x48,0};
        _asm{
            int 0x20;
        }
        printf("ESP:%x CS:%x\n",dwESP,dwCS);
        return 0;
        return 0;
    }

    windbg 修改
    其根据任务门属性来进行如下修改:
    eq 8003f500  0000e500`00480000 (任务门,通过int 0x20触发,找到48选择子处)
    eq 8003f048 0000e943`2c680068 (TSS内存地址构造TSS段描述符)
 填写进程的CR3地址,之后就可以看见运行成功。

原文地址:https://www.cnblogs.com/onetrainee/p/12436412.html

时间: 2024-10-29 14:29:55

任务段与任务门的相关文章

【OpenCV入门教程之一】 OpenCV 2.4.8 +VS2010的开发环境配置

目录(?)[-] 因为读研期间的研究方向是图像处理所以浅墨这段时间闭门研究了很多OpenCV和图像处理相关的知识与内容眼看自己积累到一定的程度了于是决定开始开设这个OpenCV系列专栏总结自己所学也分享知识给大家 还是先放出待会儿的测试用图 下载和安装OpenCV SDK sources里面是源代码想查看完整的源代码需要用cmake来解包如何解包大家百度一下就可以或者下次浅墨来专门讲一讲这里就先不多说了 配置环境变量 工程包含include目录的配置 工程库lib目录的配置 链接库的配置 在Wi

win10系统调用架构分析

1.  操作系统模型 大多数操作系统中,都会把应用程序和内核代码分离运行在不同的模式下.内核模式访问系统数据和硬件,应用程序运行在没有特权的模式下(用户模式),只能使用有限的API,且不能直接访问硬件.当用户模式调用系统服务时,CPU执行一个特殊的指令以切换到内核模式(Ring0),当系统服务调用完成时,操作系统切换回用户模式(Ring3). Windows与大多数UNIX系统类似,驱动程序代码共享内核模式的内存空间,意味着任何系统组件或驱动程序都可能访问其他系统组件的数据.但是,Windows

opencv环境变量配置

本文章由@浅墨_毛星云 出品  原文文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 知乎:http://www.zhihu.com/people/mao-xing-yun 写作当前博文时配套使用的OpenCV版本: 2.4.8.2.4.9.3.0   ( 2014年4月28更新Ope

(转) 安装OpenCV:OpenCV 2.4.8或OpenCV 2.4.9 +VS 开发环境配置

因为读研期间的研究方向是图像处理,所以浅墨这段时间闭门研究了很多OpenCV和图像处理相关的知识与内容.眼看自己积累到一定的程度了,于是决定开始开设这个OpenCV系列专栏,总结自己所学,也分享知识给大家. 好了,这篇文章作为OpenCV的启程篇,自然少不了先系统地介绍OpenCV开发环境的配置. 浅墨前后经历过OpenCV 2.4.6,OpenCV 2.4.7,OpenCV 2.4.8这三个版本的配置,有时候还要涉及到三个版本之间的转换,所以还是对OpenCV的配置有一定的理解的,希望自己的一

(转)OpenCV学习:OpenCV2.4.8+VS2010开发环境配置

初学OpenCV,关于OpenCV的环境配置,在网上搜索了很多方法,最后自己终于搞定了,纪念一下... 配置的过程深受一篇博文的影响,该博文讲述的十分清楚,特此转载过来,和大家分享!!!!! 本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅墨)    邮箱: [email protected] 写作当前博文时配套使用OpenCV版本:2.4.

非常好!!!【从头开始写操作系统系列】实现一个-GDT(1)【转】

转自:http://blog.csdn.net/luoyhang003/article/details/47338019 权声明:本文为博主原创文章,未经博主允许不得转载.(文章来源:http://blog.luoyuanhang.com) 目录(?)[-] 介绍 GDT GDT 是什么 描述符结构 在这篇文章中我们完成了以下内容: 介绍 GDT 介绍段描述符 实现一个段描述符 介绍 GDT GDT 是什么? GDT(Global Descriptor Table)是一种数据结构,用来提供段式存

[转载]Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取

原文地址:点击打开链接 为什么要写这篇文章 1.      因为最近在学习<软件调试>这本书,看到书中的某个调试历程中讲了Windows的系统调用的实现机制,其中讲到了从Ring3跳转到Ring0之后直接进入了KiFastCallEntry这个函数. 2.      碰巧前天又在网上看到了一篇老文章介绍xxx安全卫士对Windows系统调用的Hook,主要就是Hook到这个函数 3.      刚刚做完毕业设计,对使用中断来实现系统调用的方式记忆犹新. 以上原因导致我最近眼前总是出现系统调用这

分段机制(个人理解)

分段机制可用于实现多种系统设计.这些设计范围从使用分段机制的最小功能来保护程序的平坦模型,到使用分段机制创建一个可同时可靠地运行多个程序(或任务)的具有稳固操作环境的多段模型. 多段模型能够利用分段机制全部功能提供由硬件增强的代码,数据结构,程序和任务的保护措施.通常,每个程序(或任务)都是用自己的段描述符以及自己的段.对程序来说段能够完全是私有的,或者是程序之间共享的.对所有段以及系统上运行程序各自执行环境的访问都由硬件控制. 访问检查不仅能够用来保护对段界限以外地址的引用,而且也能用来在某些

安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 知乎:http://www.zhihu.com/people/mao-xing-yun 写作当前博文时配套使用的OpenCV版本: 2.4.8.2.4.9.3.0   ( 2014