如何将 libc6 中的函数导入 ELF 可执行文件?

发布于 2024-09-25 11:30:25 字数 2426 浏览 6 评论 0原文

我正在创建一个 i386 ELF 可执行文件,需要从 libc6 导入函数。 (顺便说一句,它是 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     $ - $$

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

I am creating an i386 ELF executable that needs to import a function from libc6. (It's printf, by the way.)

I have created a very small ELF executable that prints "Hello, world!" to the console by using the Linux kernel interrupt 0x80. This is not optimal and I would like to have the application make use of libc instead.

Here is what I have so far: (credit to this page for most of the structure alignment code.)

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     $ - $

I think I need to add another program header for imports, but I really don't know - nor am I familiar with the format of the contents of that section.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝礼 2024-10-02 11:30:25

如果您愿意让链接器完成其工作,这就足够了(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/ 。然后,使用 readelf、objdump 和/或 hexdump 拆解编译上述代码得到的可执行映像,并了解其构造方式。

If you're willing to let the linker do its job, this is enough (GAS syntax; compile with 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!"

(Technically .LC0 should be put into .rodata but I can't remember exactly how you do that and I'm not on my Linux box right now. Also, this doesn't maintain any stack pointer alignment, which shouldn't be a problem for a toy program like this, but I make no promises.)

If you really want to construct the entire executable by hand, first read this book: http://www.iecc.com/linker/ Then you'll need to read the ELF specification, the System V generic ABI, and the x86-32 psABI supplement; these can all be found here: http://refspecs.freestandards.org/ . Then, use readelf, objdump, and/or hexdump to dismantle the executable image you get from compiling the above and work out how it's constructed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文