保护模式利用V86 mode 调用bios中断

        进入保护模式后,可以利iret 设置eflags寄存器中VM位 从而进入V86 mode。返回保护模式是用sysenter指令返回。

        注意事项:

                1、V86 mode是运行在CPL 3特权下的,操作代码是16位;

                2、分页机制有保护标志;

                3、需先初始化 GDT、IDT;

                4、使用iret指令前要将eglags中的IOPL设置为3,这样执行iret、sysenter指令不会报错;

                5、寻方式为 段:偏移,1M范围内;

                6、IOPL值需手动恢复

                7、待续

void bios_intx(BYTE number,PCONTEXT cont)
{
	DWORD stackAddr;
	WORD seg=*(WORD*)(number*4);
	WORD ip=*(WORD*)(number*4+2);

	*(DWORD*)(0x7C00-4)=0x0202;	//中断返回iret用到的eflags
	*(WORD*)(0x7C00-6)=0x0000;		//cs
	*(WORD*)(0x7C00-8)=0x7C05;		//eip
	*(BYTE*)(0x7C00)=0xEA;  //根据中断号跳转中断入口地址
	*(WORD*)(0x7C01)=*(WORD*)(number*4);	//偏移
	*(WORD*)(0x7C03)=*(WORD*)(number*4+2);//段

	*(WORD*)(0x7C05)=0x340f;//sysenter 0x340f
	*(WORD*)(0x7C09)=0x90;//

	asm("mov %%esp,%0 \n"
			:"=m"(stackAddr)
			 :);
	//根据后面保存数据使用栈的数量计算
	stackAddr-=24;
	//sysenter用到的数据
	wrmsr(IA32_SYSENTER_CS,(0x10),0); //
	wrmsr(IA32_SYSENTER_ESP,stackAddr,0);
	wrmsr(IA32_SYSENTER_EIP,&&_THIS_IP_,0);

	__asm__(
			"pushl %%ebp\n"		    //	|—————|
			"pushfl \n"				//	|	合计需保存
			"pushl %%gs \n"			//	|	6个寄存器
			"pushl %%fs\n"			//	|	此处保存的数量
			"pushl %%es \n"			//	|	影响stackAddr的值
			"pushl %%ds\n"			//	|—————|

			"pushl $0x0 \n"				//gs			|—————|
			"pushl $0x0 \n"				//fss			|
			"pushl $0x0 \n"				//es			| 6个段寄存器
			"pushl $0x0 \n"				//ds			|		+
			"pushl $0x0 \n"				//ss			| esp+eip+eflags
			"pushl $(0x7C00-8) \n"	//esp				| 都是用于iret 进入v86 mode 的
			"pushl $0x23202 \n"		//eflags 			| 标志,第17位vm ;第9位中断 ;第13~14位 iopl=3
			"pushl $0  \n"					//cs		|
			"pushl $0x7C00 \n"		//压入eip       	|—————|
			"movl %0,%%eax\n"					// 	|—————|
			"movl 0x9C(%%eax),%%edi\n"			//	|为中断传递
			"movl 0xA0(%%eax),%%esi\n"			//	|的数据
			"movl 0xA4(%%eax),%%ebx\n"			//	|寄存器
			"movl 0xA8(%%eax),%%edx\n"			//	|
			"movl 0xAC(%%eax),%%ecx\n"			//	|
			"movl 0xB0(%%eax),%%eax\n"			//	|—————|
			"iret \n"
			:
			:"m"(cont)
			);
			//:"m"(cont->Eax),"m"(cont->Ebx),"m"(cont->Ecx),"m"(cont->Edx),"m"(cont->Edi),"m"(cont->Esi)

	_THIS_IP_:
	asm(
			"pushf\n"				//		|---------------
			"pushal\n" 				//		|eflags
			"pushl %%ds \n"		// 		    |8个通用寄存器
			"pushl %%es\n"		//			|4个段寄存器
			"pushl %%fs\n"		//			|共13个全部保存
			"pushl %%gs \n"		//			|-------------
			"add $52,%%esp\n"   // 13*4
			"popl %%ds \n"	//ds			|------------
			"popl %%es\n"	//es			|
			"popl %%fs\n"	//fs			|共六个寄器
			"popl %%gs \n"	//gs			|
			"popf \n"		//eflags    	|
			"popl %%ebp\n"//				|-------------
			:
			:);
	memcpy(&cont->SegGs,(void*)(stackAddr-52),52);
	cont->EFlag=*(DWORD*)(stackAddr-4);
	//memcpy(&cont->Edi,(stackAddr+),4);
	//stackAddr
	return;
}
void bios_int_10h()
{
	CONTEXT cont;
	memset(&cont,0,sizeof(CONTEXT));
	cont.Eax=0x4f0a;
	cont.Ebx=0;
	bios_intx(0x10,&cont);
	//es:di为返回数据
	print_farmat_msg("int 10 %x,%x \n",cont.SegEs<<4,cont.Edi);

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻雀123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值