ELF 文件头
关于 elf 文件头的一个简单问题,我似乎找不到任何关于如何在 elf 头中添加/更改字段的有用信息。 我希望能够更改幻数并向标题添加构建日期,以及可能的其他一些内容。
据我了解,链接器创建标头信息,但我在 LD 脚本中没有看到任何引用它的内容(尽管我是 ld 脚本的新手)。
我正在使用 gcc 并为 ARM 构建。
谢谢!
更新:
- 好吧,也许我的第一个问题应该是:是否可以在链接时创建/编辑头文件?
A quick question about elf file headers, I can't seem to find anything useful on how to add/change fields in the elf header. I'd like to be able to change the magic numbers and to add a build date to the header, and probably a few other things.
As I understand it the linker creates the header information, but I don't see anything in the LD script that refers to it (though i'm new to ld scripts).
I'm using gcc and building for ARM.
thanks!
Updates:
- ok maybe my first question should be: is it possible to create/edit the header file at link time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我不知道可以执行此操作的链接描述文件命令,但您可以使用 objcopy 命令在链接后执行此操作。 --add-section 选项可用于向 ELF 文件添加包含任意数据的部分。 如果 ELF 标头不包含您想要的字段,只需创建一个新部分并将它们添加到那里。
I don't know of linker script commands that can do this, but you can do it post-link using the objcopy command. The --add-section option can be used to add a section containing arbitrary data to the ELF file. If the ELF header doesn't contain the fields you want, just make a new section and add them there.
此链接(teensy elf 二进制) 是某人对另一个问题的回答,但它更详细地探讨了 ELF 标头的复杂性。
This link (teensy elf binary) was someone's answer to another question, but it goes into the intricacies of an ELF header in some detail.
您可以创建一个包含版本号等信息字段的目标文件,并链接该文件,以便它们包含在生成的 ELF 二进制文件中。
例如
,作为构建过程的一部分,您可以生成 - 例如 -
info.c
,其中包含一个或多个#ident
指令:编译它:
检查信息是否包含:
或者,您可以使用 objdump -s --section .comment info.o 。 请注意,默认情况下,GCC 也会编写自己的注释。
链接 ELF 可执行文件后检查信息:
注释部分
在 C 翻译单元中使用
#ident
基本上等同于在汇编程序文件中创建.comment
部分。 示例:使用不常见的节名称也可以(例如
.section .blahblah
)。 但是.comment
被其他工具使用和理解。 GNU as 也理解.ident
指令,这就是 GCC 将#ident
翻译成的内容。使用符号
对于您还想从 ELF 可执行文件本身访问的数据,您需要创建符号。
Objcopy
假设您想要包含存储在数据文件中的一些魔法字节:
使用 GNU objcopy:
检查符号:
示例用法:
将所有内容链接在一起:
GNU ld
GNU ld 还能够使用 objcopy 兼容的命名方案将数据文件转换为目标文件:
与 objcopy 不同,它将符号放入
.data
而不是中。不过,rodata
部分(参见objdump -h magic.o
)。incbin
如果 GNU objcopy 不可用,可以使用 GNU as
.incbin
指令 创建对象文件(使用 gcc -c incbin.s 进行汇编):xxd
一种更可移植的替代方案,不需要 GNU objcopy 也不需要 GNU 创建中间 C 文件并编译和链接它。 例如 xxd:
You can create an object file with informative fields like a version number and link that file such that they are included in the resulting ELF binary.
Ident
For example, as part of you build process, you can generate - say -
info.c
that contains one or more#ident
directives:Compile it:
Check if the information is included:
Alternatively, you can use
objdump -s --section .comment info.o
. Note that GCC also writes its own comment, by default.Check the information after linking an ELF executable:
Comment Section
Using
#ident
in a C translation unit is basically equivalent to creating a.comment
section in an assembler file. Example:Using an uncommon section name works, as well (e.g.
.section .blahblah
). But.comment
is used and understood by other tools. GNU as also understands the.ident
directive, and this is what GCC translates#ident
to.With Symbols
For data that you also want to access from the ELF executable itself you need to create symbols.
Objcopy
Say you want to include some magic bytes stored in a data file:
Convert into a object file with GNU objcopy:
Check for the symbols:
Example usage:
Link everything together:
GNU ld
GNU ld is also able to turn data files into object files using an objcopy compatible naming scheme:
Unlike objcopy, it places the symbols into the
.data
instead of the.rodata
section, though (cf.objdump -h magic.o
).incbin
In case GNU objcopy isn't available, one can use the GNU as
.incbin
directive to create the object file (assemble withgcc -c incbin.s
):xxd
A more portable alternative that doesn't require GNU objcopy nor GNU as is to create an intermediate C file and compile and link that. For example with xxd:
我相当确定足够复杂的 ld 脚本可以完成您想要的操作。 但是,我不知道该怎么做。
另一方面, elfsh 可以轻松地对 elf 对象进行各种操作,所以尝试一下吧。
I'm fairly sure that a sufficiently complex ld script can do what you want. However, I have no idea how.
On the other hand, elfsh can easily do all sorts of manipulations to elf objects, so give it a whirl.
你也许可以使用 libmelf,这是一个关于 freshmeat 的死项目,但可以从 LOPI 获得 - http ://www.ipd.bth.se/ska/lopi.html
否则,您可以获取规范并自己(覆盖)编写标头。
You might be able to use libmelf, a dead project on freshmeat, but available from LOPI - http://www.ipd.bth.se/ska/lopi.html
Otherwise, you can get the spec and (over)write the header yourself.
我已经有一段时间没有这样做了,但是你不能将任意数据附加到可执行文件中吗? 如果您总是附加固定大小的数据,那么恢复您附加的任何内容将是微不足道的。 可变大小不会更困难。 可能比弄乱 elf 标头并可能破坏您的可执行文件更容易。
I haven't done this in awhile, but can't you just append arbitrary data to an executable. If you always append fixed-size data it would be trivial to recover anything you append. Variable size wouldn't be much harder. Probably easier than messing w/ elf headers and potentially ruining you executables.
我没有读完这本书,但是 iirc John Levine 的链接器和加载器你需要能够做到这一点的血淋淋的细节。
I didn't finish the book but iirc Linkers and Loaders by John Levine had the gory details that you would need to be able to do this.
在 Solaris 中,您可以使用 elfedit 但我认为您实际上是在寻求 Linux 的解决方案。 Linux 不是 Unix :P
In Solaris you can use elfedit but I think you are really asking solutions for Linux. Linux Is Not UniX :P
在 Linux 控制台中:
$ man ld
$ ld --verbose
HTH
In Linux Console:
$ man ld
$ ld --verbose
HTH