首页
社区
课程
招聘
[原创]带你重新认识保护模式TSS任务段!
发表于: 2020-3-23 16:51 12355

[原创]带你重新认识保护模式TSS任务段!

2020-3-23 16:51
12355
疫情隔离期间闲着没事又重新探索了一下i386保护模式,主要是TSS任务段,之前一直云里雾里,背后的机制不是太明白。

先说使用TSS段的一些注意事项,大神请无视:

下图给出不同的任务切换方法对NT位,TSS描述符的B位(忙位)以及TSS任务链接域的影响:

最后附上一段在TSS任务切换不提权,切换到新任务后使用中断门提权的代码:
#include<stdio.h>
#include<Windows.h>
DWORD STACK[50] = { 0 };
DWORD TSS[]=
{
	0x00000000,//前一个TSS段选择子
	0x83f2ccb0,//esp0
	0x00000010,//ss0
	0x00000000,//esp1
	0x00000000,//ss1
	0x00000000,//esp2
	0x00000000,//ss2
	0x00000000,//CR3--TSS[7]
	0x00000000,//eip--TSS[8]
	0x00000002,//eflags
	0x11111111,//eax
	0x22222222,//ecx
	0x33333333,//edx
	0x44444444,//ebx
	(DWORD)(STACK+0x11),//esp
	0x00000000,//ebp
	0x55555555,//esi
	0x66666666,//edi
	0x00000023,//es
	0x0000001b,//cs
	0x00000023,//ss
	0x00000023,//ds
	0x0000003b,//fs
	0x00000000,//gs
	0x00000000,//ldt
	0x20ac0000,//iomap
};

void _declspec(naked) ring3()
{
	__asm
	{
		xor eax, eax;
		mov ax, fs;
		push eax;
		mov ax, cs;
		push eax;
		mov ax, ss;
		push eax;
		pushfd;
		mov eax, esp;
		push eax;
		int 34;
		mov bx, 0x1b;
		mov fs, bx;
		iretd;
	}
}

void _declspec(naked) ring0()
{
	__asm
	{
		pushfd;
		pop ecx;
		lea edi, dword ptr[STACK];
		mov dword ptr[edi], ecx;//efalgs

		mov eax, dword ptr[esp];
		mov dword ptr[edi + 0x8], eax;//eip

		mov eax, dword ptr[esp + 0x4];
		mov dword ptr[edi + 0xc], eax;//cs

		mov eax, dword ptr[esp + 0x8];
		mov dword ptr[edi + 0x10], eax;//eflags

		mov eax, dword ptr[esp + 0xc];
		mov dword ptr[edi + 0x14], eax;//esp

		mov eax, dword ptr[esp + 0x10];
		mov dword ptr[edi + 0x18], eax;//ss

		xor eax, eax;
		mov ax, cs;
		mov dword ptr[edi + 0x20], eax;
		mov ax, ss;
		mov dword ptr[edi + 0x24], eax;
		mov ax, fs;
		mov dword ptr[edi + 0x28], eax;

		mov bx, 0x30;
		mov fs, bx;
		mov eax, dword ptr fs : [0x40];
		mov edx, cr3;
		mov dword ptr[eax + 0x1c], edx;//存储CR3到原TSS中

		iretd;
	}
}
int main()
{
	memset(STACK, 0xcc, sizeof(DWORD) * 50);
	DWORD EIP = (DWORD)ring3;
	TSS[8] = EIP;
	printf("中断例程=%p\n", ring0);
	printf("请输入CR3:\n");
	scanf("%x", &TSS[7]);
	printf("TSS=%p\n请设置好TSS的段描述符以及中断门描述符!\n", (VOID*)TSS);
	system("pause");
	char buff[6];
	*((DWORD*)&buff[0]) = 0x0;
	*((WORD*)&buff[4]) = 0x0093;
	__asm
	{
		int 3;
		call fword ptr[buff];
		int 3;
		xor eax, eax;
		mov ax, 0x3b;
		mov fs, ax;
	}
	for (int i = 0; i < 18; ++i)
	{
		printf("%X\n", STACK[i]);
	}
	system("pause");
	return 0;
}

#include<stdio.h>
#include<Windows.h>
DWORD STACK[50] = { 0 };
DWORD TSS[]=
{
	0x00000000,//前一个TSS段选择子
	0x83f2ccb0,//esp0
	0x00000010,//ss0
	0x00000000,//esp1
	0x00000000,//ss1
	0x00000000,//esp2
	0x00000000,//ss2
	0x00000000,//CR3--TSS[7]
	0x00000000,//eip--TSS[8]
	0x00000002,//eflags
	0x11111111,//eax
	0x22222222,//ecx
	0x33333333,//edx
	0x44444444,//ebx
	(DWORD)(STACK+0x11),//esp
	0x00000000,//ebp
	0x55555555,//esi
	0x66666666,//edi
	0x00000023,//es
	0x0000001b,//cs
	0x00000023,//ss
	0x00000023,//ds
	0x0000003b,//fs
	0x00000000,//gs
	0x00000000,//ldt
	0x20ac0000,//iomap
};

void _declspec(naked) ring3()
{
	__asm
	{
		xor eax, eax;
		mov ax, fs;
		push eax;
		mov ax, cs;
		push eax;
		mov ax, ss;
		push eax;
		pushfd;
		mov eax, esp;
		push eax;
		int 34;
		mov bx, 0x1b;
		mov fs, bx;
		iretd;
	}
}

void _declspec(naked) ring0()
{
	__asm
	{
		pushfd;
		pop ecx;
		lea edi, dword ptr[STACK];
		mov dword ptr[edi], ecx;//efalgs

		mov eax, dword ptr[esp];
		mov dword ptr[edi + 0x8], eax;//eip

		mov eax, dword ptr[esp + 0x4];
		mov dword ptr[edi + 0xc], eax;//cs

		mov eax, dword ptr[esp + 0x8];
		mov dword ptr[edi + 0x10], eax;//eflags

		mov eax, dword ptr[esp + 0xc];
		mov dword ptr[edi + 0x14], eax;//esp

		mov eax, dword ptr[esp + 0x10];
		mov dword ptr[edi + 0x18], eax;//ss

		xor eax, eax;
		mov ax, cs;
		mov dword ptr[edi + 0x20], eax;
		mov ax, ss;
		mov dword ptr[edi + 0x24], eax;
		mov ax, fs;
		mov dword ptr[edi + 0x28], eax;

		mov bx, 0x30;
		mov fs, bx;
		mov eax, dword ptr fs : [0x40];
		mov edx, cr3;
		mov dword ptr[eax + 0x1c], edx;//存储CR3到原TSS中

		iretd;
	}
}
int main()
{
	memset(STACK, 0xcc, sizeof(DWORD) * 50);
	DWORD EIP = (DWORD)ring3;
	TSS[8] = EIP;
	printf("中断例程=%p\n", ring0);
	printf("请输入CR3:\n");
	scanf("%x", &TSS[7]);
	printf("TSS=%p\n请设置好TSS的段描述符以及中断门描述符!\n", (VOID*)TSS);
	system("pause");
	char buff[6];
	*((DWORD*)&buff[0]) = 0x0;
	*((WORD*)&buff[4]) = 0x0093;
	__asm
	{
		int 3;
		call fword ptr[buff];
		int 3;
		xor eax, eax;
		mov ax, 0x3b;
		mov fs, ax;
	}
	for (int i = 0; i < 18; ++i)
	{
		printf("%X\n", STACK[i]);
	}
	system("pause");
	return 0;
}




[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-3-23 18:15 被Mr.hack编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (12)
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
可以探索下x64的TSS
2020-3-23 20:04
1
雪    币: 83
活跃值: (1092)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
x64下 如何利用TSS 硬核切换任务呢
2020-3-24 10:33
1
雪    币: 2
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大哥   win7x86做tss段实验  我老是蓝屏
2020-4-21 08:08
1
雪    币: 2
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
能不能加个微信   交流交流
2020-4-21 08:19
1
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
吻天的狼 能不能加个微信 交流交流
我QQ:1358680601
2020-4-22 18:56
1
雪    币: 167
活跃值: (876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
大兄弟知道进入1环FS的值是多少嘛?
2020-7-25 23:20
1
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
taolaoda 大兄弟知道进入1环FS的值是多少嘛?
fs的值和cpu处于几环实际上没有关系,fs寄存器在0环和3环有特定的值只是因为window系统在0环时用fs寄存器获取kpcr,在3环时用fs寄存器获取teb,在你cpu进入1环后的例程中没有使用fs寄存器就无需为它指定特别的值
2020-7-26 19:14
2
雪    币: 167
活跃值: (876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
多谢,一直蓝屏,让我不能不多找细节
2020-7-26 23:27
1
雪    币: 177
活跃值: (368)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
到R0 后如果使用int 3之前保存efl,使用完int 3后再恢复efl,理论看着可以,但是实验时候经过int 3后面代码就卡死调试不动了,请教什么原因?
2022-12-22 11:21
1
雪    币: 177
活跃值: (368)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
吻天的狼 大哥 win7x86做tss段实验 我老是蓝屏
请问你win7 用的vc6编译器吗?
2022-12-22 11:22
0
雪    币: 3625
活跃值: (4559)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
xiaoheizi66 到R0 后如果使用int 3之前保存efl,使用完int 3后再恢复efl,理论看着可以,但是实验时候经过int 3后面代码就卡死调试不动了,请教什么原因?
估计是开了中断后发生线程切换了
2022-12-22 15:20
0
雪    币: 177
活跃值: (368)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
Mr.hack 估计是开了中断后发生线程切换了
在call R0实验时候,进入R0后随意下int3没有任何问题,怎么在TSS实验时候int3问题很严重,像你说int3改变了NT位,应该在int3之前保存efl,int3之后恢复efl,理论上就没有问题了,但在实验中很是有问题
2022-12-22 15:36
0
游客
登录 | 注册 方可回帖
返回