将内存复制功能复制到用户空间后,如何纠正相对寻址?

时间:2019-05-21 06:51:32

标签: c gcc operating-system

嗨,我正在尝试使用“ 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;
}

因此,我想问一下是否有解决方法?

非常感谢!

1 个答案:

答案 0 :(得分:0)

可以使用-fno-pic编译器选项吗?