91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

windows PE文件與Linux ELF文件概述

發布時間:2021-09-18 09:42:57 來源:億速云 閱讀:276 作者:chen 欄目:網絡管理

本篇內容主要講解“windows PE文件與Linux ELF文件概述”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“windows PE文件與Linux ELF文件概述”吧!

1. windows PE文件與Linux ELF文件概述

      在windows中可執行文件是pe文件格式,Linux中可執行文件是ELF文件,其文件格式是ELF文件格式,在Linux下的ELF文件除了可執行文件(Excutable File),可重定位目標文件(RellocatableObject File)、共享目標文件(SharedObject File)、核心轉儲文件(CoreDump File)也都是ELF格式文件。

2. ELF文件結構分析

2.1 ELF文件查看

        使用Linux下專用工具——readelf   來查看elf文件信息

windows PE文件與Linux ELF文件概述

        查看readelf中的源碼

windows PE文件與Linux ELF文件概述

        一個典型的ELF文件大致的結構如下:

ELF文件大致的結構
文件頭(ELF Header)
程序頭表(Program Header Table)
代碼段(.text)
數據段(.data)
bss段(.bss)
段表字符串表(.shstrtab)
段表(Section Header Table)
符號表(.symtab)
字符串表(.strtab)
重定位表(.rel.text)
重定位表(.rel.data)

2.2 FLF文件組成

2.2.1文件頭

      用于記錄一個ELF文件的信息(多少位?能夠運行的CPU平臺是什么?程序的入口點在哪里)

      查看ELF頭

windows PE文件與Linux ELF文件概述

在readelf的源碼中變量類型Elf_Internal_Ehdr_,定義在internal頭文件中

#define
EI_NIDENT        16                /* Size of e_ident[] */


 


typedef
struct elf_internal_ehdr {


  unsigned char                e_ident[EI_NIDENT];   /* ELF "magic
number" */


  bfd_vma                      e_entry;              /* Entry point virtual address */


  bfd_size_type                e_phoff;              /* Program header table file offset */


  bfd_size_type                e_shoff;              /* Section header table file offset */


  unsigned long                e_version;            /* Identifies object file version */


  unsigned long                e_flags;              /* Processor-specific flags */


  unsigned short               e_type;               /* Identifies object file type */


  unsigned short               e_machine;            /* Specifies required architecture */


  unsigned int                 e_ehsize;             /* ELF header size in bytes */


  unsigned int                 e_phentsize;          /* Program header table entry size */


  unsigned int                 e_phnum;       
      /* Program header table
entry count */


  unsigned int                 e_shentsize;           /* Section header table entry size */


  unsigned int                 e_shnum;       
       /* Section header table
entry count */


  unsigned int                 e_shstrndx;            /* Section header string table index */


}
Elf_Internal_Ehdr;

      在Linux自帶的頭文件中查看,源碼文件頭的結構中一共有14個字段,對應到文件16進制中。

windows PE文件與Linux ELF文件概述

#define EI_NIDENT (16) 
typedef struct
{
  unsigned char     e_ident[EI_NIDENT];        /* Magic number and other info */
  Elf32_Half        e_type;                    /* Object file type */
  Elf32_Half        e_machine;                 /* Architecture */
  Elf32_Word        e_version;                 /* Object file version */
  Elf32_Addr        e_entry;                   /* Entry point virtual address */
  Elf32_Off         e_phoff;                   /* Program header table file offset */
  Elf32_Off         e_shoff;                   /* Section header table file offset */
  Elf32_Word        e_flags;                   /* Processor-specific flags */
  Elf32_Half        e_ehsize;                  /* ELF header size in bytes */
  Elf32_Half        e_phentsize;               /* Program header table entry size */
  Elf32_Half        e_phnum;                   /* Program header table entry count */
  Elf32_Half        e_shentsize;               /* Section header table entry size */
  Elf32_Half        e_shnum;                   /* Section header table entry count */
  Elf32_Half        e_shstrndx;                /* Section header string table index */
} Elf32_Ehdr;

2.2.2 程序頭表

      記錄了每個Segment的相關信息,比如類型、對應文件的偏移、大小、屬性等。

      程序頭表和段頭表相對獨立,它們是由ELF文件頭統一管理,程序頭表管理ELF文件加載后,ELF文件內可加載段到內存映像的映射關系,一般只有可執行文件中,包含程序頭表。程序頭表包含多個程序頭表項,程序頭表描述的對象稱為“Segment”,Segment描述的是ELF文件加載后的數據塊,段(Section)描述的是ELF文件加載前的數據塊。一般來說,來說兩者會存在一定的對應關系,比如代碼段.text的加載信息保存在程序頭表項對應存放代碼的Segment中,數據段.data的加載信息保存在程序頭表項對應存放數據的Segment中。有時候為了簡化程序頭表項的個數,會把同類型的多個段,設置整個ELF文件作為一個Segment。

windows PE文件與Linux ELF文件概述

程序頭表的數據結構

/* Program segment header.  */
typedef struct
{
  Elf32_Word        p_type;                 /* Segment type */
  Elf32_Off         p_offset;               /* Segment file offset  Segment對應的內容在文件的偏移*/
  Elf32_Addr        p_vaddr;                /* Segment virtual address Segment在內存中的線性地址*/
  Elf32_Addr        p_paddr;                /* Segment physical address */
  Elf32_Word        p_filesz;               /* Segment size in file */
  Elf32_Word        p_memsz;                /* Segment size in memory */
  Elf32_Word        p_flags;                /* Segment flags */
  Elf32_Word        p_align;                /* Segment alignment */
} Elf32_Phdr;
 
#define        PT_NULL           0                /* Program header table entry unused */
#define        PT_LOAD           1                /* Loadable program segment */
#define        PT_DYNAMIC        2                /* Dynamic linking information */
#define        PT_INTERP         3                /* Program interpreter */
#define        PT_NOTE           4                /* Auxiliary information */
#define        PT_SHLIB          5                /* Reserved */
#define        PT_PHDR           6                /* Entry for header table itself */
#define        PT_TLS            7                /* Thread-local storage segment */
#define        PT_NUM            8                /* Number of defined types */

p_flag權限屬性標志

 說明    
1可執行PE_X
2可寫PE_W
3可讀PE_R

2.2.3 區段頭表

      用于記錄ELF文件的主要的數據

      查看區段

windows PE文件與Linux ELF文件概述

區段表頭的數據結構:

typedef struct
{
  Elf32_Word        sh_name;                /* Section name (string tbl index) */ 
  Elf32_Word        sh_type;                /* Section type */
  Elf32_Word        sh_flags;               /* Section flags */
  Elf32_Addr        sh_addr;                /* Section virtual addr at execution */
  Elf32_Off         sh_offset;              /* Section file offset */
  Elf32_Word        sh_size;                /* Section size in bytes */
  Elf32_Word        sh_link;                /* Link to another section */
  Elf32_Word        sh_info;                /* Additional section information */
  Elf32_Word        sh_addralign;           /* Section alignment */
  Elf32_Word        sh_entsize;             /* Entry size if section holds table */
} Elf32_Shdr;

區段頭表一共有10個字段,含義如下:

      (1)sh_name段名,是一個是一個4字節的偏移,記錄了段名字符串在段表字符串表(“.shstrtab”段)內的偏移。段表字符串并非表的形式,而是一個文件塊,保存了所有的段表字符串內容,存儲在“.shstrtab”的段中,根據“.shstrtab”的偏移,加上sh_name便可以訪問到每個段對應的段名字符串。

windows PE文件與Linux ELF文件概述

windows PE文件與Linux ELF文件概述

        起始地址是000017ac,第一個段表項全0,sh_name在段表項中的偏移是001b,由上圖可以得到“.shstrtab”段的偏移是0016ae,

所以,計算段名的偏移應該是0x0000001b+ 0x000016ae = 0x000016c9

根據計算的結果,查看0x000016c9處:

windows PE文件與Linux ELF文件概述

      (2)sh_type,表示段的類型。段的類型有很多,常見的有SHT_PROGBITS,表示程序數據,SHT_SYMTAB表示符號表,SHT_STRTAB表示字符串表,還有專門存放構造函數數組段SHT_INIT_ARRAY,析構函數數組段SHT_FINI_ARRAY。

      a   .txt 代碼段

      b   .data 數據段

      c   .radata記錄常量數據

      d   .symtab記錄符號表(相當于PE文件的導出表)的數據

      e   .strtab 串表段

      f   .shstrtab 有段表 字符串表段

      g   .rel .plt記錄某個區段的重定位內容(相當于PE文件的導入表)

對應的宏如下:

/* Legal values for sh_type (section type).  */
 
#define SHT_NULL              0       /* Section header table entry unused */
#define SHT_PROGBITS          1       /* Program data */
#define SHT_SYMTAB            2       /* Symbol table */
#define SHT_STRTAB            3       /* String table */
#define SHT_RELA              4       /* Relocation entries with addends */
#define SHT_HASH              5       /* Symbol hash table */
#define SHT_DYNAMIC           6       /* Dynamic linking information */
#define SHT_NOTE              7       /* Notes */
#define SHT_NOBITS            8       /* Program space with no data (bss) */
#define SHT_REL               9       /* Relocation entries, no addends */
#define SHT_SHLIB             10      /* Reserved */
#define SHT_DYNSYM            11      /* Dynamic linker symbol table */
#define SHT_INIT_ARRAY        14      /* Array of constructors */
#define SHT_FINI_ARRAY        15      /* Array of destructors */
#define SHT_PREINIT_ARRAY     16      /* Array of pre-constructors */

      (3)sh_flags,表示段標志,記錄段的屬性。其中0表示默認屬性,1表示段可寫,取值位SHF_WRITE。2表示段加載后需要為之分配內存空間,取值為SHF_ALLOC。4表示可執行,取值為SHF_EXECINSTR,段標志屬性可以疊加。

      (4)sh_addr,表示段加載后的線性地址

      (5)sh_offset,表示段在文件內的偏移,根據此偏移可確定段的位置,讀取段的內容。

      (6)sh_size,表示段的大小,單位為字節。需要注意的是,如果段類型為SHT_NOBITS,段內沒有數據,那么段的大小并非指文件塊的大小,而是指段加載后占用內存的大小。

windows PE文件與Linux ELF文件概述

      (7~8)sh_link和sh_info表示段的鏈接信息,一般用于描述符號表段和重定位表段的鏈接信息。對于符號表段(SHT_SYMTAB),sh_link記錄的是符號表使用的串表所在段(一般是,.strtab)對應段表項在段表內的索引。

windows PE文件與Linux ELF文件概述

      sh_info記錄的是符號表最后一個局部符號的符號表項在符號表內的索引加1,一般恰好是第一個全局符號的符號表項索引,這樣可以幫助連接器更快的地定位到第一個全局符號。如下圖:段中符號表段的信息sh_info,剛好是局部符號+1的索引。

windows PE文件與Linux ELF文件概述

      對于重定位表表段(段類型是SHT_REL),sh_link記錄重定位所作用的符號表段表項早段內的索引,而sh_info記錄重定位所作用的段對應的段表項在段表中的索引。

windows PE文件與Linux ELF文件概述

sh_type  sh_link  sh_info  
SHT_DYNAMIC此表項中條目所用到的字符串表在段表中的索引 
SHT_HASH此哈希表所適用的符號表的段表索引 
SHT_REL相關符號表的段表索引重定位所使用的段的段表索引
SHT_RELA相關聯的字符串表的段表索引最后一個局部符號的符號表索引值+1
其它SHN_UNDEF0

      (9)sh_addralign,表示段的對齊方式,對齊規則為 sh_offset %sh_addralign = 0,即段的文件偏移必須是sh_addralign的整數倍,sh_addralign的取值必須是2的整數倍,入1、2、4、8等。

對齊值對齊方式說明
0無對齊要求 
1無對齊要求
4對齊4滿足sh_iffset % 4 = 0
16對齊16滿足sh_iffset % 16 = 0
32對齊32滿足sh_iffset % 32 = 0

windows PE文件與Linux ELF文件概述

      (10) sh_entsize,一般用于保存注入符號表段,重定位表段時,表示段內保存表的表項大小。例如符號表段“.symtab”內保存的符號表的表項大小為sizeof(Elf32_sym)= 16字節,重定位表段“.rel.plt”內保存的重定位表的表項大小為sizeof(Elf32_rel)= 8字節。

2.2.4 ELF符號表(Symbol Table)

      ELF文件的符號表保存了程序中的符號信息,包括程序中的文件名、函數名、全局變量名等,符號表一般保存在名為“.strtab”的段內,該段對應段表項的類型為SHT_SYMTAB。符號表包含多個符號表項,每個符號表項記錄了符號的名稱、位置、類型等信息。

符號表象的數據結構:

typedef struct
{
  Elf32_Word           st_name;         /* Symbol name (string tbl index) */
  Elf32_Addr           st_value;        /* Symbol value */
  Elf32_Word           st_size;         /* Symbol size */
  unsigned char        st_info;         /* Symbol type and binding */
  unsigned char        st_other;        /* Symbol visibility */
  Elf32_Section        st_shndx;        /* Section index */
} Elf32_Sym;

windows PE文件與Linux ELF文件概述

2.2.5 ELF重定位表(Reloc Table

       

      重定位表常見于可重定位目標文件內,對于靜態鏈接生成的可可執行文件,一般不包括重定位表,動態鏈接生成的可執行文件暫時不討論。重定位表一般保存在以名為“.rel”開頭的段內,該段對應段表項的類型為SHT_REL,ELF文件需要重定位的段,一般都對應一個重定位表,比如代碼段“.txt”的重定位表保持在“.rel.text”內,數據段“.data”的重定位表保持在“.rel.data”內。

      重定位表包含多個重定位表項,每個重定位表項記錄一條重定位信息,包括重定位的符號、位置、類型等。

/* Relocation table entry without addend (in section of type SHT_REL).  */
 
typedef struct
{
  Elf32_Addr        r_offset;                /* Address */
  Elf32_Word        r_info;                  /* Relocation type and symbol index */
} Elf32_Rel;

windows PE文件與Linux ELF文件概述

2.2.6 ELF串表(String Table)

      ELF文件內的段表和符號表需要記錄段名和符號名,這些名稱都是字符串。然而,段表項和符號表項都是固定長度的數據結構,無法存儲不定長的字符串。因此FLE文件將名稱字符串內容集中存放在一個段內,稱為串表。這些段表項和符號表項只需記錄段名字符串或符號名字符串在對應串表項的位置即可。

      雖然存儲的字符串表的內容稱為串表,但是并非表的形式,而是一個文件區域。

windows PE文件與Linux ELF文件概述

到此,相信大家對“windows PE文件與Linux ELF文件概述”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绥德县| 宜丰县| 临湘市| 财经| 唐海县| 廊坊市| 肃宁县| 敦煌市| 湟源县| 榆中县| 中阳县| 新晃| 贵溪市| 博乐市| 铜梁县| 体育| 涞源县| 龙游县| 荥经县| 精河县| 哈尔滨市| 彭泽县| 岑巩县| 玛沁县| 邳州市| 黄浦区| 通化县| 东丰县| 营口市| 含山县| 扎鲁特旗| 济源市| 镇安县| 兴安盟| 达州市| 灵山县| 蓬莱市| 龙游县| 彰化市| 庄河市| 梁平县|