我想在特定部分的开头插入一些数据(或代码或符号)。
假设在<.got>节的开头插入数据0x11223344
。
# gcc -o test test.s
.global main
.section .got.plt
.byte 0x11, 0x22, 0x33, 0x44
main:
nop
但是,正如您所见,
编译后,数据将附加到<.got.plt>的 end 处。
Disassembly of section .got.plt:
080495dc <_GLOBAL_OFFSET_TABLE_>:
80495dc: f0 94 lock xchg %eax,%esp
80495de: 04 08 add $0x8,%al
...
80495e8: 86 82 04 08 11 22 xchg %al,0x22110804(%edx)
80495ee: 33 .byte 0x33
80495ef: 44 inc %esp
问题:
我可以在本节的开头插入数据(或代码或符号)吗?
( ..是否有任何编译选项或类似汇编程序指令的内容?)
答案 0 :(得分:1)
这是一个链接问题,而不是一个装配问题。
如果您要求GCC(或更好的ld
)显示带有-Wl,--verbose
的链接脚本,您会找到一行
.got.plt : { *(.got.plt) *(.igot.plt) }
指示链接程序按照遇到的顺序 提取所有.got.plt
部分。
通常,链接器将按通配符在链接期间显示的顺序放置文件和节。
来自here
由于您正在使用CRT进行编译,这意味着它具有自己的目标文件,因此您的目标文件将紧随其后。
我不知道此订购是标准化的还是在GCC的不同版本中进行了订购,我认为可以随时更改。
您应该能够确认在GCC的命令行中添加了-v
和-Wl,-M
;第一个将向您展示GCC如何调用链接器,对我来说是这样的:
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. /tmp/ccref9XH.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o
很难看到它,但是test.s
对象文件是/tmp/ccref9XH.o
(在完整输出中的上面几行汇编),并且一些CRT对象文件在传递之前先传递到collect2
。
第二个选项将显示输出和输入部分之间的映射:
.got.plt 0x0000000000601000 0x25
*(.got.plt)
.got.plt 0x0000000000601000 0x20 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o
0x0000000000601000 _GLOBAL_OFFSET_TABLE_
.got.plt 0x0000000000601020 0x5 /tmp/ccisjx2P.o
0x0000000000601024 main
首先显示crt1.o
的{{1}}部分(请注意,您在.got.plt
部分保留了main
)。
我没有找到令人满意的方法来克服这个问题。
一种可能是复制链接程序脚本,并将.got.plt
定义更改为以下内容:
.got.plt
然后您可以将数据放入.got.plt : { *(.got.plt.pre) *(.got.plt) *(.igot.plt) }
中(注意:未经测试)。
但这是可维护性的噩梦。
我正在尝试使用.got.plt.pre
中的--sort-section=name
,将ld
命令添加到链接描述文件中输入的每个通配符节中。
这应该根据“ 文件或节名称”对齐节。
经过几次尝试,我查看了源代码,它实际上只是部分名称,因此在这里没有用。
我已恢复为SORT
。
首先,必须使用--sort-section=alignment
将文件test.s
组装成目标文件。
这里的问题是使gcc -c test.s -o test.o
中的.plt.got
部分的对齐方式大于8(其他test.o
部分使用的对齐方式)。
我检查了.plt.got
,但是什么也没找到,也许有人会找到合适的命令?
我已经用十六进制编辑器为objcopy
文件打了补丁,使该部分对齐了32个字节。
然后调用test.o
会产生一个ELF,其中gcc -Wl,--sort-section=alignment test.o -o test
节位于其他节之前。
尽管这是一个麻烦的解决方案,尽管可以轻松开发一种工具来更改ELF截面对齐方式,但我希望找到一个现有的工具。
很抱歉,以上都不是您的问题的正确答案。