12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 141|回复: 0

9.任务段(Task-State-Segment)

[复制链接]
发表于 2022-1-28 20:31:18 | 显示全部楼层 |阅读模式
[ 本帖最后由 woshikele 于 2021-10-6 18:40 编辑 ]\n\n章节介绍

  • 参考体系段形貌符介绍,.
  • TR段寄存器的结构,读写,切换时机.
  • 任务段存储于GDT表中,TR段寄存器指向的任务段形貌符中的Base定位了TSS在内存中的起始地址.
  • TSS的结构,大小,用途.
  • 不同指令实行任务段的影响.(详情参考代码示例)
0.TR寄存器

intel白皮书解释如下:
The task register holds the 16-bit segment selector, base address (32 bits in protected mode; 64 bits in IA-32e mode), segment limit, and descriptor attributes for the TSS of the current task. The selector references the TSS descriptor in the GDT. The base address specifies the linear address of byte 0 of the TSS;
The LTR and STR instructions load and store the segment selector part of the task register, respectively. When the LTR instruction loads a segment selector in the task register, the base address, limit, and descriptor attributes from the TSS descriptor are automatically loaded into the task register. On power up or reset of the processor, the base address is set to the default value of 0 and the limit is set to 0FFFFH.
When a task switch occurs, the task register is automatically loaded with the segment selector and descriptor for the TSS for the new task. The contents of the task register are not automatically saved prior to writing the new TSS information into the register.
TR寄存器的读写:
//1.将TSS段形貌符加载到TR寄存器//指令:LTR//用LTR指令去装载的话 仅仅是改变TR寄存器的值(96位) 并没有真正改变TSS  LTR指令只能在RING0使用 加载后TSS段形貌符会状态位会发生改变//2.读TR寄存器//指令:STR//说明:假如用STR去读的话,只读了TR的16位 也就是选择子#include #include int main(){  WORD wTR = 0;  __asm  {    str wTR  }  printf("TR = %04x \n",wTR);  system("Pause");  return 0;}1.任务段形貌符


在调用门,中断门,陷阱门中一旦出现权限切换,会有新的ESP SS,来自于任务段(TASK-STATE SEGMENT) TR寄存器指向当前TSS.
TSS.BASE指向TSS在内存中的基址

  • 高4字节 31-24(BIT) BASE 31:24
  • 高4字节 07-00(BIT) BASE 23:16
  • 低4字节 31-16(BIT) BASE 15:00
TSS.LENGTH指向TSS在内存中的大小

  • 高4字节 19-16(BIT) LIMIT 19:16
  • 低4字节 15-00(BIT) LIMIT 15:00
  • 高4字节 23(BIT)    G == 0(BYTE)  G == 1(PAGE)
TSS.ATTRIBUTE

  • 高4字节 15-12(BIT) P == 1 DPL == 00/11  S == 0
  • 高4字节 11-08(BIT) TYPE == 1001(空闲) 1011(占用)
2.TSS


TR寄存器指向的任务段形貌符的BASE为TSS的基址

TSS是一块内存,大小104字节.通过TSS可以同时更换“一堆”寄存器,包括通用寄存器和段寄存器等.
Windows只使用了TSS的SS0和ESP0,用于权限切换.
TSS这个东西是Intel设计出来做任务切换的,windows和linux都没有使用任务,而是本身实现了线程。在windows中,TSS唯一的作用就是权限切换时要用到SS0和ESP0,又或者这样理解,TSS就是用来一次性更换一堆寄存器的.
查看默认TR指向的数据:

3.任务段实行流程

1.通过TR寄存器段选择子去GDT表中查找TSS段形貌符
2.通过TSS段形貌符BASE定位TSS内存地址
3.切换任务通过TSS内存数据内寄存器一次性切换

  • call far 实行会记载 PTL 且 NT标记位 = 1 返回时通过当前TSS表previous task link加载
  • jmp  far 实行不记载 PTL 且 NT标记位 = 0 返回时需提前备份TSS数据 通过 jmp far 返回
  • NT位影响IRETD指令 NT == 1 通过切换任务返回  NT == 0 通过堆栈返回
PS:WIN7 X86 通过 CALLFAR JMPFAR TSS内存都均为保存CR3数据需要我们自行备份否则蓝屏或C05  
4.任务段示例

4.1 CALL FAR实行任务段

#include #include //TSS结构体struct _KiIoAccessMap{    UCHAR DirectionMap[32];                                                 //0x0    UCHAR IoMap[8196];                                                      //0x20};typedef struct _KTSS{    USHORT Backlink;                                                        //0x0    USHORT Reserved0;                                                       //0x2    ULONG Esp0;                                                             //0x4    USHORT Ss0;                                                             //0x8    USHORT Reserved1;                                                       //0xa    ULONG NotUsed1[4];                                                      //0xc    ULONG CR3;                                                              //0x1c    ULONG Eip;                                                              //0x20    ULONG EFlags;                                                           //0x24    ULONG Eax;                                                              //0x28    ULONG Ecx;                                                              //0x2c    ULONG Edx;                                                              //0x30    ULONG Ebx;                                                              //0x34    ULONG Esp;                                                              //0x38    ULONG Ebp;                                                              //0x3c    ULONG Esi;                                                              //0x40    ULONG Edi;                                                              //0x44    USHORT Es;                                                              //0x48    USHORT Reserved2;                                                       //0x4a    USHORT Cs;                                                              //0x4c    USHORT Reserved3;                                                       //0x4e    USHORT Ss;                                                              //0x50    USHORT Reserved4;                                                       //0x52    USHORT Ds;                                                              //0x54    USHORT Reserved5;                                                       //0x56    USHORT Fs;                                                              //0x58    USHORT Reserved6;                                                       //0x5a    USHORT Gs;                                                              //0x5c    USHORT Reserved7;                                                       //0x5e    USHORT LDT;                                                             //0x60    USHORT Reserved8;                                                       //0x62    USHORT Flags;                                                           //0x64    USHORT IoMapBase;                                                       //0x66    struct _KiIoAccessMap IoMaps[1];                                        //0x68}TSS;TSS tss = {0};DWORD g_dwTR = 0;DWORD g_dwCr3 = 0;CHAR ESP0STACK[0x100] = {0};_declspec(naked) VOID CALLTASK(){  __asm  {    //提升堆栈 修复CR3 存储暂时数据提供空间    sub esp, 0x10    //获取GDT表数据    sgdt [esp]    //获取GDT.Base    mov eax, [esp + 0x2]    //获取默认任务段形貌符    add eax, g_dwTR    lea edx, [esp + 0x8]    //获取默认任务段形貌符低4字节    mov ecx, [eax]    //LO    //获取默认任务段形貌符高4字节    mov eax, [eax + 0x4]//HI    //获取默认TSS 31:24    mov ebx, eax    shr ebx, 24    mov byte ptr [edx + 3], bl    //获取默认TSS 23:16    mov ebx, eax    and ebx, 0xFF    mov byte ptr [edx + 2], bl    //获取默认TSS 15:00    mov ebx, ecx    shr ebx, 16    mov word ptr [edx], bx    //修复CR3    mov eax, [esp + 0x8]    mov ecx, [g_dwCr3]    mov [eax + 0x1C], ecx    add esp, 0x10    //call指令实行任务切换会使EFLAG.NT标记位置1(IRETD指令通过任务切换返回)    iretd  }}int main(){        //构建段形貌符XX00E9XX`XXXX0068        //G = 0        //P = 1        //DPL = 11        //S = 0        //TYPE = 1001        printf("%02x00e9%02x`%04x0068  \n",(DWORD)&tss >> 24,((DWORD)&tss >> 16) & 0xFF,LOWORD(&tss));        printf("TSSADDR [0x%08x]  \n",&tss);        system("Pause");        //Windbg 输入指令!process 0 0 获取自身进程CR3        printf("INPUT CR3: ");        scanf("%x",&g_dwCr3);        //构建ESP0        memset(ESP0STACK,0,0x100);        //构建TSS        tss.CR3 = g_dwCr3;        tss.Eip = (ULONG)CALLTASK;          tss.Esp = (ULONG)ESP0STACK + 0x100;        tss.Es = 0x23;        tss.Cs = 0x8;        tss.Ss = 0x10;        tss.Ds = 0x23;        tss.Fs = 0x30;        tss.IoMapBase = 0x20ac;        //TR        __asm        {                str [g_dwTR]        }        CHAR calldata[6] = {0,0,0,0,0x48,0};        __asm        {                call fword ptr [calldata]        }        system("Pause");        return 0;}实行任务切换前数据

进入切换任务时查看此时数据



4.2 JMP FAR实行任务段

#include #include //TSS结构体struct _KiIoAccessMap{    UCHAR DirectionMap[32];                                                 //0x0    UCHAR IoMap[8196];                                                      //0x20};typedef struct _KTSS{    USHORT Backlink;                                                        //0x0    USHORT Reserved0;                                                       //0x2    ULONG Esp0;                                                             //0x4    USHORT Ss0;                                                             //0x8    USHORT Reserved1;                                                       //0xa    ULONG NotUsed1[4];                                                      //0xc    ULONG CR3;                                                              //0x1c    ULONG Eip;                                                              //0x20    ULONG EFlags;                                                           //0x24    ULONG Eax;                                                              //0x28    ULONG Ecx;                                                              //0x2c    ULONG Edx;                                                              //0x30    ULONG Ebx;                                                              //0x34    ULONG Esp;                                                              //0x38    ULONG Ebp;                                                              //0x3c    ULONG Esi;                                                              //0x40    ULONG Edi;                                                              //0x44    USHORT Es;                                                              //0x48    USHORT Reserved2;                                                       //0x4a    USHORT Cs;                                                              //0x4c    USHORT Reserved3;                                                       //0x4e    USHORT Ss;                                                              //0x50    USHORT Reserved4;                                                       //0x52    USHORT Ds;                                                              //0x54    USHORT Reserved5;                                                       //0x56    USHORT Fs;                                                              //0x58    USHORT Reserved6;                                                       //0x5a    USHORT Gs;                                                              //0x5c    USHORT Reserved7;                                                       //0x5e    USHORT LDT;                                                             //0x60    USHORT Reserved8;                                                       //0x62    USHORT Flags;                                                           //0x64    USHORT IoMapBase;                                                       //0x66    struct _KiIoAccessMap IoMaps[1];                                        //0x68}TSS;TSS tss = {0};DWORD g_dwTR = 0;DWORD g_dwCr3 = 0;CHAR JMPDATA[6] = {0};CHAR ESP0STACK[0x100] = {0};_declspec(naked) VOID CALLTASK(){  __asm  {    //提升堆栈 修复CR3 存储暂时数据提供空间    sub esp, 0x10    //获取GDT表数据    sgdt [esp]    //获取GDT.Base    mov eax, [esp + 0x2]    //获取默认任务段形貌符    add eax, g_dwTR    lea edx, [esp + 0x8]    //获取默认任务段形貌符低4字节    mov ecx, [eax]    //LO    //获取默认任务段形貌符高4字节    mov eax, [eax + 0x4]//HI    //获取默认TSS 31:24    mov ebx, eax    shr ebx, 24    mov byte ptr [edx + 3], bl    //获取默认TSS 23:16    mov ebx, eax    and ebx, 0xFF    mov byte ptr [edx + 2], bl    //获取默认TSS 15:00    mov ebx, ecx    shr ebx, 16    mov word ptr [edx], bx    //修复CR3    mov eax, [esp + 0x8]    mov ecx, [g_dwCr3]    mov [eax + 0x1C], ecx    add esp, 0x10    //jmp far实行任务段NT标记位 = 0 不能使用iretd返回    jmp fword ptr [JMPDATA]  }}int main(){  //构建段形貌符XX00E9XX`XXXX0068  //G = 0  //P = 1  //DPL = 11  //S = 0  //TYPE = 1001  printf("%02x00e9%02x`%04x0068  \n",(DWORD)&tss >> 24,((DWORD)&tss >> 16) & 0xFF,LOWORD(&tss));  printf("TSSADDR [0x%08x]  \n",&tss);  system("Pause");  //Windbg 输入指令!process 0 0 获取自身进程CR3  printf("INPUT CR3: ");  scanf("%x",&g_dwCr3);  //构建ESP0  memset(ESP0STACK,0,0x100);  //构建TSS  tss.CR3 = g_dwCr3;  tss.Eip = (ULONG)CALLTASK;    tss.Esp = (ULONG)ESP0STACK + 0x100;  tss.Es = 0x23;  tss.Cs = 0x8;  tss.Ss = 0x10;  tss.Ds = 0x23;  tss.Fs = 0x30;  tss.IoMapBase = 0x20ac;  //TR  __asm  {    str [g_dwTR]  }  *(LPWORD)&JMPDATA[4] = g_dwTR;  CHAR calldata[6] = {0,0,0,0,0x48,0};  __asm  {    jmp fword ptr [calldata]  }  system("Pause");  return 0;}进入切换任务时查看此时数据



来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-3-29 23:28 , Processed in 0.140625 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表