首页
社区
课程
招聘
未解决 [求助]TSS 任务段跳转问题
发表于: 2018-11-21 12:06 2776

未解决 [求助]TSS 任务段跳转问题

2018-11-21 12:06
2776
最近在学习保护模式的时候构建TSS任务段的时候发现了这个问题。
首先找TSS地址构建TSS段描述符。 用windbg写入gdt表中。 
用jmp来跳转的时候程序执行顺利。 jmp回来的TSS选择子是提前查看好的(即原来TR寄存器存储的值)
但是用call来调用的时候, 程序可以跳转到目标裸函数位置, 寄存器也全部更换完成。 但iretd指令执行后直接蓝屏。 
查看以前的文章, 也参考了intel的官方文档。就是找不出问题所在。

跪求指导~  感激不尽~~

偶然间看见intel对于iretd的描述如下:



我的CPU就是64位的, 不太清楚跟这个IA-32e mode是不是一个概念。 另外我是用了win7系统搭建了一个XP sp3虚拟机来进行练习的。

代码如下:(tss描述符:0000E912`FF0C0068)

char pretr[6] = {0x78, 0x56, 0x34, 0x12, 0x28, 0x00};

void _declspec(naked) test()
{
	_asm 
	{	
		int 3
	
		iretd
		//jmp fword ptr ds:[pretr]
	}
}

int main(int argc, char* argv[])
{
	
	char sele[6] = {0};
	*(DWORD*)sele = 0x12345678;
	*(WORD*)&sele[4] = 0x0048;
	

	DWORD cr3 = 0;
	printf("cr3:");
	scanf("%x",&cr3);

	//12ff0c
	DWORD myTSS[26] ={   
	0x00000000, //0 previous task link
	0x0012fe00, //4 esp0
	0x00000010, //8
	0x00000000, //12
	0x00000000, //16
	0x00000000, //20
	0x00000000, //24
	cr3,		//28 cr3
	0x00401020, //32 eip
	0x00000000, //36 eflags	
	0x00000000, //40 eax
	0x00000000, //44 ecx 
	0x00000000, //48 edx
	0x00000000, //52 ebx
	0x0012fe00, //56 esp
	0x00000000, //60 ebp
	0x00000000, //64 esi
	0x00000000, //68 edi
	0x00000023, //72 es
	0x00000008, //76 cs
	0x00000010, //80 ss
	0x00000023, //84 ds
	0x00000030, //88 fs
	0x00000000, //92 gs
	0x00000000, //96 LDT
	0x20ac0000, //100 I/O map

	};
	
	_asm
	{
		
		call fword ptr ds:[sele]
		//jmp fword ptr ds:[sele]
	}
	
	return 0;

}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-11-21 12:07 被米九编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
lz写错指令了,iretd是中断返回,应该用retf
2018-11-30 02:41
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
问题解决了。   
程序执行过程中不能有任何调试器的中断或单步执行。如果把int 3 去掉程序可以顺利执行。
调试器的动作会导致eflag寄存器被修改。 而eflag寄存器的nt位正好用于标志此时CPU处于一个nested task中, 调试器的单步或中断会使nt位置0, 导致iretd不能正确执行tss返回(因为nt位被置0了), 而执行了中断返回,中断返回就会pop cs, eip, eflag,esp, ss出来, 那程序当然会直接崩掉, 并导致蓝屏。
2018-11-30 08:08
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
米九 问题解决了。 程序执行过程中不能有任何调试器的中断或单步执行。如果把int 3 去掉程序可以顺利执行。 调试器的动作会导致eflag寄存器被修改。 而eflag寄存器的nt位正好用于标志此时 ...
试试x64的
2018-11-30 19:22
0
游客
登录 | 注册 方可回帖
返回
//