简体   繁体   English

编译动态链接内核

[英]Compile Dynamically Linked Kernel

I am attempting to implement KASLR in the xv6 kernel, so i need to recompile/link the kernel in a dynamic way(relocation table). 我正在尝试在xv6内核中实现KASLR,因此我需要以动态方式(重定位表)重新编译/链接内核。 Since the kernel is currently hardcoded, even if I change the kernel code and data mappings, the instructions will still reference hardcoded virtual addresses. 由于内核当前是硬编码的,因此即使我更改了内核代码和数据映射,指令仍将引用硬编码的虚拟地址。 I need a way for the instructions to reference other parts of the elf without hardcoded addresses. 我需要一种说明方式来引用没有硬编码地址的elf其他部分。 An example of this is below: This is a sample of how it looks after current compilation: 下面是一个示例:这是当前编译后的外观示例:

8010018e:   83 ec 0c                sub    $0xc,%esp
80100191:   68 a7 79 10 80          push   $0x801079a7
80100196:   e8 b5 01 00 00          call   80100350 <panic>
8010019b:   90                      nop
8010019c:   8d 74 26 00             lea    0x0(%esi,%eiz,1),%esi.

As you can see, the instructions such as the push instruction reference hardcoded v addresses($0x801079a7). 如您所见,诸如push指令之类的指令引用了硬编码的v地址($ 0x801079a7)。 This is because this elf is compiled in a static way with no relocations:(readelf printout) 这是因为此elf以静态方式编译而没有重定位:(readelf打印输出)

 Program Headers:
    Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
    LOAD           0x001000 0x80100000 0x00100000 0x0b516 0x15668 RWE 0x1000
    GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10
    Section to Segment mapping:
    Segment Sections...
    00     .text .rodata .stab .stabstr .data .bss
    01
    There is no dynamic section in this file.
    There are no relocations in this file.

I need advice on how to recompile a statically linked elf binary to one with relocation and then be able to map the kernel anywhere in virtual memory. 我需要有关如何通过重定位将静态链接的elf二进制文件重新编译为一个二进制文件,然后能够将内核映射到虚拟内存中任何位置的建议。 Additionally, what would I have to modify in the bootloader for parsing the elf to load it correctly with relocation? 另外,为了解析elf以重定位正确加载它,我需要在引导加载程序中进行哪些修改? Will I have to custom parse a GOT included in the kernel elf? 我是否需要自定义解析内核小精灵中包含的GOT?

The following is a linker script to compile the kernel and essentially set its base hardcoded virtual address: 0x80100000 以下是一个链接器脚本,用于编译内核并从本质上设置其基本硬编码虚拟地址:0x80100000

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)

SECTIONS
{
    /* Link the kernel at this address: "." means the current address */
        /* Must be equal to KERNLINK */
    . = 0x80100000;

    .text : AT(0x100000) {
        *(.text .stub .text.* .gnu.linkonce.t.*)
    }

    PROVIDE(etext = .); /* Define the 'etext' symbol to this value */

    .rodata : {
        *(.rodata .rodata.* .gnu.linkonce.r.*)
    }

    /* Include debugging information in kernel memory */
    .stab : {
        PROVIDE(__STAB_BEGIN__ = .);
        *(.stab);
        PROVIDE(__STAB_END__ = .);
        BYTE(0)     /* Force the linker to allocate space
                   for this section */
    }

    .stabstr : {
        PROVIDE(__STABSTR_BEGIN__ = .);
        *(.stabstr);
        PROVIDE(__STABSTR_END__ = .);
        BYTE(0)     /* Force the linker to allocate space
                   for this section */
    }

    /* Adjust the address for the data segment to the next page */
    . = ALIGN(0x1000);

    /* Conventionally, Unix linkers provide pseudo-symbols
     * etext, edata, and end, at the end of the text, data, and bss.
     * For the kernel mapping, we need the address at the beginning
     * of the data section, but that's not one of the conventional
     * symbols, because the convention started before there was a
     * read-only rodata section between text and data. */
    PROVIDE(data = .);

    /* The data segment */
    .data : {
        *(.data)
    }

    PROVIDE(edata = .);

    .bss : {
        *(.bss)
    }

    PROVIDE(end = .);

    /DISCARD/ : {
        *(.eh_frame .note.GNU-stack)
    }
}

看来我必须修改xv6引导程序并重写许多操作系统才能完成动态内核。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM