标签: elf

如何查看共享库加载的顺序

给定一个 ELF 二进制文件或共享对象,我如何才能最轻松地查看所需共享库的加载顺序?

它们是否按照列出的顺序加载readelf -d

linker shared-libraries elf

3
推荐指数
2
解决办法
6599
查看次数

ELF 文件 - 获取字符串使用位置的函数

我有一个 elf 文件,我想知道是否可以获得一些有关可执行文件中使用变量(字符串)的信息。

如果我打印出 .elf 的字符串,我会发现一个有趣的字符串,我想知道它在哪个函数中使用,这是否可能?

谢谢你!

debugging execute elf

3
推荐指数
1
解决办法
1939
查看次数

ELF - 了解 R_386_PC32 重定位

我正在尝试理解 ELF 中的重定位,但是我在处理这方面的文档时遇到了一些麻烦,因为它相当神秘。例如,重定位方程描述了 3 个参数:S、A 和 P。现在我知道 A 只是加数,它是用于帮助重定位计算的一些数字,而 S 是“索引位于的符号的值”搬迁条目”(与函数名称相同,对吧?)但是 P 呢?手册将其描述为“存储单元被重新安置的位置”,但这到底是什么意思呢?

\n\n

我刚刚找到一个例子来说明这一点:假设我们有 2 个目标文件,obj1.oobj2.o。第一个引用了一个名为 foo() 的函数,该函数位于obj2.o内部。

\n\n

objdump -d obj1.o产生:

\n\n
Disassembly 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   \n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,readelf表明这是一个R_386_PC32重定位,其方程为:S + A - P

\n\n

将这两个文件组合起来生成完整的可执行文件re located …

x86 elf

3
推荐指数
1
解决办法
1476
查看次数

ELF - sh_offset 字段的用途是什么?

我正在尝试了解有关 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

3
推荐指数
1
解决办法
1023
查看次数

ELF 文件中的重定位加数 - Elf64_Rel 与 Elf64_Rela?

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)

我想看一下重定位条目,但我不确定该使用哪一个。手册页对此非常含糊。每种都有具体的用途吗?

elf

3
推荐指数
1
解决办法
1962
查看次数

部分与段?

我已经阅读了这篇文章,并且了解段包含运行时信息和封装部分,其中包含链接信息。但是,我仍然很困惑为什么这些术语在这两本书中似乎可以互换使用。

\n\n

《Shellcoder 手册》

\n\n
\n

接下来,信息从程序\xe2\x80\x99s可执行文件加载到新创建的地址空间。段共有三种类型:.text、\n.bss 和.data。.text 段被映射为只读,而\n .data 和 .bss 是可写的。.bss 和.data 段是为全局变量保留的。.data 段包含静态初始化数据,.bss 段包含未初始化数据。最后一段 .text 保存程序指令。

\n
\n\n

《专业汇编语言》

\n\n
\n

所有汇编语言程序都需要文本部分。这是在可执行程序中声明指令代码的地方。data 和 bss 部分是可选的,但经常在程序中使用。数据部分声明使用初始值声明的数据元素。这些数据元素在汇编语言程序中用作变量。bss 部分声明用零(或 null)值实例化的数据元素。这些数据元素最常用作汇编语言程序中的缓冲区。

\n
\n

assembly elf

3
推荐指数
1
解决办法
2298
查看次数

为什么 gcc 会在显然不需要的时候生成 PLT?

考虑这段代码:

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)

linux x86 assembly elf dynamic-linking

3
推荐指数
1
解决办法
2307
查看次数

裸机 RISC-V CPU - 处理器如何知道从哪个地址开始获取指令?

我正在设计自己的 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)

assembly cpu-architecture elf riscv riscv32

3
推荐指数
2
解决办法
2344
查看次数

为什么 nm 隐藏 .o 文件中的 .rela.eh_frame 和 .rela.text ?

我试图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)

c elf relocation nm

3
推荐指数
1
解决办法
159
查看次数

为什么linux上以64位模式构建的可执行文件显示机器类型为AMD x86 64?

我在尝试理解ELF(可执行文件和链接格式)时遇到了这个问题.

我遵循的步骤

  1. 写了一个简单的应用程序. main.cint main(int argc, char **argv){ return 0;}
  2. 使用gcc在linux环境下编译.(完成英特尔笔记本电脑)最简单的命令可能 gcc main.c
  3. 现在,当我跑步时a.out,它运行没有任何问题.所以构建很好.
  4. 我使用readelf工具检索ELF信息,在机器字段中放置Advanced Micro Devices X86-64.这部分困惑了我.

所以我检查了文件头a.out,它是按照ELF-64规范(Value 64 - EM_X86_64).

有人会关心解释,为什么在linux上以64位模式构建的可执行文件显示机器类型为AMD x86 64

linux makefile elf

2
推荐指数
1
解决办法
634
查看次数