相关疑难解决方法(0)

70
推荐指数
2
解决办法
6万
查看次数

x86-64 Linux中不再允许32位绝对地址?

64位Linux默认使用小内存模型,它将所有代码和静态数据置于2GB地址限制之下.这可确保您可以使用32位绝对地址.较旧版本的gcc使用静态数组的32位绝对地址,以便为相对地址计算保存额外的指令.但是,这不再有效.如果我尝试在汇编中创建一个32位的绝对地址,我会收到链接器错误:"在创建共享对象时,不能使用".data"重定位R_X86_64_32S;使用-fPIC重新编译".当然,此错误消息具有误导性,因为我没有创建共享对象,-fPIC也没有帮助.到目前为止我发现的是:gcc版本4.8.5对静态数组使用32位绝对地址,gcc版本6.3.0不使用.版本5可能也没有.binutils 2.24中的链接器允许32位绝对地址,而2.28则不允许.

这种变化的后果是必须重新编译旧库并破坏传统汇编代码.

现在我想问一下:这个改变是什么时候做的?它在某处记录了吗?是否有一个链接器选项,使其接受32位绝对地址?

linux gcc x86-64 linker-errors relocation

21
推荐指数
1
解决办法
5787
查看次数

检查是否使用"-static"编译的二进制文件

我在linux中有一个二进制文件.如何检查是否已使用"-static"编译?

linux static gcc

11
推荐指数
3
解决办法
7457
查看次数

ELF 文件类型 - ET_EXEC 和 ET_DYN

好吧,据我所知ET_EXEC用于表示该文件是可执行文件,而ET_DYN表示该文件是一个共享库。所以可以肯定的是,我用 C 编写了一个简单的程序,但问题是readelf -h产生了以下内容:

ELF Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              DYN (Shared object file)
  .
  .
  .
Run Code Online (Sandbox Code Playgroud)

我认为这与我使用的编译器有关,所以我对/bin 中的一些实用程序做了同样的事情,但不幸的是得到了相同的结果。那么问题来了:为什么 readelf 将可执行文件识别为共享库?

x86 elf

6
推荐指数
1
解决办法
4714
查看次数

如何在 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
查看次数

在 Linux 中如何确定 PIE 可执行文件的文本部分的地址?

首先,我尝试对其进行一些逆向工程:

printf '
#include <stdio.h>
int main() {
    puts("hello world");
}
' > main.c
gcc -std=c99 -pie -fpie -ggdb3 -o pie main.c
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
readelf -s ./pie | grep -E 'main$'
gdb -batch -nh \
  -ex 'set disable-randomization off' \
  -ex 'start' -ex 'info line' \
  -ex 'start' -ex 'info line' \
  -ex 'set disable-randomization on' \
  -ex 'start' -ex 'info line' \
  -ex 'start' -ex 'info line' \
  ./pie \
;
Run Code Online (Sandbox Code Playgroud)

输出:

64: 000000000000063a    23 …
Run Code Online (Sandbox Code Playgroud)

linux glibc linux-kernel aslr position-independent-code

4
推荐指数
1
解决办法
1427
查看次数

为什么我的简单“main”程序的 ELF 标头说它是“DYN(共享目标文件)”而不是可执行文件?

这是一个非常简单的 C++ 程序:

// main.cpp
int main() {}
Run Code Online (Sandbox Code Playgroud)

Makefile生成以下命令来编译程序。

? make
g++ -O0 -fverbose-asm  -o main main.cpp
Run Code Online (Sandbox Code Playgroud)

我检查命令file以查看它是一个 ELF 可执行文件:

? file main
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=921d352e49a0e4262aece7e72418290189520782, for GNU/Linux 3.2.0, not stripped
Run Code Online (Sandbox Code Playgroud)

一切似乎都很好,直到我尝试检查 ELF 标头

? readelf -e main
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
...
  Type:                              DYN …
Run Code Online (Sandbox Code Playgroud)

c++ g++ elf readelf

4
推荐指数
1
解决办法
747
查看次数