标签: position-independent-code

STM32,位置无关代码 - 不在GOT中的函数指针?

我需要一个在STM32F401上工作的位置无关代码(PIC).但是我对指向例如struct中使用的函数的指针有问题.

简短的例子:

struct process {
  struct process *next;
  const char *name;
  PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t));
  struct pt pt;
  unsigned char state, needspoll;
};

process etimer_process...

static void call_process(struct process *p, process_event_t ev, process_data_t data) {
  int ret;
  ret = p->thread(&p->pt, ev, data);
}
Run Code Online (Sandbox Code Playgroud)

反汇编后:

Disassembly of section .data:
   ...
 20000768 <etimer_process>:
 20000768:  00000000    andeq   r0, r0, r0
 2000076c:  0803b134    stmdaeq r3, {r2, r4, r5, r8, ip, sp, pc}
 20000770:  08027435    stmdaeq r2, {r0, r2, r4, r5, sl, ip, …
Run Code Online (Sandbox Code Playgroud)

gcc arm stm32 position-independent-code

7
推荐指数
1
解决办法
790
查看次数

RISCV - 跳转指令与 PC 有何关系?

在 RISC-V 非特权规范 V20191213 中,说明了以下内容(第 21 页)

无条件跳转指令均使用 PC 相对寻址来帮助支持位置无关代码。

查看JALR指令的定义,

间接跳转指令JALR(跳转链接寄存器)采用I型编码。通过将符号扩展的 12 位 I 立即数与寄存器 rs1 相加,然后将结果的最低有效位设置为零来获得目标地址。

这个地址计算显然与PC无关那么,为什么规范声称所有跳转指令都使用 PC 相对寻址呢?

另外,PC 相对寻址如何支持位置无关代码?难道不应该是完全相反的吗?

assembly instruction-set cpu-architecture riscv position-independent-code

7
推荐指数
1
解决办法
1万
查看次数

如何强制gcc直接在PIC代码中调用函数?

考虑以下功能:

extern void test1(void);
extern void test2(void) {
    test1();
}
Run Code Online (Sandbox Code Playgroud)

这是gcc -fpic在amd64 Linux上生成的代码:

test2:
    jmp test1
Run Code Online (Sandbox Code Playgroud)

当我编译时-fpic,gcc显式调用PLT来启用符号插入:

test2:
    jmp test1@PLT
Run Code Online (Sandbox Code Playgroud)

然而,这对于与位置无关的代码并不是严格需要的,如果我不想支持,可能会被遗漏.如有必要,链接器仍然会将跳转目标重写为PLT符号.

如何在不更改源代码且不使编译代码不适合共享库的情况下,使函数调用直接转到其目标而不是通过PLT显式转换?

c x86 gcc position-independent-code plt

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

如何配置gcc默认使用-no-pie?

我想在Linux上编译以下程序:

    .global _start
    .text
_start:
    mov $1,   %rax
    mov $1,   %rdi
    mov $msg, %rsi
    mov $13,  %rdx
    syscall
    mov $60,  %rax
    xor %rdi, %rdi
    syscall
msg:
    .ascii "Hello World!\n"
Run Code Online (Sandbox Code Playgroud)

但是,它给了我以下链接器错误:

$ gcc -nostdlib hello.s
/usr/bin/ld: /tmp/ccMNQrOF.o: relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

我认为它不起作用的原因是 gcc-pie默认使用生成共享对象。因此,使用-no-pie修复它:

$ gcc -no-pie -nostdlib hello.s
$ ./a.out …
Run Code Online (Sandbox Code Playgroud)

configuration gcc gnu-assembler ld position-independent-code

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

两个进程如何共享同一个共享库?

我一直在努力更好地了解共享库的工作原理,但我无法围绕两件事进行思考。

1- 每个进程都有自己的虚拟内存空间和页表,因此如果共享库被加载到一个进程虚拟内存空间中,那么第二个进程如何访问该共享库,因为它不在其内存空间中?

2- 我知道只有文本部分是共享的,而全局数据不是,这怎么可能?我的理解是,对全局变量的每次引用都是通过全局偏移表(简称 GOT)完成的。所以,如果我有这行代码,x = glob那么这将大致等于mov eax,DWORD PTR [ecx-0x10]汇编中的东西,其中ecx用作 GOT 的基值。但如果是这种情况,那么很明显,无论哪个进程调用该行,它将始终访问相同的全局变量,其地址位于 GOT 中的偏移量 0x10。那么,如果两个进程使用引用相同 GOT 条目的相同文本部分,那么它们如何拥有不同的全局变量副本呢?

unix shared-libraries dynamic-linking position-independent-code got

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

为什么用-fpic和-pie编译的程序有重定位表?

如果使用以下命令编译一个简单的程序:

arm-none-eabi-gcc -shared -fpic -pie --specs=nosys.specs simple.c -o simple.exe
Run Code Online (Sandbox Code Playgroud)

并使用以下命令打印重定位条目:

arm-none-eabi-readelf simple.exe -r
Run Code Online (Sandbox Code Playgroud)

有一堆重定位条目部分(见下文)。

由于 -fpic / -pie 标志会导致编译器生成位置无关的可执行文件,因此我天真的(并且显然不正确)假设不需要重定位表,因为加载程序可以将可执行映像放置在任何地方而不会出现问题。那么为什么那里有一个重定位表,这是否表明代码实际上不是位置无关的?

Relocation section '.rel.dyn' at offset 0x82d4 contains 37 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
000084a8  00000017 R_ARM_RELATIVE   
000084d0  00000017 R_ARM_RELATIVE   
00008508  00000017 R_ARM_RELATIVE   
00008510  00000017 R_ARM_RELATIVE   
0000855c  00000017 R_ARM_RELATIVE   
00008560  00000017 R_ARM_RELATIVE   
00008564  00000017 R_ARM_RELATIVE   
00008678  00000017 R_ARM_RELATIVE   
0000867c  00000017 R_ARM_RELATIVE   
0000870c  00000017 R_ARM_RELATIVE   
00008710  00000017 R_ARM_RELATIVE   
00008714  00000017 R_ARM_RELATIVE   
00008718  00000017 R_ARM_RELATIVE   
00008978  00000017 R_ARM_RELATIVE   
000089dc  00000017 R_ARM_RELATIVE   
000089e0 …
Run Code Online (Sandbox Code Playgroud)

c gcc position-independent-code

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

如何找到PIE二进制文件的负载重定位?

我需要在运行的进程中获取堆栈的基地址。这将使我能够打印将由addr2line理解的原始堆栈跟踪(已剥离运行二进制文件,但addr2line可以访问符号)。我通过检查以下内容的elf标头成功做到了这一点argv[0]:我读取了入口点并将其从中减去&_start

#include <stdio.h>
#include <execinfo.h>
#include <unistd.h>
#include <elf.h>
#include <stdio.h>
#include <string.h>
void* entry_point = NULL;
void* base_addr = NULL;
extern char _start;

/// given argv[0] will populate global entry_pont
void read_elf_header(const char* elfFile) {
  // switch to Elf32_Ehdr for x86 architecture.
  Elf64_Ehdr header;
  FILE* file = fopen(elfFile, "rb");
  if(file) {
    fread(&header, 1, sizeof(header), file);
    if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
        printf("Entry point from file: %p\n", (void *) header.e_entry);
        entry_point = (void*)header.e_entry;
        base_addr = …
Run Code Online (Sandbox Code Playgroud)

c linux elf aslr position-independent-code

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

Why I cannot compile with -fPIE but can with -fPIC?

I have one interesting compilation problem. At first, please see code to be compiled.

$ ls
Makefile main.c sub.c sub.h
$ gcc -v
...
gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
Run Code Online (Sandbox Code Playgroud)
## Makefile
%.o: CFLAGS+=-fPIE #[2]

main.so: main.o sub.o
    $(CC) -shared -fPIC -o $@ $^
Run Code Online (Sandbox Code Playgroud)
$ ls
Makefile main.c sub.c sub.h
$ gcc -v
...
gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
Run Code Online (Sandbox Code Playgroud)
## Makefile
%.o: CFLAGS+=-fPIE #[2]

main.so: main.o sub.o
    $(CC) -shared -fPIC -o $@ $^
Run Code Online (Sandbox Code Playgroud)
//main.c
#include …
Run Code Online (Sandbox Code Playgroud)

c linux gcc fpic position-independent-code

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

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

为什么 gcc 会在没有标志 -fno-pie 的情况下生成奇怪的代码?

我试图在 gcc 中编译带有标志 -fno-pie 和不带的虚拟函数。

void dummy_test_entrypoint() { }
Run Code Online (Sandbox Code Playgroud)

当我在没有标志的情况下编译时。

gcc -m32 -ffreestanding -c test.c -o test.o
Run Code Online (Sandbox Code Playgroud)

我得到以下反汇编代码。

00000000 <dummy_test_entrypoint>:
0:  55                      push   ebp
1:  89 e5                   mov    ebp,esp
3:  e8 fc ff ff ff          call   4 <dummy_test_entrypoint+0x4>
8:  05 01 00 00 00          add    eax,0x1
d:  90                      nop
e:  5d                      pop    ebp
f:  c3                      ret    
Run Code Online (Sandbox Code Playgroud)

当我用标志编译时。

00000000 <dummy_test_entrypoint>:
0:  55                      push   ebp
1:  89 e5                   mov    ebp,esp
3:  90                      nop
4:  5d                      pop    ebp
5:  c3                      ret 
Run Code Online (Sandbox Code Playgroud)

我的问题。

它是什么??? …

x86 assembly gcc i386 position-independent-code

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