昨天刚学到保护模式的TSS任务段,试验是CALL JMP实现切换任务并且能跳转回来,用jmp切换,jmp能够切换,并且跳转回来,用call就一直挂,挂到不知道重复了多少次,也找到很多帖子
!process 0 0获取 进程的Cr3
eq 8003f048 0000e913`f9ec0068
是在不知道哪里出了问题,是感觉没多少东西的,
jmp切换的时候,需要jmp跳回来,不管NT位
call切换的时候NT置为1,但只要中断了会给NT=0,所以我在里面恢复了eflag
iretd指令执行的时候会依赖eflag寄存器的NT为nT=0从堆栈里返回
NT=1的时候iretd从当前TR寄存器指向的TSS的结构的前两个字节的链接(保存上一个任务的任务段选择子),根本这个选择子可以找到切换之前的环境(我测试过)切换回去
链接jmp切换的时候不会填充,call切换的时候会自动填充,
我们自己构造的TSS,虽然里面有4个堆栈的ESP,SS,但是jmp call切换的时候会把esp,ss填充到esp,ss我猜测,esp0,ss0,esp1,ss1,esp2,ss2这些是用
#include "stdafx.h"
#include <Windows.h>
int valer=0;
char str[6]={0};
void _declspec(naked) text(){
__asm{
#if 1
int 3
pushfd
pop eax
or eax,0x4000
push eax
popfd
iretd
#else
jmp fword ptr str
#endif
}
}
int main(int argc, char argv[])
{ char stack[1000]={0};
char buf[6]={0,0,0,0,0,0};
((int)buf)=(int)text;
DWORD Cr3=0;
(DWORD)&buf[0]=0x12345678;
(WORD*)&buf[4]=0x48;
printf("请输入当前进程Cr3的值:");
scanf("%x",&Cr3);
DWORD TSS[0x68]={
0,
(DWORD)stack,
0x10,
0,
0,
0,
0,
Cr3, //CR3
(DWORD)text, //EIP
0, //EFLAGE
0x1111, //EAX
0x2222, //EBX
0x3333, //ECX
0x4444, //EDX
(DWORD)(stack)+500 , //ESP
0, //EBP
0, //ESi
0, //EDI
0x23, //ES
0x08, //CS
0x10, //SS
0x23, //DS
0x30, //FS
0, //GS
0, //LDR
0x20ac0000 //Io MAP
};
printf("TSS=%p\n",TSS);
DWORD tr=0;
__asm{
str eax
mov tr,eax
}
*(WORD*)&str[4]=tr;
__asm{
call fword ptr buf
}
printf("%p\n",valer);
getchar();
return 0;
}
这是call的试验结构
最后一张图片是执行完iretd 立刻这样,这好像不是蓝屏,虚拟机一会它就自己重启了,见鬼了 Windug也不会出现终止信息,求教各位大神,这程序应该不会出现问题的啊,call jmp就是返回方式不同嘛
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课