关于精灵文件头的一个快速问题,我似乎找不到任何有用的东西,关于如何在精灵头中添加/更改字段。我希望能够改变神奇的数字和添加一个构建日期到标题,可能还有其他一些事情。
据我所知,链接器会创建标题信息,但在LD脚本中看不到引用它的任何内容(尽管我对ld脚本还不熟悉)。
我用gcc和建筑做手臂。
谢谢!
更新:
发布于 2008-10-24 16:14:28
我不知道链接器脚本命令可以做到这一点,但您可以使用objcopy命令进行post链接。-添加节选项可用于将包含任意数据的部分添加到ELF文件中。如果ELF标题不包含您想要的字段,只需创建一个新的部分并将它们添加到其中。
发布于 2008-10-26 10:49:12
这个链接(teensy精灵二进制)是某人对另一个问题的回答,但它涉及到ELF标题的一些细节。
发布于 2017-11-02 21:24:13
您可以创建一个具有信息字段(如版本号)的对象文件,并链接该文件,以便将它们包含在结果的ELF二进制文件中。
伊万特
例如,作为构建过程的一部分,可以生成包含一个或多个#ident指令的-例如-#ident:
#ident "Build: 1.2.3 (Halloween)"
#ident "Environment: example.org"汇编:
$ gcc -c info.c检查是否包括这些信息:
$ readelf -p .comment info.o
String dump of section '.comment':
[ 1] Build: 1.2.3 (Halloween)
[ 1a] Environment: example.org
[ 33] GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)或者,您可以使用objdump -s --section .comment info.o。请注意,在默认情况下,GCC也会撰写自己的评论。
链接ELF可执行文件后,请检查以下信息:
$ gcc -o main main.o info.o
$ readelf -p .comment main
String dump of section '.comment':
[ 0] GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)
[ 2c] Build: 1.2.3 (Halloween)
[ 45] Environment: example.org评论科
在C转换单元中使用#ident基本上等同于在汇编程序文件中创建.comment部分。示例:
$ cat info.s
.section .comment
.string "Build: 1.2.3 (Halloween)"
.string "Environment: example.org"
$ gcc -c info.s
$ readelf -p .comment info.o
String dump of section '.comment':
[ 0] Build: 1.2.3 (Halloween)
[ 19] Environment: example.org使用不常见的节名也同样有效(例如,.section .blahblah)。但是.comment被其他工具所使用和理解。GNU也理解.ident指令,这就是GCC将#ident翻译成的。
有符号
对于您也希望从ELF可执行文件本身访问的数据,您需要创建符号。
奥比文特
假设您希望包含存储在数据文件中的一些神奇字节:
$ cat magic.bin
2342使用GNU讣告转换为对象文件
$ objcopy -I binary -O elf64-x86-64 -B i386 \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
magic.bin magic.o检查符号:
$ nm magic.o
0000000000000005 R _binary_magic_bin_end
0000000000000005 A _binary_magic_bin_size
0000000000000000 R _binary_magic_bin_start示例用法:
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
extern const char _binary_magic_bin_start[];
extern const char _binary_magic_bin_end[];
extern const unsigned char _binary_magic_bin_size;
static const size_t magic_bin_size = (uintptr_t) &_binary_magic_bin_size;
int main()
{
char s[23];
memcpy(s, _binary_magic_bin_start,
_binary_magic_bin_end - _binary_magic_bin_start);
s[magic_bin_size] = 0;
puts(s);
return 0;
}将一切联系在一起:
$ gcc -g -o main_magic main_magic.c magic.oGNU ld
GNU ld还可以使用与objcopy兼容的命名方案将数据文件转换为对象文件:
$ ld -r -b binary magic.bin -o magic-ld.o与objcopy不同,它将符号放置到.data中,而不是.rodata部分(cf )。objdump -h magic.o)。
夹竹桃
如果GNU不可用,可以使用GNU as 指令创建对象文件(使用gcc -c incbin.s组装):
.section .rodata
.global _binary_magic_bin_start
.type _binary_magic_bin_start, @object
_binary_magic_bin_start:
.incbin "magic.bin"
.size _binary_magic_bin_start, . - _binary_magic_bin_start
.global _binary_magic_bin_size
.type _binary_magic_bin_size, @object
.set _binary_magic_bin_size, . - _binary_magic_bin_start
.global _binary_magic_bin_end
.type _binary_magic_bin_end, @object
.set _binary_magic_bin_end, _binary_magic_bin_start + _binary_magic_bin_size
; an alternate way to include the size
.global _binary_magic_bin_len
.type _binary_magic_bin_len, @object
.size _binary_magic_bin_len, 8
_binary_magic_bin_len:
.quad _binary_magic_bin_sizexxd
一个更可移植的选择,不需要GNU objcopy,也不需要GNU,比如创建一个中间C文件并编译并链接它。例如,使用xxd
$ xxd -i magic.bin | sed 's/\(unsigned\)/const \1/' > magic.c
$ gcc -c magic.c
$ nm magic.o
0000000000000000 R magic_bin
0000000000000008 R magic_bin_len
$ cat magic.c
const unsigned char magic_bin[] = {
0x32, 0x33, 0x34, 0x32, 0x0a
};
const unsigned int magic_bin_len = 5;https://stackoverflow.com/questions/233358
复制相似问题