嗨,我正在尝试使用“ sysexit”从内核级别跳到用户级别,并准备了以下用户功能:
void user_level_function(void)
{
color_printk(RED, BLACK, "user_level_function task is running\n");
while(1);
}
GCC编译如下:
ffff80000010322f <user_level_function>:
ffff80000010322f: 55 push %rbp
ffff800000103230: 48 89 e5 mov %rsp,%rbp
ffff800000103233: 41 57 push %r15
ffff800000103235: 48 83 ec 08 sub $0x8,%rsp
ffff800000103239: 48 8d 0d f9 ff ff ff lea -0x7(%rip),%rcx # ffff800000103239 <user_level_function+0xa>
ffff800000103240: 49 bb af d9 00 00 00 movabs $0xd9af,%r11
ffff800000103247: 00 00 00
ffff80000010324a: 4c 01 d9 add %r11,%rcx
ffff80000010324d: 48 b8 a0 01 00 00 00 movabs $0x1a0,%rax
ffff800000103254: 00 00 00
ffff800000103257: 48 8d 14 01 lea (%rcx,%rax,1),%rdx
ffff80000010325b: be 00 00 00 00 mov $0x0,%esi
ffff800000103260: bf 00 00 ff 00 mov $0xff0000,%edi
ffff800000103265: 49 89 cf mov %rcx,%r15
ffff800000103268: b8 00 00 00 00 mov $0x0,%eax
ffff80000010326d: 49 b8 ca 4a ff ff ff movabs $0xffffffffffff4aca,%r8
ffff800000103274: ff ff ff
ffff800000103277: 49 01 c8 add %rcx,%r8
ffff80000010327a: 41 ff d0 callq *%r8
ffff80000010327d: eb fe jmp ffff80000010327d <user_level_function+0x4e>
上面的汇编代码表明该函数正在使用其当前编译的地址进行寻址。
因此,在我将函数复制到用户空间(0x800000)并执行后,由于相对寻址,寻址变得混乱。
unsigned long do_execve(void)
{
color_printk(RED,BLACK,"do_execve task is running\n");
memcpy(user_level_function,(void *)0x800000,1024);
PUSH_ALL;
__asm__ __volatile__ (
"wrmsr \n\t"
"movq $0x800000, %%rdx \n\t"
"movq $0xa00000, %%rcx \n\t"
".byte 0x48 \n\t"
"sysexit \n\t"
:
:"d"((unsigned long)KERNEL_CS >> 32),
"a"((unsigned long)KERNEL_CS & 0xffffffff),
"c"(0x174)
:"memory"
);
POP_ALL;
return 0;
}
因此,我想问一下是否有解决方法?
非常感谢!
答案 0 :(得分:0)
可以使用-fno-pic
编译器选项吗?