zoukankan      html  css  js  c++  java
  • Windows内核 TSS任务段

    TSS不是寄存器,就是一段内存 共有104个字节

     TSS包括当前执行任务的重要信息(如所有的通用寄存器,段寄存器,标志寄存器,CR3等)

    TSS作用

    TSS的意义就在于可以同时换掉“一堆”寄存器,实现任务的切换。

    任务是对于CPU而言的,对于操作系统而言则为线程,因为每个进程都至少有一个线程,进程是空间实体,真正执行代码的是线程。

    CPU如何寻找TSS

    TR段寄存器

    既然为段寄存器,则肯定有相对应的段描述符进行加载,即TR段寄存器的段描述符在GDT(全局描述符表)中。

    这里总结三个概念

    TSS描述符  TR寄存器  GDT

    TR寄存器中的Base指向TSS在内存中的位置,Limit表示TSS的大小

    TSS段描述符

    如果Type 为 1001  (9)的时候说明这个段描述符没有加载到TR寄存器中

    如果Type 为 1011  (B)的时候说明这个段描述符加载到TR寄存器中

    TR寄存器读写

    将TSS段描述符加载到TR寄存器当中

    LTR  

    用LTR指令去装载的话,仅仅是改变TR寄存器的值,而实际指向的TSS并没有改变

    LTR只能在0环进行使用,即只能在系统层使用

    加载后TSS段描述符会状态位发生改变

    读TR寄存器

    STR

    用STR去读的话,只读TR的16位,即选择子部分

    6.修改TR寄存器:

    用JMP去访问一个代码段时,改变的是CS和EIP

    JMP 0x48:0x123456 如果0x48是代码段,则CS->0x48  EIP->0x123456

    JMP 0x48:0x123456 如果0x48是TSS段描述符,则先修改TR寄存器,再用TR.Base

    指向的TSS中的值去修改其他寄存器中的值

    实验思路

    • 编写测试入口函数
    • 构造TSS
    • 设计TSS段描述符并安装

    一、构造TSS:

     

    复制代码
    typedef struct TSS {
        DWORD link; // 保存前一个 TSS 段选择子,使用 call 指令切换寄存器的时候由CPU填写。
        // 这 6 个值是固定不变的,用于提权,CPU 切换栈的时候用
        DWORD esp0; // 保存 0 环栈指针
        DWORD ss0;  // 保存 0 环栈段选择子
        DWORD esp1; // 保存 1 环栈指针
        DWORD ss1;  // 保存 1 环栈段选择子
        DWORD esp2; // 保存 2 环栈指针
        DWORD ss2;  // 保存 2 环栈段选择子
        // 下面这些都是用来做切换寄存器值用的,切换寄存器的时候由CPU自动填写。
        DWORD cr3; 
        DWORD eip;  
        DWORD eflags;
        DWORD eax;
        DWORD ecx;
        DWORD edx;
        DWORD ebx;
        DWORD esp;
        DWORD ebp;
        DWORD esi;
        DWORD edi;
        DWORD es;
        DWORD cs;
        DWORD ss;
        DWORD ds;
        DWORD fs;
        DWORD gs;
        DWORD ldt;
        // 这个暂时忽略
        DWORD io_map;
    } TSS;
    复制代码

     

    复制代码
    char st[10] = {0};   //定义一个堆栈切换的
    TSS tss = {// tss的地址根据执行代码自己组合
        0x00000000,//link
        (DWORD)st,//esp0
        0x00000010,//ss0
        0x00000000,//esp1
        0x00000000,//ss1
        0x00000000,//esp2
        0x00000000,//ss2
        0x00000000,//cr3
        0x0040fad0,//eip   必填项,不然执行完后cpu不知道回来从哪开始执行
        0x00000000,//eflags
        0x00000000,//eax
        0x00000000,//ecx
        0x00000000,//edx
        0x00000000,//ebx
        (DWORD)st,//esp    切换后堆栈在哪分配
        0x00000000,//ebp
        0x00000000,//esi
        0x00000000,//edi
        0x00000023,//es  
        0x00000008,//cs  
        0x00000010,//ss
        0x00000023,//ds
        0x00000030,//fs
        0x00000000,//gs
        0x00000000,//ldt
        0x20ac0000  //IO权限位图
    };
    
    复制代码

    二、 准备TSS段描述符:

    0040e900~7b400068  //加载的地址在你自己的VC6中看!

    三、写入准备好的TSS段描述符到GDT空白位置

    1: kd> r gdtr
    gdtr=fffff8800470b4c0
    1: kd> dq fffff8800470b4c0
    fffff880`0470b4c0 00000000`00000000 00000000`00000000
    fffff880`0470b4d0 00209b00`00000000 00cf9300`0000ffff
    fffff880`0470b4e0 00cffb00`0000ffff 00cff300`0000ffff
    fffff880`0470b4f0 0020fb00`00000000 00000000`00000000
    fffff880`0470b500 04008b70`4ec00067 00000000`fffff880
    fffff880`0470b510 ff40f3f9`e0007c00 00000000`00000000
    fffff880`0470b520 00cf9a00`0000ffff 00000000`00000000
    fffff880`0470b530 00000000`00000000 00000000`00000000
    1: kd> eq fffff8800470b4f8 0040e9007b400068
    1: kd> dq fffff8800470b4c0
    fffff880`0470b4c0 00000000`00000000 00000000`00000000
    fffff880`0470b4d0 00209b00`00000000 00cf9300`0000ffff
    fffff880`0470b4e0 00cffb00`0000ffff 00cff300`0000ffff
    fffff880`0470b4f0 0020fb00`00000000 0040e900`7b400068
    fffff880`0470b500 04008b70`4ec00067 00000000`fffff880
    fffff880`0470b510 ff40f3f9`e0007c00 00000000`00000000
    fffff880`0470b520 00cf9a00`0000ffff 00000000`00000000
    fffff880`0470b530 00000000`00000000 00000000`00000000

     
       

    四.修改TR寄存器

    CALL FAR或者JMP FAR 

    复制代码
    char buff[6];
    *(DWORD*)&buff[0]= 0x12345678;
    *(DWORD*)&buff[4]= 0xC0;
    
    __asm
    {
      call fword ptd[buff]      
    }
    复制代码
  • 相关阅读:
    探索c#之Async、Await剖析
    探索C#之布隆过滤器(Bloom filter)
    探索C#之虚拟桶分片
    刷新本地的DNS缓存数据
    php取整函数ceil,floor,round,intval函数的区别
    这样顶级人生规划 ,想不成功都难
    全篇干货,10分钟带你读透《参与感》
    iOS审核秘籍】提审资源检查大法
    php如何遍历多维的stdClass Object 对象,php的转换成数组的函数只能转换外面一丛数组
    RDS MySQL 连接数满情况的处理
  • 原文地址:https://www.cnblogs.com/Virus-Faker/p/12698551.html
Copyright © 2011-2022 走看看