给定一个 ELF 二进制文件或共享对象,我如何才能最轻松地查看所需共享库的加载顺序?
它们是否按照列出的顺序加载readelf -d?
我有一个 elf 文件,我想知道是否可以获得一些有关可执行文件中使用变量(字符串)的信息。
如果我打印出 .elf 的字符串,我会发现一个有趣的字符串,我想知道它在哪个函数中使用,这是否可能?
谢谢你!
我正在尝试理解 ELF 中的重定位,但是我在处理这方面的文档时遇到了一些麻烦,因为它相当神秘。例如,重定位方程描述了 3 个参数:S、A 和 P。现在我知道 A 只是加数,它是用于帮助重定位计算的一些数字,而 S 是“索引位于的符号的值”搬迁条目”(与函数名称相同,对吧?)但是 P 呢?手册将其描述为“存储单元被重新安置的位置”,但这到底是什么意思呢?
\n\n我刚刚找到一个例子来说明这一点:假设我们有 2 个目标文件,obj1.o和obj2.o。第一个引用了一个名为 foo() 的函数,该函数位于obj2.o内部。
\n\nobjdump -d obj1.o产生:
\n\nDisassembly of section .text:\n00000000 <func>:\n0: 55 push %ebp\n1: 89 e5 mov %esp,%ebp\n3: 83 ec 08 sub $0x8,%esp\n6: e8 fc ff ff ff call 7 <func+0x7>\nb: c9 leave \nc: c3 ret \nRun Code Online (Sandbox Code Playgroud)\n\n现在,readelf表明这是一个R_386_PC32重定位,其方程为:S + A - P。
\n\n将这两个文件组合起来生成完整的可执行文件re located …
我正在尝试了解有关 ELF 格式的更多信息,特别是节标题,我刚刚遇到了以下内容:
Elf32_Ehdr *ehdr = (Elf32_Ehdr*)p;
Elf32_Shdr *shdr = (Elf32_Shdr *)(p + ehdr->e_shoff);
int shnum = ehdr->e_shnum;
Elf32_Shdr *sh_strtab = &shdr[ehdr->e_shstrndx];
const char *const sh_strtab_p = p + sh_strtab->sh_offset;
for (int i = 0; i < shnum; ++i) {
printf("%2d: %4d '%s'\n", i, shdr[i].sh_name,
sh_strtab_p + shdr[i].sh_name);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,我知道这基本上是遍历节表并打印节名称,但我仍然对sh_offset字段感到困惑。它到底有什么作用?如果e_shstrndx已经指向字符串表部分,为什么我们需要sh_offset?
ELF 文件包含两个结构来处理重定位:
Elf64_Rel:
typedef struct {
Elf64_Addr r_offset;
Uint64_t
r_info;
} Elf64_Rel;
Run Code Online (Sandbox Code Playgroud)
和Elf64_Rela:
typedef struct {
Elf64_Addr r_offset;
uint64_t
r_info;
int64_t
r_addend;
} Elf64_Rela;
Run Code Online (Sandbox Code Playgroud)
我想看一下重定位条目,但我不确定该使用哪一个。手册页对此非常含糊。每种都有具体的用途吗?
我已经阅读了这篇文章,并且了解段包含运行时信息和封装部分,其中包含链接信息。但是,我仍然很困惑为什么这些术语在这两本书中似乎可以互换使用。
\n\n《Shellcoder 手册》
\n\n\n\n\n接下来,信息从程序\xe2\x80\x99s可执行文件加载到新创建的地址空间。段共有三种类型:.text、\n.bss 和.data。.text 段被映射为只读,而\n .data 和 .bss 是可写的。.bss 和.data 段是为全局变量保留的。.data 段包含静态初始化数据,.bss 段包含未初始化数据。最后一段 .text 保存程序指令。
\n
《专业汇编语言》
\n\n\n\n所有汇编语言程序都需要文本部分。这是在可执行程序中声明指令代码的地方。data 和 bss 部分是可选的,但经常在程序中使用。数据部分声明使用初始值声明的数据元素。这些数据元素在汇编语言程序中用作变量。bss 部分声明用零(或 null)值实例化的数据元素。这些数据元素最常用作汇编语言程序中的缓冲区。
\n
考虑这段代码:
int foo();
int main() {
foo();
while(1){}
}
Run Code Online (Sandbox Code Playgroud)
int foo()在共享对象中实现。
编译此代码会gcc -o main main.c -lfoo -nostdlib -m32 -O2 -e main --no-pic -L./shared给出以下diasm:
$ objdump -d ./main
./main: file format elf32-i386
Disassembly of section .plt:
00000240 <.plt>:
240: ff b3 04 00 00 00 pushl 0x4(%ebx)
246: ff a3 08 00 00 00 jmp *0x8(%ebx)
24c: 00 00 add %al,(%eax)
...
00000250 <foo@plt>:
250: ff a3 0c 00 00 00 jmp *0xc(%ebx)
256: 68 00 00 00 …Run Code Online (Sandbox Code Playgroud) 我正在设计自己的 RISC-V CPU,并且已经能够实现一些指令代码。
我已经安装了 RV32I 版本的 GCC 编译器,因此现在可以使用汇编器riscv32-unknown-elf-as了。
我正在尝试仅用一条指令来汇编一个程序:
# simple.asm
add x5,x6,x7
Run Code Online (Sandbox Code Playgroud)
我使用汇编器编译它,然后使用以下命令运行 objdump:
# simple.asm
add x5,x6,x7
Run Code Online (Sandbox Code Playgroud)
这会打印出以下内容:
new: file format elf32-littleriscv
Disassembly of section .text:
00000000 <.text>:
0: 007302b3 add t0,t1,t2
Disassembly of section .riscv.attributes:
00000000 <.riscv.attributes>:
0: 2d41 jal 0x690
2: 0000 unimp
4: 7200 flw fs0,32(a2)
6: 7369 lui t1,0xffffa
8: 01007663 bgeu zero,a6,0x14
c: 00000023 sb zero,0(zero) # 0x0
10: 7205 lui tp,0xfffe1
12: 3376 fld ft6,376(sp)
14: 6932 flw fs2,12(sp)
16: …Run Code Online (Sandbox Code Playgroud) 我试图nm在 C 中重新创建该命令的行为,尽管我成功获取了符号和部分的名称,但我发现我的版本中出现了一些额外的名称。
$> ./my_nm -a obj.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 n .note.GNU-stack
0000000000000000 r .note.gnu.property
0000000000000000 d .rela.eh_frame
0000000000000000 d .rela.text
0000000000000000 t .text
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T elf64_syms
0000000000000000 a elf64_syms.c
U malloc
Run Code Online (Sandbox Code Playgroud)
$> nm -a obj.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 n .note.GNU-stack
0000000000000000 r .note.gnu.property
0000000000000000 t .text
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T elf64_syms
0000000000000000 a elf64_syms.c
U …Run Code Online (Sandbox Code Playgroud) 我在尝试理解ELF(可执行文件和链接格式)时遇到了这个问题.
我遵循的步骤
main.c含
int main(int argc, char **argv){ return 0;}gcc main.ca.out,它运行没有任何问题.所以构建很好.readelf工具检索ELF信息,在机器字段中放置Advanced Micro Devices X86-64.这部分困惑了我.所以我检查了文件头a.out,它是按照ELF-64规范(Value 64 - EM_X86_64).
有人会关心解释,为什么在linux上以64位模式构建的可执行文件显示机器类型为AMD x86 64?