(x64)Linux中断门状态切换时rsp的获取。
在IA-32e架构中,Interrupt/trap-gate描述符中新增了IST域(Interrupt Stack Table
, 中断栈表),可以为 interrupt handler 提供额外的stack指针。
当中断门描述符表中的IST字段若不为0,则在状态切换时rsp将不会采用 tss.rsp0;若IST=n(1~7),则 rsp=tss.istn。
code
int main()
{
long res = 0x1234567812345678;
char buff[] = "haha,walker!";
long rsp, rbp, tr;
asm volatile ("movq %%rsp, %%rax; movq %%rbp, %%rbx; xorq %%rdx, %%rdx;str %%dx" : "=a"(rsp), "=b"(rbp), "=d"(tr));
printf("buff:%s addr: %p\n", buff, buff);
printf("int3_handler addr: %p\n", int3_handler);
printf("stack rsp: %p; rbp: %p; res addr: %p; tr: %p\n", rsp, rbp, &res, tr);
getchar();
asm volatile ("int $0x3;");
asm volatile ("leaq %0, %%rdx; movq %%rax, (%%rdx);" : "=m"(res));
printf("___ user mode ___\n");
printf("Good Done! res: %p\n", res);
return 0;
}
注:str指令为非特权指令,可以在用户态下获取。
测试
tr寄存器的低16bit为tss描述符的段选择子,其:index=1000(b),即8。
其处于GDT中的TSS段描述符为 00000000ffff8100 01008b008c802087
。
00000000 ffff810001 008b 008c80 2087
保留 段基地址 段基地址 段长度
008b ==> 0000 0000 1 00 0 1011(tss)
段长度 P DPL S type
段基地址(tss):0xffff810001008c80
int3中断使用IDT表中的index=3的中断门描述符,其为 00108780 8056ee04
。其IST=4,即在发生状态切换至内核时,rsp将会使用IST4的stack。
1 11 0 1110(64 int gate) 00000 100
P PDL type IST
段选择子:0010 index=2(GDT)
发生int3中断时,将会中断至内核 arch/x86/kernel/entry_64.S
中的int3处理函数中:
此时 rsp=0xffffffff80825fd8
。
由于栈是逆向增长的,故发生中断时的参数应该在 0xffffffff80826000 之下。