在Linux下执行平面二进制文件

时间:2009-08-16 02:31:05

标签: linux assembly nasm

有没有办法在Linux中执行平面二进制映像,使用如下语法:

nasm -f bin -o foo.bin foo.asm
runbinary foo.bin

3 个答案:

答案 0 :(得分:9)

Linux内核可以加载几种不同的二进制格式 - ELF只是最常见的,尽管a.out格式也是众所周知的。

支持的二进制格式由哪个binfmt模块加载或编译到内核(它们位于内核配置的Filesystem部分下)来控制。 uClinux BFLT平面格式二进制文件有一个binfmt_flat非常小 - 它们甚至可以被zlib压缩,这样可以让你的二进制文件更小,所以这可能是一个不错的选择。

看起来nasm本身不支持这种格式,但是如Jim Lewis为ELF所描述的那样,手动添加必要的标题非常容易。有格式here的描述。

答案 1 :(得分:7)

是否有某些原因你不想使用“-f elf”而不是“-f bin”?

我认为Linux不会运行不是ELF格式的二进制文件。我找不到将平面二进制文件转换为ELF的工具,但你可以通过将ELF信息放在foo.asm中来作弊, 使用here描述的技术:

  

我们可以看一下ELF   规范,和   /usr/include/linux/elf.h,和   标准创建的可执行文件   工具,弄清楚我们的空洞   ELF可执行文件应该是这样的。但,   如果你是不耐烦的类型,你可以   只需使用我在这里提供的那个:

 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      phdr - $$                       ;   e_phoff
               dd      0                               ;   e_shoff
               dd      0                               ;   e_flags
               dw      ehdrsize                        ;   e_ehsize
               dw      phdrsize                        ;   e_phentsize
               dw      1                               ;   e_phnum
               dw      0                               ;   e_shentsize
               dw      0                               ;   e_shnum
               dw      0                               ;   e_shstrndx

 ehdrsize      equ     $ - ehdr

 phdr:                                                 ; Elf32_Phdr
               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

 phdrsize      equ     $ - phdr

 _start:

 ; your program here

  filesize      equ     $ - $$
     

此图片包含ELF标头,   将文件标识为Intel 386   可执行文件,没有节头   表和程序头表   包含一个条目。说入口   指示程序加载器加载   将整个文件存入内存(它是   程序的正常行为   包括其ELF标题和程序   内存图像中的标头表)   从内存地址0x08048000开始   (这是默认地址   要加载的可执行文件,并开始   在_start执行代码,其中   程序后立即出现   标头表。没有.data段,没有   .bss段,没有评论 - 什么都没有   但是必需品。

     

所以,让我们加入我们的小程序:

 ; tiny.asm
               org     0x08048000

 ;
 ; (as above)
 ;

_start: mov bl, 42 xor eax, eax inc eax int 0x80 filesize equ $ - $$
     

并尝试一下:

 $ nasm -f bin -o a.out tiny.asm
 $ chmod +x a.out
 $ ./a.out ; echo $?
 42

答案 2 :(得分:0)

最低限度,Linux将需要弄清楚可执行文件的格式,并且它将从第一个字节中获取该格式。例如,如果该脚本将是#!,则 shebang 。如果是ELF,则为0x7F'E''L''F'。这些魔术数字将通过查找确定处理程序。

因此,您将需要一个带有公认魔术数字的标头。您可以在 / proc / sys / fs / binfmt_misc 中获得shebang支持的格式的列表。 (很不幸)a little trickier是获取本机二进制格式的列表。

bFLT可能是一个不错的选择。确实,这是一种流行的嵌入式可执行格式。但是您也可以将ELF压得很远。 This article得到了一个ELF可执行文件,最小为45个字节。就是说,您将主要通过手动而不是工具来压缩它。