【发布时间】:2021-11-03 19:58:57
【问题描述】:
我正在使用 NASM 版本 2.14.02 和 GNU ld 2.34 在 64 位 Linux 上编译程序集文件(例如,hello world)。
我想(基本上只是为了好玩)生成一个尽可能小的可执行文件。但是,在实用程序生成的可执行文件中,有一些字符串对于可执行文件绝对没有意义(如源文件的名称、节名等)。我该如何摆脱它们?
这是我的工作:
$ cat hello_world_32.s
SECTION .rodata
msg: db 'Hello world!',0xA
msg_len: equ $-msg
SECTION .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msg_len
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
$ nasm -f elf32 -o hello_world.o hello_world_32.s
$ ld --nmagic -m elf_i386 -o hello_world hello_world.o
$ ./hello_world
Hello world!
$ grep hello_world_32.s hello_world
Binary file hello_world matches
$ grep .text hello_world
Binary file hello_world matches
$ grep .rodata hello_world
Binary file hello_world matches
$
这是xxd hello_world的输出:
00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............
00000010: 0200 0300 0100 0000 6080 0408 3400 0000 ........`...4...
00000020: 9001 0000 0000 0000 3400 2000 0100 2800 ........4. ...(.
00000030: 0600 0500 0100 0000 6000 0000 6080 0408 ........`...`...
00000040: 6080 0408 2d00 0000 2d00 0000 0500 0000 `...-...-.......
00000050: 1000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: b804 0000 00bb 0200 0000 b980 8004 08ba ................
00000070: 0d00 0000 cd80 b801 0000 0031 dbcd 8000 ...........1....
00000080: 4865 6c6c 6f20 776f 726c 6421 0a00 0000 Hello world!....
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000a0: 0000 0000 6080 0408 0000 0000 0300 0100 ....`...........
000000b0: 0000 0000 8080 0408 0000 0000 0300 0200 ................
000000c0: 0100 0000 0000 0000 0000 0000 0400 f1ff ................
000000d0: 1200 0000 8080 0408 0000 0000 0000 0200 ................
000000e0: 1600 0000 0d00 0000 0000 0000 0000 f1ff ................
000000f0: 2300 0000 6080 0408 0000 0000 1000 0100 #...`...........
00000100: 1e00 0000 8d90 0408 0000 0000 1000 0200 ................
00000110: 2a00 0000 8d90 0408 0000 0000 1000 0200 *...............
00000120: 3100 0000 9090 0408 0000 0000 1000 0200 1...............
00000130: 0068 656c 6c6f 5f77 6f72 6c64 5f33 322e .hello_world_32.
00000140: 7300 6d73 6700 6d73 675f 6c65 6e00 5f5f s.msg.msg_len.__
00000150: 6273 735f 7374 6172 7400 5f65 6461 7461 bss_start._edata
00000160: 005f 656e 6400 002e 7379 6d74 6162 002e ._end...symtab..
00000170: 7374 7274 6162 002e 7368 7374 7274 6162 strtab..shstrtab
00000180: 002e 7465 7874 002e 726f 6461 7461 0000 ..text..rodata..
00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001b0: 0000 0000 0000 0000 1b00 0000 0100 0000 ................
000001c0: 0600 0000 6080 0408 6000 0000 1f00 0000 ....`...`.......
000001d0: 0000 0000 0000 0000 1000 0000 0000 0000 ................
000001e0: 2100 0000 0100 0000 0200 0000 8080 0408 !...............
000001f0: 8000 0000 0d00 0000 0000 0000 0000 0000 ................
00000200: 0400 0000 0000 0000 0100 0000 0200 0000 ................
00000210: 0000 0000 0000 0000 9000 0000 a000 0000 ................
00000220: 0400 0000 0600 0000 0400 0000 1000 0000 ................
00000230: 0900 0000 0300 0000 0000 0000 0000 0000 ................
00000240: 3001 0000 3600 0000 0000 0000 0000 0000 0...6...........
00000250: 0100 0000 0000 0000 1100 0000 0300 0000 ................
00000260: 0000 0000 0000 0000 6601 0000 2900 0000 ........f...)...
00000270: 0000 0000 0000 0000 0100 0000 0000 0000 ................
如何去除可执行文件中不需要的字符串?是否有某种方法可以只编译指令而忽略所有其他指令?
【问题讨论】:
-
你试过链接器的
-s开关吗? -
nasm -fbin进行“平面二进制”输出,没有围绕它的 ELF 元数据。如果您在 .asm 文件中使用db手动定义 ELF 标头(并在一些无关字段中塞入一些机器代码),您可以制作一个非常小的静态 ELF 二进制文件。 muppetlabs.com/~breadbox/software/tiny/teensy.html -
我不是 elf 格式方面的专家,但我想说它们是正确加载程序所必需的。
-
在编程中,准确地知道你到底想要什么是非常重要的,尤其是当你告诉计算机该做什么时。在与其他人类程序员交流时,这也是一件有用的事情,他们往往会准确地注意到你所说的话。
-
不管怎样,你可能想试试FASM;它可以输出完整的 ELF 可执行文件(不仅仅是 .o),没有任何部分只是 ELF 程序头。所以它可以运行,但是在上面使用 GDB 很痛苦。但它很小。