• 怎样判定一个可执行文件是否是PIE 格式的文件


    /* ****************************************************    
        author: hjjdebug
        date:      2023年 10月 10日 星期二 11:03:52 CST
        description: 怎样判定可执行文件是否是PIE格式文件
    *******************************************************/

    PIE: Position Independent Executable, 位置无关可执行文件.

    表示可以把执行文件加载到任意位置都可执行.

    执行文件是PIE 需要两个条件:
    1. 其文件头类型是 DYN 类型
    2. 其动态节中有 DEBUG 符号名存在

    随便找一个我们自己编译的可执行文件,查看其文件头(file header)
    $ readelf -h multiview
    ELF 头:
      Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
      类别:                              ELF64
      数据:                              2 补码,小端序 (little endian)
      Version:                           1 (current)
      OS/ABI:                            UNIX - GNU
      ABI 版本:                          0
      类型:                              EXEC (可执行文件)  // 该行说明此文件不是PIE 格式文件,而是一般的EXEC文件
      系统架构:                          Advanced Micro Devices X86-64
      版本:                              0x1
      入口点地址:               0x431070
      程序头起点:          64 (bytes into file)
      Start of section headers:          20939056 (bytes into file)
      标志:             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         11
      Size of section headers:           64 (bytes)
      Number of section headers:         40
      Section header string table index: 39

    找一个PIE 格式文件,例如 /bin/ls 文件,

    查看其文件头: (改成英文输出了,怎样修改参考符录)
    $ readelf -h /bin/ls
    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)   // PIE 格式文件肯定是DYN 类型的
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x67d0
      Start of program headers:          64 (bytes into file)
      Start of section headers:          140224 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         13
      Size of section headers:           64 (bytes)
      Number of section headers:         30
      Section header string table index: 29

    查看其动态节
    $ readelf -d /bin/ls

    Dynamic section at offset 0x21a58 contains 28 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
     0x000000000000000c (INIT)               0x4000
     0x000000000000000d (FINI)               0x17574
     0x0000000000000019 (INIT_ARRAY)         0x22010
     0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
     0x000000000000001a (FINI_ARRAY)         0x22018
     0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
     0x000000006ffffef5 (GNU_HASH)           0x3a0
     0x0000000000000005 (STRTAB)             0x1190
     0x0000000000000006 (SYMTAB)             0x488
     0x000000000000000a (STRSZ)              1612 (bytes)
     0x000000000000000b (SYMENT)             24 (bytes)
     0x0000000000000015 (DEBUG)              0x0                 // PIE 格式文件动态节中包含DEBUG 符
     0x0000000000000003 (PLTGOT)             0x22c58
     0x0000000000000002 (PLTRELSZ)           2544 (bytes)
     0x0000000000000014 (PLTREL)             RELA
     0x0000000000000017 (JMPREL)             0x2cb8
     0x0000000000000007 (RELA)               0x1968
     0x0000000000000008 (RELASZ)             4944 (bytes)
     0x0000000000000009 (RELAENT)            24 (bytes)
     0x000000000000001e (FLAGS)              BIND_NOW
     0x000000006ffffffb (FLAGS_1)            Flags: NOW PIE
     0x000000006ffffffe (VERNEED)            0x18f8
     0x000000006fffffff (VERNEEDNUM)         1
     0x000000006ffffff0 (VERSYM)             0x17dc
     0x000000006ffffff9 (RELACOUNT)          193
     0x0000000000000000 (NULL)               0x0

    附录:  命令行下,怎样把中文输出改成英文输出?
    中文有一目了然的感觉, 但不适合某些脚本操作. 所以有时候还是要换成英文.
    按以下3步操作. (在ubuntu20 下操作的), 改动只需要一处.
    查看locale, 修改LANGUAGE,验证输出

    1. 查看locale,
    $ locale
    LANG=zh_CN.UTF-8
    LANGUAGE=zh_CN:en
    LC_CTYPE="zh_CN.UTF-8"
    LC_NUMERIC=zh_CN.UTF-8
    LC_TIME=zh_CN.UTF-8
    LC_COLLATE="zh_CN.UTF-8"
    LC_MONETARY=zh_CN.UTF-8
    LC_MESSAGES="zh_CN.UTF-8"
    LC_PAPER=zh_CN.UTF-8
    LC_NAME=zh_CN.UTF-8
    LC_ADDRESS=zh_CN.UTF-8
    LC_TELEPHONE=zh_CN.UTF-8
    LC_MEASUREMENT=zh_CN.UTF-8
    LC_IDENTIFICATION=zh_CN.UTF-8
    LC_ALL=


    2. 修改语言环境变量, 采用英文输出, 仅这里是需要修改的.
    $ LANGUAGE=en_US

    3. 重新查看执行文件信息, 已经按英文输出了,如下:
    $ readelf -h multiview
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - GNU
      ABI Version:                       0
      Type:                              EXEC (Executable file)  // 指示它是可运行文件, 不是PIE 形式
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x431070
      Start of program headers:          64 (bytes into file)
      Start of section headers:          20939056 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         11
      Size of section headers:           64 (bytes)
      Number of section headers:         40
      Section header string table index: 39

  • 相关阅读:
    健康管理信息系统
    CMU15445 (Fall 2019) 之 Project#4 - Logging & Recovery 详解
    自动监测站主要设备介绍(​​​​​​​雨水情遥测终端机)
    IDEA代码重构
    GitHub私有派生仓库(fork仓库) | 派生仓库改为私有
    嵌入式操作系统--机房管理系统
    二叉查找树(2)-二叉树-数据结构和算法(Java)
    Vue3简单项目流程分享——工作室主页
    GraphRAG学习小结(4)
    【无标题】
  • 原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/133742654