标签: elf

将ELF文件的入口点计算为物理地址(从0开始的偏移量)

我正在构建一个 RISC-V 模拟器,它基本上将整个 ELF 文件加载到内存中。

到目前为止,我使用了 risc-v 基金会提供的预编译测试二进制文件,该二进制文件在本节的开头处方便地有一个入口点.text

例如:

> riscv32-unknown-elf-objdump ../riscv32i-emulator/tests/simple -d

../riscv32i-emulator/tests/simple:     file format elf32-littleriscv


Disassembly of section .text.init:

80000000 <_start>:
80000000:       0480006f                j       80000048 <reset_vector>
...
Run Code Online (Sandbox Code Playgroud)

进入这个项目时,我对 ELF 文件了解不多,所以我只是假设每个 ELF 的入口点与该部分的开头完全相同.text

当我编译自己的二进制文件时出现了问题,我发现实际的入口点并不总是与该部分的开头相同.text,但它可能位于其中的任何位置,如下所示:

> riscv32-unknown-elf-objdump a.out -d

a.out:     file format elf32-littleriscv


Disassembly of section .text:

00010074 <register_fini>:
   10074:       00000793                li      a5,0
   10078:       00078863                beqz    a5,10088 <register_fini+0x14>
   1007c:       00010537                lui     a0,0x10
   10080:       43850513                addi    a0,a0,1080 # 10438 <__libc_fini_array>
   10084:       3a00006f                j       10424 <atexit> …
Run Code Online (Sandbox Code Playgroud)

linux emulation elf virtual-memory riscv

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

.text 段大于可执行文件中的 .text 段。为什么?

我在 NASM 中有以下“uppercaser.asm”汇编程序,它将用户输入的所有小写字母转换为大写:

section .bss
    Buff resb 1

section .data

section .text
        global _start

_start:
        nop            ; This no-op keeps the debugger happy

Read:   mov eax,3      ; Specify sys_read call
        mov ebx,0      ; Specify File Descriptor 0: Standard Input
        mov ecx,Buff   ; Pass offset of the buffer to read to
        mov edx,1      ; Tell sys_read to read one char from stdin
        int 80h        ; Call sys_read

        cmp eax,0       ; Look at sys_read's return value in EAX
        je Exit         ; Jump …
Run Code Online (Sandbox Code Playgroud)

linux x86 assembly elf

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

C++ ctor问题(linux)

  • 环境:linux,用户空间应用程序通过g ++从几个C++文件创建(结果是ELF)

  • 遍历构造函数列表时出现问题(SIGSEGV)

    ( __CTOR_LIST__ )

(注意:通过此列表调用的代码是每个类的一种系统初始化, 而不是我编写的构造函数代码)

  • 当我正确理解每个编译单元(每个.o创建一个.cpp)创建一个条目
    __CTOR_LIST__ 
  • 当我通过程序通过GDB步进时,问题(SIGSEGV)不存在

  • 为了调试这个我正在寻找一种方法来在调用之前添加自己的代码

    "_do_global_ctors_aux"

有什么提示吗?

谢谢,

乌韦

c++ linux constructor elf segmentation-fault

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

ELF程序标题:MemSiz与FileSiz

readelf -l /bin/bash 给我这个:

程序标题:
  类型偏移VirtAddr PhysAddr
                 FileSiz MemSiz标志对齐
  PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8 RE 8
  INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001a 0x000000000000001a R 1
      [请求程序解释器:/lib/ld-linux-x86-64.so.2]
  加载0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000aeef4 0x00000000000aeef4稀土200000
  加载0x00000000000afde0 0x00000000006afde0 0x00000000006afde0
                 0x0000000000003cec 0x000000000000d3c8   读写200000
  动态0x00000000000afdf8 0x00000000006afdf8 0x00000000006afdf8
                 0x0000000000000200 0x0000000000000200读写8
  注意0x0000000000000254 0x0000000000400254 0x0000000000400254
                 0x0000000000000044 0x0000000000000044 R 4
  GNU_EH_FRAME 0x000000000009dbc0 0x000000000049dbc0 0x000000000049dbc0
                 0x0000000000002bb4 0x0000000000002bb4 R 4
  GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000读写8
  GNU_RELRO 0x00000000000afde0 0x00000000006afde0 0x00000000006afde0
                 0x0000000000000220 0x0000000000000220 R 1

为什么在某些细分市场中MemSiz不等于?包含但不包含的存储区应该怎么办?FileSizLOADMemSizFileSiz

linux elf memory-alignment readelf

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

为什么我在运行readelf -s时获得此输出

我有Linux内核并尝试使用objcopy工具生成ELF Header,下面是第一步

     objcopy -I binary -B i386 -O elf32-i386 --rename-section .data=.text linux_kernel.bin  main.o
Run Code Online (Sandbox Code Playgroud)

在此之后我想使用readelf -s main.o读取符号表,但是输出下面的奇怪符号

   Symbol table '.symtab' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
 0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
 1: 00000000     0 SECTION LOCAL  DEFAULT    1 
 2: 00000000     0 NOTYPE  GLOBAL DEFAULT    1 _binary_linux_kernel_bin_
 3: 004df650     0 NOTYPE  GLOBAL DEFAULT    1 _binary_linux_kernel_bin_
 4: 004df650     0 NOTYPE  GLOBAL DEFAULT  ABS _binary_linux_kernel_bin_
Run Code Online (Sandbox Code Playgroud)

现在应该可以看到像这样的符号

_binary_linux_kernel_bin_start
_binary_linux_kernel_bin__end
_binary_linux_kernel_bin_size
Run Code Online (Sandbox Code Playgroud)

任何人都可以让我知道我在哪里做错了吗?还是期待一个?

为什么我想看到正确的符号,因为必须做类似下面的事情

 --entry_point=_binary_linux_kernel_bin_start
Run Code Online (Sandbox Code Playgroud)

elf linux-kernel objcopy

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

访问C++程序的代码部分

根据我的理解,C/C++程序在内存中看起来像这样:

C程序的内存布局. 来源:互联网

我想知道以下内容:

  1. 我可以访问正在运行的程序的"文本部分"吗?通过访问我的意思是打印开始和结束地址并检查内容.
  2. 我可以在运行时将"文本部分"重定位到内存中的其他地址吗?

谢谢,

c c++ linux memory-management elf

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

二进制文件中cut和dd的结果不同

我的环境:

CentOS 6.5
Run Code Online (Sandbox Code Playgroud)

我需要提取ELF文件的一些部分.

当我使用dd如下命令时,我没有问题:

$dd if=a.out of=a.cut1 bs=1 skip=16    
Run Code Online (Sandbox Code Playgroud)

另一方面,当我cut按如下方式使用命令时,创建的文件的大小比我预期的要小得多:

$cut --bytes=16- a.out > a.cut2
Run Code Online (Sandbox Code Playgroud)


例如,我通过使用gcc(v.4.4.7)编译以下示例c程序来创建a.out:

#include <stdio.h>

int main()
{
    printf("Hello world\n");
}
Run Code Online (Sandbox Code Playgroud)

然后,我按上述执行ddcut命令,我有以下大小的文件:

a.out - 6415 bytes
a.cut1 - 6399 bytes
a.cut2 - 6356 bytes
Run Code Online (Sandbox Code Playgroud)

我想知道为什么cut命令减小了比我指定的更多的大小.

linux cut binaryfiles dd elf

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

c - 加载原始二进制文件

是否可以执行存储在char数组中的原始二进制文件?我尝试这样做:

#include "stdio.h"
int main(int argc, char **argv)
{
    FILE *f = fopen(argv[1],"r");
    if(!f)
        return 1;
    fseek(f,0,SEEK_END);
    long l=ftell(f);
    rewind(f);
    char *buf = malloc(l+1);
    fread(buf,1,l,f);
    fclose(f);
    void (*func)() = (void(*))buf;
    func();
}
Run Code Online (Sandbox Code Playgroud)

但它只给我的段错误.我正在研究自己的操作系统(从头开始),所以我摆脱了它们.

c operating-system elf

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

elf符号表中value列的含义

我有一个elf二进制文件,它具有以下dynsym符号表作为输出readelf:

Num:    Value          Size Type    Bind   Vis      Ndx Name
 0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
 1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
 2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
 3: 0000000000400440     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
 4: 0000000000400460     0 FUNC    GLOBAL DEFAULT  UND fgets@GLIBC_2.2.5 (2)
Run Code Online (Sandbox Code Playgroud)

value栏是什么意思?由于此表有400440for printf,这是否意味着动态链接器必须映射printf到该地址?如果是,这个值是如何决定的?是随机的吗?

编辑:另外,这是带有gcc的linux x86-64

c assembly elf

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

如何隔离两个同名的c ++类?

我有一个包含大量C++测试文件的项目.每个测试文件都声明一个这样的类:

// test1.cpp
...
class Foo { void bar() {...} };
...
Run Code Online (Sandbox Code Playgroud)

// test2.cpp
...
class Foo { void bar() {...} };
...
Run Code Online (Sandbox Code Playgroud)

等等.

在测试套件变得非常大并且Foo某些测试模块中的类内容变得不同之前,一切都很好.在联系方面出现问题.每个ELF文件中的类的方法被声明为公共弱(nm符号中的"W" )符号,并且它导致调用方法的错误实例,例如来自的tests1.cpp调用.Foo::bar()tests2.cpp

如何将一个实例class Foo与另一个实例隔离开来?

宣布课程__attributes__ ((visibility ("hidden")))没有帮助,符号仍然是公开的.

同样可以肯定的是我可以使用命名空间,但我更愿意避免使用此选项.

有任何想法吗?

c++ g++ elf

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