Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么ELF入口点0x8048000与"ld -e“选项不可更改?

为什么ELF入口点0x8048000与"ld -e“选项不可更改?
EN

Stack Overflow用户
提问于 2011-11-13 18:25:59
回答 1查看 8K关注 0票数 10

跟踪Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?Why do virtual memory addresses for linux binaries start at 0x8048000?,为什么我不能让ld使用与默认ld -e不同的入口点?

如果这样做,我要么得到一个返回代码139的segmentation fault,即使是在默认入口点关闭的地址。为什么?

编辑:

我会提出更具体的问题:

代码语言:javascript
运行
AI代码解释
复制
        .text
        .globl _start    
_start:
        movl   $0x4,%eax        # eax = code for 'write' system call   
        movl   $1,%ebx          # ebx = file descriptor to standard output
        movl   $message,%ecx    # ecx = pointer to the message
        movl   $13,%edx         # edx = length of the message
        int    $0x80            # make the system call
        movl   $0x0,%ebx        # the status returned by 'exit'
        movl   $0x1,%eax        # eax = code for 'exit' system call
        int    $0x80            # make the system call
        .data
        .globl message
message:        
        .string "Hello world\n" # The message as data

如果我用as program.s -o program.o编译它,然后将它静态地链接到ld -N program.o -o programreadelf -l program显示0x0000000000400078作为文本段的VirtAddr0x400078作为入口点。运行时,打印“”。

但是,当我试图链接到ld -N -e0x400082 -Ttext=0x400082 program.o -o program (移动文本段和入口点4字节)时,程序将是killed。用readelf -l检查它现在显示了LOAD类型的两个不同的头,一个在0x0000000000400082,一个在0x00000000004000b0

当我尝试0x400086时,它都能工作,而且只有一个LOAD部分。

  1. 这是怎么回事?
  2. ,我可以选择哪个内存地址,哪些是我不能选择的,为什么?

谢谢你。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-13 21:41:34

为什么我不能让ld使用与默认的ld -e不同的入口点?

你当然可以。这是:

代码语言:javascript
运行
AI代码解释
复制
int foo(int argc, char *argv[]) { return 0; }
代码语言:javascript
运行
AI代码解释
复制
gcc main.c -Wl,-e,foo

不起作用,因为执行不是从main开始的。它从_start开始,它是从crt0.o (glibc的一部分)链接起来的,并安排诸如动态链接等的事情来正确地启动。通过将_start重定向到foo,您已经绕过了所有所需的glibc初始化,因此无法工作。

但是,如果您不需要动态链接,并且愿意做glibc通常为您做的事情,那么您可以随意命名入口点。示例:

代码语言:javascript
运行
AI代码解释
复制
#include <syscall.h>

int foo()
{
  syscall(SYS_write, 1, "Hello, world\n", 13);
  syscall(SYS_exit, 0);
}
代码语言:javascript
运行
AI代码解释
复制
gcc t.c -static -nostartfiles -Wl,-e,foo && ./a.out
Hello, world

哦,这个问题的标题和你的实际问题不匹配(坏主意(TM))。

要回答标题中的问题,您肯定可以更改可执行文件链接到的地址。默认情况下,您将获得0x8048000加载地址(仅以32位为单位;64位默认值为0x400000)。

通过将0x80000添加到链接行中,您可以轻松地将其更改为例如-Wl,-Ttext-segment=0x80000

更新:

,但是,当我试图链接到ld -N -e0x400082 -Ttext=0x400082 program.o -o程序(将文本段和入口点移动4个字节)时,程序将被终止。

不可能在不违反Ttext节对齐约束(即4)的情况下将0x400082分配给.text。必须在至少4字节的边界上保持.text地址对齐(或更改.text所需的对齐方式)。

当我将起始地址设置为0x400078、0x40007c、0x400080、0x400084、.、0x400098并使用GNU 2.20.1时,程序就可以工作了。

但是,当我使用binutils的当前CVS快照时,该程序工作于0x400078、0x40007c、0x400088、0x40008c,并因0x400080、0x400084、0x400090、0x400094、0x400098而被杀死。这可能是链接器中的一个bug,或者我违反了其他一些约束(我看不出是哪个)。

在这一点上,如果您真的感兴趣,我建议下载二进制文件源代码,构建ld,并找出究竟是什么原因导致它创建两个PT_LOAD段而不是一个。

更新2:

强制新的区段与重叠的LMA。

阿!这就意味着你需要把.data移开。这使得一个工作的可执行文件:

代码语言:javascript
运行
AI代码解释
复制
ld -N -o t t.o -e0x400080 -Ttext=0x400080 -Tdata=0x400180
票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8116648

复制
相关文章
【Android 逆向】ELF 文件格式 ( ELF 程序头入口大小 | ELF 程序头入口个数 | ELF 文件节区头入口大小 | ELF 文件节区头入口个数 | 字符表序号 )
ELF 文件头 第 42 ~ 43 字节 : ELF 程序头入口大小 ; 一般是 32 字节 ;
韩曙亮
2023/03/29
1K0
【Android 逆向】ELF 文件格式 ( ELF 程序头入口大小 | ELF 程序头入口个数 | ELF 文件节区头入口大小 | ELF 文件节区头入口个数 | 字符表序号 )
程序一定要从main函数开始运行吗?
每个目标文件都有好多个段,目标文件在被链接成可执行文件时,输入目标文件中的各个段如何被合并到输出文件?
程序员小猿
2021/01/19
1.3K0
程序一定要从main函数开始运行吗?
gcc -E 选项
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面. 例子用法: gcc -E hello.c > pianoapan.txt gcc -E hello.c | more 慢慢看吧,一个hello word 也要与处理成800行的代码
Java架构师必看
2021/03/22
9680
写一个操作系统_08 内核与C语言
我们开发用户应用程序的时候,有标准库可以用,最典型的就是GUN C库,标准库一般是系统调用的封装,表面上是通过标准库访问系统资源,实际上是通过系统调用实现的。Linux的系统调用一般是先往eax寄存器写入系统调用号,然后通过0x80中断来实现。中断向量号为0x80称为系统中断门,更多的中断参考中断描述符表。
changan
2020/11/04
8280
动态链接的步骤与实现
我们知道动态链接器本身也是一个共享对象,但是事实上它有一些特殊性。对于普通共享对象文件来说,它的重定位工作由动态链接器来完成。他也可以依赖其他共享对象,其中的被依赖共享对象由动态链接器负责链接和装载。可是对于动态链接器来说,它的重定位工作由谁来完成?它是否可以依赖于其他共享对象?
233333
2019/05/25
1.4K0
只有170字节,最小的64位Hello World程序这样写成
机器之心转载 作者:CJ Ting 最简单的 C 语言 Hello World 程序,底层到底发生了什么?如何编写出最小的 64 位 Hello World 程序? Hello World 应该是每一位程序员的启蒙程序,出自于 Brian Kernighan 和 Dennis Ritchie 的一代经典著作 The C Programming Language。 // hello.c#include <stdio.h>int main() { printf("hello, world\n"
机器之心
2023/03/29
5450
只有170字节,最小的64位Hello World程序这样写成
BUUCTF 刷题笔记——PWN 2
先验文件,本题文件为 32 为可执行文件,保护约等于没开。值得注意的是,该文件又是静态链接,因此又可以直接调用一些未被调用过的函数来解题,比如老朋友 mprotect() 函数。
h-t-m
2023/03/10
1.5K0
BUUCTF 刷题笔记——PWN 2
吴章金: 如何创建一个*可执行*的共享库
license: "cc-by-nc-nd-4.0" description: "本文手把手指导如何创建一个可以执行的共享目标文件"
Linux阅码场
2019/11/10
1.2K0
Linux共享库、静态库、动态库详解
1. 介绍 使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程
sunsky
2020/08/20
9K0
Linux共享库、静态库、动态库详解
含大量图文解析及例程 | Linux下的ELF文件、链接、加载与库(中)
可执行文件的装载 进程和装载的基本概念的介绍 程序(可执行文件)和进程的区别 程序是静态的概念,它就是躺在磁盘里的一个文件。 进程是动态的概念,是动态运行起来的程序。 现代操作系统如何装载可执行文件 给进程分配独立的虚拟地址空间 将可执行文件映射到进程的虚拟地址空间(mmap) 将CPU指令寄存器设置到程序的入口地址,开始执行 可执行文件在装载的过程中实际上如我们所说的那样是映射的虚拟地址空间,所以可执行文件通常被叫做映像文件(或者Image文件)。 可执行ELF文件的两种视角 可执行ELF格式具有不寻常的
刘盼
2022/08/26
3.4K0
含大量图文解析及例程 | Linux下的ELF文件、链接、加载与库(中)
ROP的基本原理和实战教学,看这一篇就够了!
ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。通过上一篇文章栈溢出漏洞原理详解与利用,我们可以发现栈溢出的控制点是ret处,那么ROP的核心思想就是利用以ret结尾的指令序列把栈中的应该返回EIP的地址更改成我们需要的值,从而控制程序的执行流程。
Java程序猿
2023/02/21
3.4K0
linux ldd命令源代码,Linux中ldd命令的用法详解[通俗易懂]
Linux中ldd命令主要用于查看程式运行所需的共享库,那么ldd命令具体要如何使用呢?下面小编就给大家介绍下Linux下ldd命令的使用方法,感兴趣的朋友一起来学习下吧。
全栈程序员站长
2022/08/23
3.5K0
linux ldd命令源代码,Linux中ldd命令的用法详解[通俗易懂]
实战操作系统 loader 编写(下) -- 进军内核
上一篇文章中,我们结合此前已经介绍过的一系列知识,成功的将内核载入内存并进入到了保护模式中。 实战操作系统 loader 编写(上) — 进入保护模式
用户3147702
2022/06/27
4090
实战操作系统 loader 编写(下) -- 进军内核
linux 编译汇编,linux下的汇编教程
第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协处理器等。初始化完成后就可以跳转到C代码执行。需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点(www.gnu.org)上下载有关规范。
全栈程序员站长
2022/06/28
3.5K0
Linux命令(65)——ld命令
ld命令是二进制工具集GNU Binutils的一员,是GNU链接器,用于将目标文件与库链接为可执行程序或库文件。
恋喵大鲤鱼
2019/04/18
17.8K0
nox&amp;CSAW部分pwn题解
暑假的时候遇到了一群一起学习安全的小伙伴,在他们的诱劝下,开始接触国外的CTF比赛,作为最菜的pwn选手就试着先打两场比赛试试水,结果发现国外比赛真有意思哎嘿。
安恒网络空间安全讲武堂
2018/10/25
1K0
写一个操作系统_14 C 链接与系统调用
链接可以指定最终生成的可执行文件的起始虚拟地址,我们 指定 内核加载到 0x1500的地方,内核初始化的时候跳转内核要跳转到这个地方。
changan
2020/11/04
4660
动态链接的相关结构
在了解了共享对象的绝对地址的引用问题后,我们基本上对动态链接的原理有了初步的了解,接下来的问题是整个动态链接具体的实现过程了。动态链接在不同的系统上有不同的实现方式。ELF的动态链接的实现方式会比PE的简单一点,在这里我们先介绍ELF的动态链接过程在LINUX下的实现,最后我们会专门的章节中介绍PE在Windows下的动态链接过程和它们的区别
233333
2019/05/25
1.7K0
nox&CSAW部分pwn题解
暑假的时候遇到了一群一起学习安全的小伙伴,在他们的诱劝下,开始接触国外的CTF比赛,作为最菜的pwn选手就试着先打两场比赛试试水,结果发现国外比赛真有意思哎嘿。
安恒网络空间安全讲武堂
2019/09/29
1.1K0
nox&CSAW部分pwn题解
ELF文件的加载过程(load_elf_binary函数详解)--Linux进程的管理与调度(十三)
一种是固定的、静态的连接,就是把需要用到的库函数的目标代码(二进制)代码从程序库中抽取出来,链接进应用软件的目标映像中;
233333
2018/10/09
8.5K0
ELF文件的加载过程(load_elf_binary函数详解)--Linux进程的管理与调度(十三)

相似问题

从加载器跳转到ELF的入口点

156

ELF入口点是否与通常的0x80*?为什么要这么做?

21

更改入口点“主”

25

入口点地址与原入口点有什么不同?

10

链接器(%ld) ELF问题

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档