其他分享
首页 > 其他分享> > 10.任务门(Task Gate)

10.任务门(Task Gate)

作者:互联网

目录

0.任务门描述符

1.任务门执行流程

2.任务门权限检查

3.任务门示例

<1>.任务门

<2>.任务门详细版本

<3>.任务门进R1

<4>.任务门进R1详细版本 


0.任务门描述符

高4字节 15-12(BIT) P == 1(有效段描述符)  DPL == 11/00(段描述符权限 0/3 Windows未使用1 2环)  S == 0(系统段描述符)
高4字节 11-08(BIT) TYPE == 0101(Task Gate)

低4字节 31-16(BIT) TSS SELECOTR

1.任务门执行流程

1.INT X(IDT[X] 任务门描述符在IDT表中的索引)
2.通过任务门描述符TSS段选择子去GDT表中查找TSS段描述符
3.通过TSS段描述符BASE定位TSS基址
4.通过TSS数据切换寄存器 EIP 等等
5.IRETD返回

2.任务门权限检查

访问任务门的时候,任务门选择子指向的TSS段描述符DPL被忽略 检查的是这个任务门的DPL

1.使用Call或者Jump指令访问GDT表中的TSS段描述符
2.使用Call或者Jump指令访问GDT表中的TSS段描述符
3.INT指令访问IDT表中的任务门
4.当Eflags寄存器里的NT位为1的时候执行iretd指令

3.任务门示例

<1>.任务门

#include <stdio.h>
#include <windows.h>


//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 //此时EDX内存储默认TSS基址

    //修复CR3
    mov eax, [esp + 0x8]
    mov ecx, [g_dwCr3]
    mov [eax + 0x1C], ecx

    add esp, 0x10

    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));

  //构建任务门描述符0000E500`00480000
  //P = 1
  //DPL = 11
  //S = 0
  //TYPE = 0101
  //SELECTOR = 构建任务段对应段选择子
  printf("0000e500`00480000 \n");  
  printf("TSSADDR [0x%08x]  \n",&tss);
  system("Pause");

  //Windbg 输入指令!process 0 0 获取自身进程CR3
  //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]
  }

  //TASK GATE
  __asm
  {
    INT 0x20
  }

  system("Pause");
  
  return 0;
}

 

<2>.任务门详细版本

//eq 80b99048 0000E91e`00000068
//eq 80b99500 0000e500`00480000

#include <stdio.h>
#include <windows.h>

//存储GDT表数据
DWORD dwGDTAddr = 0;
DWORD dwOlaTssAddr = 0;

//存储TSS数据
CHAR ESP0[0x100] = {0xCC};
WORD wTR = 0;
DWORD dwCr3 = 0;
LPDWORD lpTSS = NULL;

//存储EFLAG执行前后数据
DWORD dwOldEFLAG = 0;
DWORD dwNewEFLAG = 0;

//存储构造段描述符数据
DWORD dwNewTSSH = 0;
DWORD dwNewTSSL = 0;
DWORD dwOldTSSH = 0;
DWORD dwOldTSSL = 0;

//存储切换任务前后TSS数据
DWORD dwOldPTL = 0;
DWORD dwOldESP0 = 0;
DWORD dwOldSS0 = 0;
DWORD dwOldESP1 = 0;
DWORD dwOldSS1 = 0;
DWORD dwOldESP2 = 0;
DWORD dwOldSS2 = 0;
DWORD dwOldCR3 = 0;
DWORD dwOldEIP = 0;
DWORD dwOldEFL = 0;
DWORD dwOldEAX = 0;
DWORD dwOldECX = 0;
DWORD dwOldEDX = 0;
DWORD dwOldEBX = 0;
DWORD dwOldESP = 0;
DWORD dwOldEBP = 0;
DWORD dwOldESI = 0;
DWORD dwOldEDI = 0;
DWORD dwOldES = 0;
DWORD dwOldCS = 0;
DWORD dwOldSS = 0;
DWORD dwOldDS = 0;
DWORD dwOldFS = 0;
DWORD dwOldGS = 0;
DWORD dwOldLDT = 0;
DWORD dwOldMAP = 0;

//执行任务门裸函数
VOID _declspec(naked)Fun()
{
  __asm
  {
    //修复CR3
    
    //得到默认TR在GDT表中INDEX
    mov cx, wTR
    shr cx, 0x3

    //查找默认TSS描述符
    mov eax, dwGDTAddr
    lea eax, [eax + ecx * 8]

    //低位
    mov ecx, [eax]
    mov dwOldTSSL, ecx
    
    //高位
    mov eax, [eax + 4]
    mov dwOldTSSH, eax

    //查找默认TSS指向数据
    lea edx, dwOlaTssAddr
    
    //31-24
    mov eax, dwOldTSSH
    shr eax, 24
    mov byte ptr [edx + 3], al

    //23-16
    mov eax, dwOldTSSH
    and eax, 0xFF
    mov byte ptr [edx + 2], al

    //15-00
    mov eax, dwOldTSSL
    shr eax, 16
    mov word ptr [edx], ax

    //填充CR3
    mov eax, dwOlaTssAddr
    mov ecx, dwCr3
    mov [eax + 0x1C], ecx

    //获取调用前数据
    mov eax, dwOlaTssAddr

    mov ecx, [eax]
    mov dwOldPTL, ecx

    mov ecx, [eax + 0x4]
    mov dwOldESP0, ecx

    mov ecx, [eax + 0x8]
    mov dwOldSS0, ecx

    mov ecx, [eax + 0xC]
    mov dwOldESP1, ecx

    mov ecx, [eax + 0x10]
    mov dwOldSS1, ecx

    mov ecx, [eax + 0x14]
    mov dwOldESP2, ecx
  
    mov ecx, [eax + 0x18]
    mov dwOldSS2, ecx

    mov ecx, [eax + 0x1C]
    mov dwOldCR3, ecx

    mov ecx, [eax + 0x20]
    mov dwOldEIP, ecx

    mov ecx, [eax + 0x24]
    mov dwOldEFL, ecx

    mov ecx, [eax + 0x28]
    mov dwOldEAX, ecx

    mov ecx, [eax + 0x2C]
    mov dwOldECX, ecx

    mov ecx, [eax + 0x30]
    mov dwOldEDX, ecx

    mov ecx, [eax + 0x34]
    mov dwOldEBX, ecx

    mov ecx, [eax + 0x38]
    mov dwOldESP, ecx

    mov ecx, [eax + 0x3C]
    mov dwOldEBP, ecx

    mov ecx, [eax + 0x40]
    mov dwOldESI, ecx

    mov ecx, [eax + 0x44]
    mov dwOldEDI, ecx

    mov ecx, [eax + 0x48]
    mov dwOldES, ecx

    mov ecx, [eax + 0x4C]
    mov dwOldCS, ecx

    mov ecx, [eax + 0x50]
    mov dwOldSS, ecx

    mov ecx, [eax + 0x54]
    mov dwOldDS, ecx

    mov ecx, [eax + 0x58]
    mov dwOldFS, ecx
    
    mov ecx, [eax + 0x5C]
    mov dwOldGS, ecx

    mov ecx, [eax + 0x60]
    mov dwOldLDT, ecx

    mov ecx, [eax + 0x64]
    mov dwOldMAP, ecx


    //获取EFLAG
    pushfd
    pop dwNewEFLAG

    //读取段描述符数据
    mov eax, 0x80b99048
    mov eax, [eax]
    mov dwNewTSSL, eax

    mov eax, 0x80b9904C
    mov eax, [eax]
    mov dwNewTSSH, eax

    iretd
  }
}


int main()
{
  //申请存储TSS SPACE
  lpTSS = (LPDWORD)VirtualAlloc((LPVOID)0x001e0000,0x68,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
  if (!lpTSS)
  {
    MessageBox(NULL,"VirtualAlloc Fail !","ERROR",MB_OK|MB_ICONERROR);
    exit(0);
  }
  
  printf("TSS ADDR = %08x \n",(DWORD)lpTSS);
  printf("请输入进程CR3 : ");
  scanf("%x",&dwCr3);

  lpTSS[0] = 0x00000000;//Previous Task Link
  lpTSS[1] = 0x00000000;//ESP0
  lpTSS[2] = 0x00000000;//SS0
  lpTSS[3] = 0x00000000;//ESP1
  lpTSS[4] = 0x00000000;//SS1
  lpTSS[5] = 0x00000000;//ESP2 
  lpTSS[6] = 0x00000000;//SS2
  lpTSS[7] = dwCr3;//CR3 (PDBR)
  lpTSS[8] = (DWORD)Fun;//EIP
  lpTSS[9] = 0x00000000;//EFLAGS
  lpTSS[10] = 0x00000000;//EAX
  lpTSS[11] = 0x00000000;//ECX
  lpTSS[12] = 0x00000000;//EDX
  lpTSS[13] = 0x00000000;//EBX
  lpTSS[14] = (DWORD)ESP0 + 0x100;//ESP
  lpTSS[15] = 0x00000000;//EBP
  lpTSS[16] = 0x00000000;//ESI
  lpTSS[17] = 0x00000000;//EDI
  lpTSS[18] = 0x00000023;//ES R3 = 0023 R0 = 0023
  lpTSS[19] = 0x00000008;//CS R3 = 001B R0 = 0008
  lpTSS[20] = 0x00000010;//SS R3 = 0023 R0 = 0010
  lpTSS[21] = 0x00000023;//DS R3 = 0023 R0 = 0023
  lpTSS[22] = 0x00000030;//FS R3 = 003B R0 = 0030
  lpTSS[23] = 0x00000000;//GS
  lpTSS[24] = 0x00000000;//LDT Segment Selector
  lpTSS[25] = 0x20ac0000;//I/O Map Base Address

  //备份GDT TR EFLAG
  CHAR szBuf[6] = {0};
  __asm
  {
    SGDT szBuf
    STR wTR
    PUSHFD
    POP dwOldEFLAG
  }
  dwGDTAddr = *(LPDWORD)&szBuf[2];
  system("Pause");

  //执行任务门
  __asm
  {
    int 0x20
  }

  printf("\n");
  printf("Global Descriptor Table Base = %08x \n",dwGDTAddr);
  
  printf("\n");
  printf("Old TR = %04x \n",wTR);
  printf("Old TSS Addr = %08x \n", dwOlaTssAddr);
  
  printf("\n");
  printf("New TR = 0048 \n");
  printf("New TSS Addr = %08x \n", (DWORD)lpTSS);
  
  printf("\n");
  printf("Old EFLAG = %08x \n",dwOldEFLAG);
  printf("New EFLAG = %08x \n",dwNewEFLAG);
  
  printf("\n");
  printf("New TSS DescriptorH = %08x \n",dwNewTSSH);
  printf("New TSS DescriptorL = %08x \n",dwNewTSSL);
  printf("Old TSS DescriptorH = %08x \n",dwOldTSSH);
  printf("Old TSS DescriptorL = %08x \n",dwOldTSSL);
  
  printf("\n");
  printf("TSS -> PTL  Old  = %08x \n",dwOldPTL);
  printf("TSS -> ESP0 Old  = %08x \n",dwOldESP0);
  printf("TSS -> SS0  Old  = %08x \n",dwOldSS0);
  printf("TSS -> ESP1 Old  = %08x \n",dwOldESP1);
  printf("TSS -> SS1  Old  = %08x \n",dwOldSS1);
  printf("TSS -> ESP2 Old  = %08x \n",dwOldESP2);
  printf("TSS -> SS2  Old  = %08x \n",dwOldSS2);
  printf("TSS -> CR3  Old  = %08x \n",dwOldCR3);
  printf("TSS -> EIP  Old  = %08x \n",dwOldEIP);
  printf("TSS -> EFL  Old  = %08x \n",dwOldEFL);
  printf("TSS -> EAX  Old  = %08x \n",dwOldEAX);
  printf("TSS -> ECX  Old  = %08x \n",dwOldECX);
  printf("TSS -> EDX  Old  = %08x \n",dwOldEDX);
  printf("TSS -> EBX  Old  = %08x \n",dwOldEBX);
  printf("TSS -> ESP  Old  = %08x \n",dwOldESP);
  printf("TSS -> EBP  Old  = %08x \n",dwOldEBP);
  printf("TSS -> ESI  Old  = %08x \n",dwOldESI);
  printf("TSS -> EDI  Old  = %08x \n",dwOldEDI);
  printf("TSS -> ES   Old  = %08x \n",dwOldES);
  printf("TSS -> CS   Old  = %08x \n",dwOldCS);
  printf("TSS -> SS   Old  = %08x \n",dwOldSS);
  printf("TSS -> DS   Old  = %08x \n",dwOldDS);
  printf("TSS -> FS   Old  = %08x \n",dwOldFS);
  printf("TSS -> GS   Old  = %08x \n",dwOldGS);
  printf("TSS -> LDT  Old  = %08x \n",dwOldLDT);
  printf("TSS -> MAP  Old  = %08x \n",dwOldMAP);



  printf("\n");
  system("Pause");
  return 0;
}
 

<3>.任务门进R1

#include <stdio.h>
#include <windows.h>

//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 //此时EDX内存储默认TSS基址

    //修复CR3
    mov eax, [esp + 0x8]
    mov ecx, [g_dwCr3]
    mov [eax + 0x1C], ecx

    add esp, 0x10

    iretd
  }
}
  
int main()
{
  //构建任务段描述符
  //TSS 0000e941`69400068
  //构建任务门描述符
  //TASK GATE 0000e500`00480000
  //构建R1代码段描述符
  //R1 CS 00cfbb00`0000ffff
  //构建R1数据段描述符
  //R1 SS 00cfb300`0000ffff
  //R1 FS 00cfb300`0000ffff

  //TSS BASE
  printf("TSSADDR [0x%08x]  \n",&tss);
  system("Pause");

  //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 = 0x61;
  tss.Ss = 0x69;
  tss.Ds = 0x23;
  tss.Fs = 0x69;
  tss.IoMapBase = 0x20ac;

  //TR
  __asm
  {
    str [g_dwTR]
  }

  //TASK GATE
  __asm
  {
    INT 0x20
  }

  system("Pause");
  
  return 0;
}

<4>.任务门进R1详细版本 

//eq 80b99048 0000E91e`00000068 TSS
//eq 80b99500 0000e500`00480000 TASK
//eq 80b99060 00cfbb00`0000ffff CS
//eq 80b99068 00cfb300`0000ffff SS
//eq 80b99078 0040B300`00000FFF FS

#include <stdio.h>
#include <windows.h>

//存储GDT表数据
DWORD dwGDTAddr = 0;
DWORD dwOlaTssAddr = 0;

//存储TSS数据
CHAR ESP0[0x100] = {0xCC};
WORD wTR = 0;
DWORD dwCr3 = 0;
LPDWORD lpTSS = NULL;

//存储EFLAG执行前后数据
DWORD dwOldEFLAG = 0;
DWORD dwNewEFLAG = 0;

//存储构造段描述符数据
DWORD dwNewTSSH = 0;
DWORD dwNewTSSL = 0;
DWORD dwOldTSSH = 0;
DWORD dwOldTSSL = 0;

//存储切换任务前后TSS数据
DWORD dwOldPTL = 0;
DWORD dwOldESP0 = 0;
DWORD dwOldSS0 = 0;
DWORD dwOldESP1 = 0;
DWORD dwOldSS1 = 0;
DWORD dwOldESP2 = 0;
DWORD dwOldSS2 = 0;
DWORD dwOldCR3 = 0;
DWORD dwOldEIP = 0;
DWORD dwOldEFL = 0;
DWORD dwOldEAX = 0;
DWORD dwOldECX = 0;
DWORD dwOldEDX = 0;
DWORD dwOldEBX = 0;
DWORD dwOldESP = 0;
DWORD dwOldEBP = 0;
DWORD dwOldESI = 0;
DWORD dwOldEDI = 0;
DWORD dwOldES = 0;
DWORD dwOldCS = 0;
DWORD dwOldSS = 0;
DWORD dwOldDS = 0;
DWORD dwOldFS = 0;
DWORD dwOldGS = 0;
DWORD dwOldLDT = 0;
DWORD dwOldMAP = 0;

//执行任务门裸函数
VOID _declspec(naked)Fun()
{
  __asm
  {
    //修复CR3
    
    //得到默认TR在GDT表中INDEX
    mov cx, wTR
    shr cx, 0x3

    //查找默认TSS描述符
    mov eax, dwGDTAddr
    lea eax, [eax + ecx * 8]

    //低位
    mov ecx, [eax]
    mov dwOldTSSL, ecx
    
    //高位
    mov eax, [eax + 4]
    mov dwOldTSSH, eax

    //查找默认TSS指向数据
    lea edx, dwOlaTssAddr
    
    //31-24
    mov eax, dwOldTSSH
    shr eax, 24
    mov byte ptr [edx + 3], al

    //23-16
    mov eax, dwOldTSSH
    and eax, 0xFF
    mov byte ptr [edx + 2], al

    //15-00
    mov eax, dwOldTSSL
    shr eax, 16
    mov word ptr [edx], ax

    //填充CR3
    mov eax, dwOlaTssAddr
    mov ecx, dwCr3
    mov [eax + 0x1C], ecx

    //获取调用前数据
    mov eax, dwOlaTssAddr

    mov ecx, [eax]
    mov dwOldPTL, ecx

    mov ecx, [eax + 0x4]
    mov dwOldESP0, ecx

    mov ecx, [eax + 0x8]
    mov dwOldSS0, ecx

    mov ecx, [eax + 0xC]
    mov dwOldESP1, ecx

    mov ecx, [eax + 0x10]
    mov dwOldSS1, ecx

    mov ecx, [eax + 0x14]
    mov dwOldESP2, ecx
  
    mov ecx, [eax + 0x18]
    mov dwOldSS2, ecx

    mov ecx, [eax + 0x1C]
    mov dwOldCR3, ecx

    mov ecx, [eax + 0x20]
    mov dwOldEIP, ecx

    mov ecx, [eax + 0x24]
    mov dwOldEFL, ecx

    mov ecx, [eax + 0x28]
    mov dwOldEAX, ecx

    mov ecx, [eax + 0x2C]
    mov dwOldECX, ecx

    mov ecx, [eax + 0x30]
    mov dwOldEDX, ecx

    mov ecx, [eax + 0x34]
    mov dwOldEBX, ecx

    mov ecx, [eax + 0x38]
    mov dwOldESP, ecx

    mov ecx, [eax + 0x3C]
    mov dwOldEBP, ecx

    mov ecx, [eax + 0x40]
    mov dwOldESI, ecx

    mov ecx, [eax + 0x44]
    mov dwOldEDI, ecx

    mov ecx, [eax + 0x48]
    mov dwOldES, ecx

    mov ecx, [eax + 0x4C]
    mov dwOldCS, ecx

    mov ecx, [eax + 0x50]
    mov dwOldSS, ecx

    mov ecx, [eax + 0x54]
    mov dwOldDS, ecx

    mov ecx, [eax + 0x58]
    mov dwOldFS, ecx
    
    mov ecx, [eax + 0x5C]
    mov dwOldGS, ecx

    mov ecx, [eax + 0x60]
    mov dwOldLDT, ecx

    mov ecx, [eax + 0x64]
    mov dwOldMAP, ecx


    //获取EFLAG
    pushfd
    pop dwNewEFLAG

    //读取段描述符数据
    mov eax, 0x80b99048
    mov eax, [eax]
    mov dwNewTSSL, eax

    mov eax, 0x80b9904C
    mov eax, [eax]
    mov dwNewTSSH, eax

    iretd
  }
}


int main()
{
  //申请存储TSS SPACE
  lpTSS = (LPDWORD)VirtualAlloc((LPVOID)0x001e0000,0x68,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
  if (!lpTSS)
  {
    MessageBox(NULL,"VirtualAlloc Fail !","ERROR",MB_OK|MB_ICONERROR);
    exit(0);
  }
  
  printf("TSS ADDR = %08x \n",(DWORD)lpTSS);
  printf("请输入进程CR3 : ");
  scanf("%x",&dwCr3);

  lpTSS[0] = 0x00000000;//Previous Task Link
  lpTSS[1] = 0x00000000;//ESP0
  lpTSS[2] = 0x00000000;//SS0
  lpTSS[3] = 0x00000000;//ESP1
  lpTSS[4] = 0x00000000;//SS1
  lpTSS[5] = 0x00000000;//ESP2 
  lpTSS[6] = 0x00000000;//SS2
  lpTSS[7] = dwCr3;//CR3 (PDBR)
  lpTSS[8] = (DWORD)Fun;//EIP
  lpTSS[9] = 0x00000000;//EFLAGS
  lpTSS[10] = 0x00000000;//EAX
  lpTSS[11] = 0x00000000;//ECX
  lpTSS[12] = 0x00000000;//EDX
  lpTSS[13] = 0x00000000;//EBX
  lpTSS[14] = (DWORD)ESP0 + 0x100;//ESP
  lpTSS[15] = 0x00000000;//EBP
  lpTSS[16] = 0x00000000;//ESI
  lpTSS[17] = 0x00000000;//EDI
  lpTSS[18] = 0x00000023;//ES R3 = 0023 R0 = 0023
  lpTSS[19] = 0x00000061;//CS R3 = 001B R0 = 0008
  lpTSS[20] = 0x00000069;//SS R3 = 0023 R0 = 0010
  lpTSS[21] = 0x00000023;//DS R3 = 0023 R0 = 0023
  lpTSS[22] = 0x00000079;//FS R3 = 003B R0 = 0030
  lpTSS[23] = 0x00000000;//GS
  lpTSS[24] = 0x00000000;//LDT Segment Selector
  lpTSS[25] = 0x20ac0000;//I/O Map Base Address

  //备份GDT TR EFLAG
  CHAR szBuf[6] = {0};
  __asm
  {
    SGDT szBuf
    STR wTR
    PUSHFD
    POP dwOldEFLAG
  }
  dwGDTAddr = *(LPDWORD)&szBuf[2];
  system("Pause");

  //执行任务门
  __asm
  {
    int 0x20
  }

  printf("\n");
  printf("Global Descriptor Table Base = %08x \n",dwGDTAddr);
  
  printf("\n");
  printf("Old TR = %04x \n",wTR);
  printf("Old TSS Addr = %08x \n", dwOlaTssAddr);
  
  printf("\n");
  printf("New TR = 0048 \n");
  printf("New TSS Addr = %08x \n", (DWORD)lpTSS);
  
  printf("\n");
  printf("Old EFLAG = %08x \n",dwOldEFLAG);
  printf("New EFLAG = %08x \n",dwNewEFLAG);
  
  printf("\n");
  printf("New TSS DescriptorH = %08x \n",dwNewTSSH);
  printf("New TSS DescriptorL = %08x \n",dwNewTSSL);
  printf("Old TSS DescriptorH = %08x \n",dwOldTSSH);
  printf("Old TSS DescriptorL = %08x \n",dwOldTSSL);
  
  printf("\n");
  printf("TSS -> PTL  Old  = %08x \n",dwOldPTL);
  printf("TSS -> ESP0 Old  = %08x \n",dwOldESP0);
  printf("TSS -> SS0  Old  = %08x \n",dwOldSS0);
  printf("TSS -> ESP1 Old  = %08x \n",dwOldESP1);
  printf("TSS -> SS1  Old  = %08x \n",dwOldSS1);
  printf("TSS -> ESP2 Old  = %08x \n",dwOldESP2);
  printf("TSS -> SS2  Old  = %08x \n",dwOldSS2);
  printf("TSS -> CR3  Old  = %08x \n",dwOldCR3);
  printf("TSS -> EIP  Old  = %08x \n",dwOldEIP);
  printf("TSS -> EFL  Old  = %08x \n",dwOldEFL);
  printf("TSS -> EAX  Old  = %08x \n",dwOldEAX);
  printf("TSS -> ECX  Old  = %08x \n",dwOldECX);
  printf("TSS -> EDX  Old  = %08x \n",dwOldEDX);
  printf("TSS -> EBX  Old  = %08x \n",dwOldEBX);
  printf("TSS -> ESP  Old  = %08x \n",dwOldESP);
  printf("TSS -> EBP  Old  = %08x \n",dwOldEBP);
  printf("TSS -> ESI  Old  = %08x \n",dwOldESI);
  printf("TSS -> EDI  Old  = %08x \n",dwOldEDI);
  printf("TSS -> ES   Old  = %08x \n",dwOldES);
  printf("TSS -> CS   Old  = %08x \n",dwOldCS);
  printf("TSS -> SS   Old  = %08x \n",dwOldSS);
  printf("TSS -> DS   Old  = %08x \n",dwOldDS);
  printf("TSS -> FS   Old  = %08x \n",dwOldFS);
  printf("TSS -> GS   Old  = %08x \n",dwOldGS);
  printf("TSS -> LDT  Old  = %08x \n",dwOldLDT);
  printf("TSS -> MAP  Old  = %08x \n",dwOldMAP);



  printf("\n");
  system("Pause");
  return 0;
}
 

 

标签:10,Task,mov,DWORD,eax,printf,Gate,TSS,ecx
来源: https://blog.csdn.net/m0_46125480/article/details/120399591