目录
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;
}