首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ELF文件头

ELF文件头
EN

Stack Overflow用户
提问于 2008-10-24 12:44:22
回答 9查看 12K关注 0票数 12

关于精灵文件头的一个快速问题,我似乎找不到任何有用的东西,关于如何在精灵头中添加/更改字段。我希望能够改变神奇的数字和添加一个构建日期到标题,可能还有其他一些事情。

据我所知,链接器会创建标题信息,但在LD脚本中看不到引用它的任何内容(尽管我对ld脚本还不熟悉)。

我用gcc和建筑做手臂。

谢谢!

更新:

  • 好的,也许我的第一个问题应该是:是否可以在链接时创建/编辑头文件?
EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2008-10-24 16:14:28

我不知道链接器脚本命令可以做到这一点,但您可以使用objcopy命令进行post链接。-添加节选项可用于将包含任意数据的部分添加到ELF文件中。如果ELF标题不包含您想要的字段,只需创建一个新的部分并将它们添加到其中。

票数 11
EN

Stack Overflow用户

发布于 2008-10-26 10:49:12

这个链接(teensy精灵二进制)是某人对另一个问题的回答,但它涉及到ELF标题的一些细节。

票数 8
EN

Stack Overflow用户

发布于 2017-11-02 21:24:13

您可以创建一个具有信息字段(如版本号)的对象文件,并链接该文件,以便将它们包含在结果的ELF二进制文件中。

伊万特

例如,作为构建过程的一部分,可以生成包含一个或多个#ident指令的-例如-#ident

代码语言:javascript
复制
#ident "Build: 1.2.3 (Halloween)"
#ident "Environment: example.org"

汇编:

代码语言:javascript
复制
$ gcc -c info.c

检查是否包括这些信息:

代码语言:javascript
复制
$ 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可执行文件后,请检查以下信息:

代码语言:javascript
复制
$ 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部分。示例:

代码语言:javascript
复制
$ 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可执行文件本身访问的数据,您需要创建符号。

奥比文特

假设您希望包含存储在数据文件中的一些神奇字节:

代码语言:javascript
复制
$ cat magic.bin 
2342

使用GNU讣告转换为对象文件

代码语言:javascript
复制
$ objcopy -I binary -O elf64-x86-64 -B i386 \
    --rename-section .data=.rodata,alloc,load,readonly,data,contents \
    magic.bin magic.o

检查符号:

代码语言:javascript
复制
$ nm  magic.o  
0000000000000005 R _binary_magic_bin_end
0000000000000005 A _binary_magic_bin_size
0000000000000000 R _binary_magic_bin_start

示例用法:

代码语言:javascript
复制
#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;
}

将一切联系在一起:

代码语言:javascript
复制
$ gcc -g -o main_magic main_magic.c magic.o

GNU ld

GNU ld还可以使用与objcopy兼容的命名方案将数据文件转换为对象文件:

代码语言:javascript
复制
$ 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组装):

代码语言:javascript
复制
    .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_size

xxd

一个更可移植的选择,不需要GNU objcopy,也不需要GNU,比如创建一个中间C文件并编译并链接它。例如,使用xxd

代码语言:javascript
复制
$ 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;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/233358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档