3

我正在创建一个需要从 libc6 导入函数的 i386 ELF 可执行文件。(printf顺便说一句,它是。)

我创建了一个非常小的 ELF 可执行文件,它打印“Hello, world!” 通过使用 Linux 内核中断到控制台0x80。这不是最优的,我想让应用程序使用 libc。

到目前为止,这是我所拥有的:(大部分结构对齐代码都归功于此页面。)

BITS 32

            org     0x08048000

ehdr:                                                 ; Elf32_Ehdr
            db      0x7F, "ELF", 1, 1, 1, 0         ;   e_ident
    times 8 db      0
            dw      2                               ;   e_type
            dw      3                               ;   e_machine
            dd      1                               ;   e_version
            dd      _start                          ;   e_entry
            dd      52
            dd      0                               ;   e_shoff
            dd      0                               ;   e_flags
            dw      52
            dw      32
            dw      1                               ;   e_phnum
            dw      0                               ;   e_shentsize
            dw      0                               ;   e_shnum
            dw      0                               ;   e_shstrndx

;   this is the header for the code section

            dd      1                               ;   p_type
            dd      0                               ;   p_offset
            dd      $$                              ;   p_vaddr
            dd      $$                              ;   p_paddr
            dd      filesize                        ;   p_filesz
            dd      filesize                        ;   p_memsz
            dd      5                               ;   p_flags
            dd      0x1000                          ;   p_align

_start:

            ; We want to print the string

    mov eax,4            ; 'write' system call
    mov ebx,1            ; file descriptor 1 = screen
    mov ecx,teststr      ; string to write
    mov edx,14           ; length of string to write
    int 80h              ; call the kernel

    ; Terminate program
    mov eax,1            ; 'exit' system call
    mov ebx,0            ; exit with error code 0
    int 80h              ; call the kernel

_stringtable:

            teststr db "Hello, world!",10,0

filesize      equ     $ - $$

我想我需要为导入添加另一个程序头,但我真的不知道 - 我也不熟悉该部分内容的格式。

4

1 回答 1

2

如果你愿意让链接器完成它的工作,这就足够了(GAS 语法;用 编译gcc hello.s):

        .text
        .globl main
        .type main, @function
main:
        leal    .LC0, %eax
        pushl   %eax
        call    puts
        xorl    %eax, %eax
        ret
        .size main, .-main
.LC0:
        .asciz  "Hello, world!"

(技术上.LC0应该放入,.rodata但我不记得你是如何做到这一点的,而且我现在不在我的 Linux 机器上。此外,这不会保持任何堆栈指针对齐,这不应该是一个问题像这样的玩具程序,但我不做任何承诺。)

如果您真的想手动构建整个可执行文件,请先阅读本书:http ://www.iecc.com/linker/ 然后您需要阅读 ELF 规范、System V 通用 ABI 和 x86- 32 psABI 补充;这些都可以在这里找到:http ://refspecs.freestandards.org/ 。然后,使用readelfobjdump和/或hexdump拆解您通过编译上述文件获得的可执行映像,并计算出它是如何构建的。

于 2010-09-30T22:56:42.710 回答