如何将 libc6 中的函数导入 ELF 可执行文件?
我正在创建一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您愿意让链接器完成其工作,这就足够了(GAS 语法;使用
gcc hello.s
编译):(技术上
.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
):(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/orhexdump
to dismantle the executable image you get from compiling the above and work out how it's constructed.