标签: elf

查找谁在 ELF 文件中使用符号

我有一个包含符号的大二进制文件。我可以在nm或 中看到符号objdump
我知道使用了该符号,否则链接器不会包含它(更准确地说,我知道使用了同一源文件中的某些符号)。
我试图找出它的使用方式。

如果引用是通过函数(例如函数调用函数,使用全局变量的函数),我可以使用objdump -rd反汇编文件并找到引用。
但是如果引用是由一个变量(例如一个全局指针初始化为指向某个变量),反汇编不会显示它。
我没有找到任何可以做到的方法。

这是一个演示它的示例。在这个例子中,很明显谁使用了x,但我不知道如何检查生成的二进制文件并找到它。

// x.c
int x = 3;

// main.c
extern int x;
static int *y = &x;
int main() { 
    return *y;
}

// Build process
gcc -o x.o -c x.c
ar r libx.a x.o
gcc -o main.o -c main.c
gcc -o main main.o -L. -lx
Run Code Online (Sandbox Code Playgroud)

c linux elf linkage

5
推荐指数
1
解决办法
1540
查看次数

ELF 中的 <.got> 部分是什么?

据我所知,PLT并且GOT是处理动态链接功能的部分。

如果代码调用printflibc 的函数,
1. 首先它调用PLTgetprintf的地址。
2. 并将此地址写入GOT部分。
3. 从第二次调用开始,代码使用编写的函数GOT

当我仔细查看 ELF 二进制文件时,
- 我发现PLTELF 中的section名称是<.plt>.
-GOT在 ELF 中部分的名称是<.got.plt>.

但是...... <.got>ELF中也有部分。
我无法理解如何使用此部分。



Q.<.got>节的用法是什么?部分有
什么区别?<.got><.got.plt>



PS 1. 这个<.got>部分非常小,(在我的示例二进制文件中它只包含 4byte。)
在这里我附上<.got>部分的IDA 视图:

.got:08049FFC ; ===========================================================================
.got:08049FFC
.got:08049FFC ; Segment type: Pure data
.got:08049FFC ; Segment permissions: Read/Write
.got:08049FFC _got            segment …
Run Code Online (Sandbox Code Playgroud)

binary x86 elf bin got

5
推荐指数
1
解决办法
2722
查看次数

GDB 符号从何而来?

当我将 Fedora 28 的/usr/bin/ls文件加载到 GDB 时,我可以访问符号abformat_init,即使它既不是字符串也不是二进制文件的符号表。

$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=d6d0ea6be508665f5586e90a30819d090710842f, stripped, too many notes (256)
$ readelf -S /usr/bin/ls | grep abformat
$ nm /usr/bin/ls
nm: /usr/bin/ls: no symbols
$ strings /usr/bin/ls | grep abformat
$ gdb /usr/bin/ls
[...]
Reading symbols from /usr/bin/ls...Reading symbols from /usr/bin/ls...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Missing separate debuginfos, use: dnf debuginfo-install …
Run Code Online (Sandbox Code Playgroud)

linux gdb symbols elf

5
推荐指数
1
解决办法
1297
查看次数

如何在 Linux 中创建静态链接位置无关的可执行 ELF?

我有一个独立的 Linux 独立 x86_64 hello world 工作岗位:

电源

.text
.global _start
_start:
asm_main_after_prologue:
    /* Write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    lea msg(%rip), %rsi  /* buffer */
    mov $len, %rdx  /* len */
    syscall

    /* Exit */
    mov $60, %rax   /* syscall number */
    mov $0, %rdi    /* exit status */
    syscall
msg:
    .ascii "hello\n"
len = . - msg
Run Code Online (Sandbox Code Playgroud)

我可以组装和运行:

as -o main.o main.S
ld -o main.out main.o
./main.out
Run Code Online (Sandbox Code Playgroud)

由于RIP …

linux gnu-assembler elf ld

5
推荐指数
1
解决办法
1921
查看次数

为什么独立的 C hello 程序在用作动态链接器时会崩溃

以下程序:

#include <stdio.h>

int main(int argc, char *argv[])
{
  for (int j = 0; j < argc; j++)
    printf("%d: %s\n", j, argv[j]);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

内置于静态链接的 PIE 中:

gcc -g -fpie main.c -static-pie -o ld.so
Run Code Online (Sandbox Code Playgroud)

工作正常:

$ ./ld.so foo bar
0: ./ld.so
1: foo
2: bar
Run Code Online (Sandbox Code Playgroud)

但是当我将该程序用作另一个程序的 ELF 解释器时:

$ gcc -g main.c -Wl,-I./ld.so -o a.out
Run Code Online (Sandbox Code Playgroud)

它像这样崩溃:

gdb -q ./a.out
(gdb) run
Starting program: /tmp/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7da84e2 in __ctype_init () at ctype-info.c:31
31 …
Run Code Online (Sandbox Code Playgroud)

gcc glibc elf dynamic-linking

5
推荐指数
1
解决办法
544
查看次数

什么是 *ABS* 部分以及何时使用?

// foo.c
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

当我编译上面的代码时,我注意到一些符号位于*ABS*

$ gcc foo.c
$ objdump -t a.out | grep ABS
0000000000000000 l    df *ABS*  0000000000000000              crtstuff.c
0000000000000000 l    df *ABS*  0000000000000000              foo.c
0000000000000000 l    df *ABS*  0000000000000000              crtstuff.c
0000000000000000 l    df *ABS*  0000000000000000              
Run Code Online (Sandbox Code Playgroud)

看起来它们是一些调试符号,但调试信息不​​是存储在类似.debug_info部分的地方吗?

根据man objdump

*ABS* 如果该部分是绝对的(即不与任何部分连接)

我不明白,因为这里没有给出例子。

这里的问题显示了一种有趣的方式来传递一些额外的符号*ABS*by --defsym。但我认为通过传递宏可能会更容易。

那么这个*ABS*部分是什么,什么时候有人会使用它?

编辑

绝对符号不会被重新定位,它们的虚拟地址(在您给出的示例中为 0000000000000000)是固定的。

我写了一个演示,但似乎可以修改绝对符号的地址。

$ gcc foo.c
$ objdump -t a.out | grep ABS
0000000000000000 l …
Run Code Online (Sandbox Code Playgroud)

c binary linker gcc elf

5
推荐指数
1
解决办法
1471
查看次数

在 AWS Lambda 上使用 libxmljs 的“无效 ELF 标头”

我有一个使用无服务器、express 和libxmljs(将 JavaScript 绑定到 libxml)的超级基本 AWS Lambda 函数:

代码

无服务器.xml:

service: xmltest

provider:
  name: aws
  runtime: nodejs10.x
  stage: dev
  region: us-east-1

functions:
  app:
    handler: index.handler
    events:
      - http: ANY /
      - http: 'ANY {proxy+}'

plugins:
  - serverless-offline
Run Code Online (Sandbox Code Playgroud)

索引.js:

const serverless = require('serverless-http');
const express = require('express');
const libxml = require("libxmljs");

const app = express();

app.use(express.json());

app.post('/lookup', async function (req, res) {
  res.send({result: "hello world"});
});

module.exports.handler = serverless(app);
Run Code Online (Sandbox Code Playgroud)

在本地工作但不在 AWS 上工作

当我在本地运行时:

$ curl -X POST http://localhost:3000/lookup -d …
Run Code Online (Sandbox Code Playgroud)

elf libxml2 amazon-web-services aws-lambda serverless-framework

5
推荐指数
1
解决办法
3532
查看次数

如何使用汇编制作小二进制文件?

我正在为我的某个项目编写一些汇编代码,我看到了一些有趣的东西。链接时二进制文件的大小是如此之大。所以我进行了测试和测试,即使使用尽可能少的代码行,输出 Elf 二进制文件也是如此之大。例如:

.section .text
.global _start
_start:
    movl $1,%eax
    movl $0,%ebx
    int $0x80
Run Code Online (Sandbox Code Playgroud)

组装和链接以上代码后,结果二进制文件超过 4kb!有趣的是,大多数二进制文件都填充了零。
我尝试了很多事情来找出没有成功的原因。
有人可以向我解释这里有什么问题吗?

我只是组装和链接文件:

.section .text
.global _start
_start:
    movl $1,%eax
    movl $0,%ebx
    int $0x80
Run Code Online (Sandbox Code Playgroud)

推荐任何形式的资源以供进一步阅读会很好。

你可能猜到了,我使用 64 位 GNU/Linux

谢谢。

assembly linker elf ld binutils

5
推荐指数
1
解决办法
183
查看次数

.plt .plt.got 有什么不同?

.plt: 在 REplt[n]可用段中,蹦床在0 之外运行,.got.plt 解析器链接在plt[0]

.got .got.plt : 在可读写段中,只需寻址

我从这篇文章中了解到:https : //eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/

问题

实际的 Linux shell 命令给了我不同的答案

$readelf -l /bin/bash
Run Code Online (Sandbox Code Playgroud)

读取精灵 -l 结果

got.plt 消失了,02 段中的 .plt.got 是什么?

我倾倒了两个部分(plt,plt.got)并得到了这个程序集

.plt 是我了解到的 plt: .plt 是我了解到的 plt

.plt.got ,这是做什么用的? .plt.got ,这是做什么用的

对不起,倾销不好,它是由

objcopy -O binary --only-section=.plt.got /bin/bash ./pltgot
objcopy -O binary --only-section=.plt /bin/bash ./plt
Run Code Online (Sandbox Code Playgroud)

问题

  1. .plt 和 .plt.got 有什么区别
  2. 为什么会发生这种差异?

assembly x86-64 matplotlib elf dynamic-linking

5
推荐指数
2
解决办法
1780
查看次数

“同一个库”的 dlopen 定义

根据dlopen(3) 手册页

如果使用 dlopen() 再次加载相同的库,则返回相同的文件句柄。

“同一个图书馆”是什么意思?相同的文件名?一样的路?同一个节点?同一个 SONAME?还有什么?这种行为如何与软链接交互?

假设我对 ELF so's 和主流 Linux 发行版(Debian / Arch / RHEL 系列)感兴趣。

示例后果:

  • 如果“相同的库”意味着“相同的 SONAME”,那么我可以两次加载具有不同名称的相同文件,并且只能获得一个句柄。如果“相同的库”意味着“相同的文件名”,那么我可能会因符号冲突而变得一团糟。
  • 如果符号链接被跟踪回文件并且“相同的库”意味着“相同的文件名”,那么到一个文件的多个符号链接是可以的,否则如果使用符号链接的文件名,事情又会是一团糟。
  • 如果“相同的库”意味着“相同的路径”并且文件存在两条路径(例如,带有硬链接),则事情一团糟,否则如果“相同的库”意味着“相同的 inode”,一切都可以。

linux elf dlopen

5
推荐指数
1
解决办法
180
查看次数