02 elf 的 binary 解析

news/2025/2/14 0:05:29/

前言

需求来自于 linux binary 的执行分析, 以及一些反编译工具的实现 

比如 readelf, hopper disassemble 什么的 

主要的目的是 更加详细了解 elf 的文件格式 

为 后续的一些 理解做准备 

elf 解析 

elf 文件主要分为 四个部分 

elfHeader, programHeaders, segments, segmentHeaders

我们这里查看的 elf 为一个  简单的 HelloWorld 生成的一个 elf 文件 

#include "stdio.h"int main(int argc, char** argv) {int x = 2;
int y = 3;
int z = x + y;printf(" x + y = %d\n ", z);}

readelf 解析如下 

root@ubuntu:~# readelf -a Test01Sum 
ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              EXEC (Executable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x400430Start of program headers:          64 (bytes into file)Start of section headers:          6624 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         9Size of section headers:           64 (bytes)Number of section headers:         31Section header string table index: 28Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .interp           PROGBITS         0000000000400238  00000238000000000000001c  0000000000000000   A       0     0     1[ 2] .note.ABI-tag     NOTE             0000000000400254  000002540000000000000020  0000000000000000   A       0     0     4[ 3] .note.gnu.build-i NOTE             0000000000400274  000002740000000000000024  0000000000000000   A       0     0     4[ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298000000000000001c  0000000000000000   A       5     0     8[ 5] .dynsym           DYNSYM           00000000004002b8  000002b80000000000000060  0000000000000018   A       6     1     8[ 6] .dynstr           STRTAB           0000000000400318  00000318000000000000003f  0000000000000000   A       0     0     1[ 7] .gnu.version      VERSYM           0000000000400358  000003580000000000000008  0000000000000002   A       5     0     2[ 8] .gnu.version_r    VERNEED          0000000000400360  000003600000000000000020  0000000000000000   A       6     1     8[ 9] .rela.dyn         RELA             0000000000400380  000003800000000000000018  0000000000000018   A       5     0     8[10] .rela.plt         RELA             0000000000400398  000003980000000000000030  0000000000000018  AI       5    24     8[11] .init             PROGBITS         00000000004003c8  000003c8000000000000001a  0000000000000000  AX       0     0     4[12] .plt              PROGBITS         00000000004003f0  000003f00000000000000030  0000000000000010  AX       0     0     16[13] .plt.got          PROGBITS         0000000000400420  000004200000000000000008  0000000000000000  AX       0     0     8[14] .text             PROGBITS         0000000000400430  0000043000000000000001b2  0000000000000000  AX       0     0     16[15] .fini             PROGBITS         00000000004005e4  000005e40000000000000009  0000000000000000  AX       0     0     4[16] .rodata           PROGBITS         00000000004005f0  000005f00000000000000012  0000000000000000   A       0     0     4[17] .eh_frame_hdr     PROGBITS         0000000000400604  000006040000000000000034  0000000000000000   A       0     0     4[18] .eh_frame         PROGBITS         0000000000400638  0000063800000000000000f4  0000000000000000   A       0     0     8[19] .init_array       INIT_ARRAY       0000000000600e10  00000e100000000000000008  0000000000000000  WA       0     0     8[20] .fini_array       FINI_ARRAY       0000000000600e18  00000e180000000000000008  0000000000000000  WA       0     0     8[21] .jcr              PROGBITS         0000000000600e20  00000e200000000000000008  0000000000000000  WA       0     0     8[22] .dynamic          DYNAMIC          0000000000600e28  00000e2800000000000001d0  0000000000000010  WA       6     0     8[23] .got              PROGBITS         0000000000600ff8  00000ff80000000000000008  0000000000000008  WA       0     0     8[24] .got.plt          PROGBITS         0000000000601000  000010000000000000000028  0000000000000008  WA       0     0     8[25] .data             PROGBITS         0000000000601028  000010280000000000000010  0000000000000000  WA       0     0     8[26] .bss              NOBITS           0000000000601038  000010380000000000000008  0000000000000000  WA       0     0     1[27] .comment          PROGBITS         0000000000000000  000010380000000000000035  0000000000000001  MS       0     0     1[28] .shstrtab         STRTAB           0000000000000000  000018d2000000000000010c  0000000000000000           0     0     1[29] .symtab           SYMTAB           0000000000000000  000010700000000000000648  0000000000000018          30    47     8[30] .strtab           STRTAB           0000000000000000  000016b8000000000000021a  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), l (large)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)There are no section groups in this file.Program Headers:Type           Offset             VirtAddr           PhysAddrFileSiz            MemSiz              Flags  AlignPHDR           0x0000000000000040 0x0000000000400040 0x00000000004000400x00000000000001f8 0x00000000000001f8  R E    8INTERP         0x0000000000000238 0x0000000000400238 0x00000000004002380x000000000000001c 0x000000000000001c  R      1[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]LOAD           0x0000000000000000 0x0000000000400000 0x00000000004000000x000000000000072c 0x000000000000072c  R E    200000LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e100x0000000000000228 0x0000000000000230  RW     200000DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e280x00000000000001d0 0x00000000000001d0  RW     8NOTE           0x0000000000000254 0x0000000000400254 0x00000000004002540x0000000000000044 0x0000000000000044  R      4GNU_EH_FRAME   0x0000000000000604 0x0000000000400604 0x00000000004006040x0000000000000034 0x0000000000000034  R      4GNU_STACK      0x0000000000000000 0x0000000000000000 0x00000000000000000x0000000000000000 0x0000000000000000  RW     10GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e100x00000000000001f0 0x00000000000001f0  R      1Section to Segment mapping:Segment Sections...00     01     .interp 02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 04     .dynamic 05     .note.ABI-tag .note.gnu.build-id 06     .eh_frame_hdr 07     08     .init_array .fini_array .jcr .dynamic .got Dynamic section at offset 0xe28 contains 24 entries:Tag        Type                         Name/Value0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]0x000000000000000c (INIT)               0x4003c80x000000000000000d (FINI)               0x4005e40x0000000000000019 (INIT_ARRAY)         0x600e100x000000000000001b (INIT_ARRAYSZ)       8 (bytes)0x000000000000001a (FINI_ARRAY)         0x600e180x000000000000001c (FINI_ARRAYSZ)       8 (bytes)0x000000006ffffef5 (GNU_HASH)           0x4002980x0000000000000005 (STRTAB)             0x4003180x0000000000000006 (SYMTAB)             0x4002b80x000000000000000a (STRSZ)              63 (bytes)0x000000000000000b (SYMENT)             24 (bytes)0x0000000000000015 (DEBUG)              0x00x0000000000000003 (PLTGOT)             0x6010000x0000000000000002 (PLTRELSZ)           48 (bytes)0x0000000000000014 (PLTREL)             RELA0x0000000000000017 (JMPREL)             0x4003980x0000000000000007 (RELA)               0x4003800x0000000000000008 (RELASZ)             24 (bytes)0x0000000000000009 (RELAENT)            24 (bytes)0x000000006ffffffe (VERNEED)            0x4003600x000000006fffffff (VERNEEDNUM)         10x000000006ffffff0 (VERSYM)             0x4003580x0000000000000000 (NULL)               0x0Relocation section '.rela.dyn' at offset 0x380 contains 1 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000600ff8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0Relocation section '.rela.plt' at offset 0x398 contains 2 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000601018  000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
000000601020  000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.Symbol table '.dynsym' contains 4 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__Symbol table '.symtab' contains 67 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1 2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2 3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3 4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4 5: 00000000004002b8     0 SECTION LOCAL  DEFAULT    5 6: 0000000000400318     0 SECTION LOCAL  DEFAULT    6 7: 0000000000400358     0 SECTION LOCAL  DEFAULT    7 8: 0000000000400360     0 SECTION LOCAL  DEFAULT    8 9: 0000000000400380     0 SECTION LOCAL  DEFAULT    9 10: 0000000000400398     0 SECTION LOCAL  DEFAULT   10 11: 00000000004003c8     0 SECTION LOCAL  DEFAULT   11 12: 00000000004003f0     0 SECTION LOCAL  DEFAULT   12 13: 0000000000400420     0 SECTION LOCAL  DEFAULT   13 14: 0000000000400430     0 SECTION LOCAL  DEFAULT   14 15: 00000000004005e4     0 SECTION LOCAL  DEFAULT   15 16: 00000000004005f0     0 SECTION LOCAL  DEFAULT   16 17: 0000000000400604     0 SECTION LOCAL  DEFAULT   17 18: 0000000000400638     0 SECTION LOCAL  DEFAULT   18 19: 0000000000600e10     0 SECTION LOCAL  DEFAULT   19 20: 0000000000600e18     0 SECTION LOCAL  DEFAULT   20 21: 0000000000600e20     0 SECTION LOCAL  DEFAULT   21 22: 0000000000600e28     0 SECTION LOCAL  DEFAULT   22 23: 0000000000600ff8     0 SECTION LOCAL  DEFAULT   23 24: 0000000000601000     0 SECTION LOCAL  DEFAULT   24 25: 0000000000601028     0 SECTION LOCAL  DEFAULT   25 26: 0000000000601038     0 SECTION LOCAL  DEFAULT   26 27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27 28: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c29: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__30: 0000000000400460     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones31: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones32: 00000000004004e0     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux33: 0000000000601038     1 OBJECT  LOCAL  DEFAULT   26 completed.759434: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtors_aux_fin35: 0000000000400500     0 FUNC    LOCAL  DEFAULT   14 frame_dummy36: 0000000000600e10     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_init_array_37: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Test01Sum.c38: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c39: 0000000000400728     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__40: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__41: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 42: 0000000000600e18     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_end43: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   22 _DYNAMIC44: 0000000000600e10     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_start45: 0000000000400604     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR46: 0000000000601000     0 OBJECT  LOCAL  DEFAULT   24 _GLOBAL_OFFSET_TABLE_47: 00000000004005e0     2 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini48: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab49: 0000000000601028     0 NOTYPE  WEAK   DEFAULT   25 data_start50: 0000000000601038     0 NOTYPE  GLOBAL DEFAULT   25 _edata51: 00000000004005e4     0 FUNC    GLOBAL DEFAULT   15 _fini52: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@@GLIBC_2.2.553: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_54: 0000000000601028     0 NOTYPE  GLOBAL DEFAULT   25 __data_start55: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__56: 0000000000601030     0 OBJECT  GLOBAL HIDDEN    25 __dso_handle57: 00000000004005f0     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used58: 0000000000400570   101 FUNC    GLOBAL DEFAULT   14 __libc_csu_init59: 0000000000601040     0 NOTYPE  GLOBAL DEFAULT   26 _end60: 0000000000400430    42 FUNC    GLOBAL DEFAULT   14 _start61: 0000000000601038     0 NOTYPE  GLOBAL DEFAULT   26 __bss_start62: 0000000000400526    67 FUNC    GLOBAL DEFAULT   14 main63: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses64: 0000000000601038     0 OBJECT  GLOBAL HIDDEN    25 __TMC_END__65: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable66: 00000000004003c8     0 FUNC    GLOBAL DEFAULT   11 _initVersion symbols section '.gnu.version' contains 4 entries:Addr: 0000000000400358  Offset: 0x000358  Link: 5 (.dynsym)000:   0 (*local*)       2 (GLIBC_2.2.5)   2 (GLIBC_2.2.5)   0 (*local*)    Version needs section '.gnu.version_r' contains 1 entries:Addr: 0x0000000000400360  Offset: 0x000360  Link: 6 (.dynstr)000000: Version: 1  File: libc.so.6  Cnt: 10x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 2Displaying notes found at file offset 0x00000254 with length 0x00000020:Owner                 Data size	DescriptionGNU                  0x00000010	NT_GNU_ABI_TAG (ABI version tag)OS: Linux, ABI: 2.6.32Displaying notes found at file offset 0x00000274 with length 0x00000024:Owner                 Data size	DescriptionGNU                  0x00000014	NT_GNU_BUILD_ID (unique build ID bitstring)Build ID: 676de8fa9bce03059433028da409bb25c151f668

hopper disassemble 解析如下, 截取片段 

相关实体

ElfFile 

/*** ElfFile** @author Jerry.X.He <970655147@qq.com>* @version 1.0* @date 2022-09-25 11:08*/
@Data
public class ElfFile implements Serializable {private ElfHeader header;private List<ElfProgramHeader> programHeaders;private Integer[] sectionBytes;private List<ElfSegment> segments;private List<ElfSectionHeader> sectionHeaders;@Field(sort = 0, name = "header", dataType = DataType.GENERIC_BEAN, desc = "header", version = {1})public ElfHeader getHeader() {return header;}@Field(sort = 10, name = "programHeaders", dataType = DataType.GENERIC_BEAN_COLLECTION, desc = "programHeaders", version = {1})public List<ElfProgramHeader> getprogramHeaders() {return programHeaders;}@Field(sort = 20, name = "sectionBytes", dataType = DataType.BYTE_ARRAY, desc = "sectionBytes", version = {1})public Integer[] getSectionBytes() {return sectionBytes;}public void setSegments(List<ElfSegment> segments) {this.segments = segments;}@Field(sort = 30, name = "sectionHeaders", dataType = DataType.GENERIC_BEAN_COLLECTION, desc = "sectionHeaders", version = {1})public List<ElfSectionHeader> getSectionHeaders() {return sectionHeaders;}}

ElfHeader

/*** ElfHeader** @author Jerry.X.He <970655147@qq.com>* @version 1.0* @date 2022-09-25 11:08*/
@Data
public class ElfHeader implements Serializable {private String ident;private Integer type;private Integer machine;private Integer version;private Long entry;private Long phoff;private Long shoff;private Integer flags;private Integer ehsize;private Integer phentsize;private Integer phnum;private Integer shentsize;private Integer shnum;private Integer shstrndx;private Long offsetInFile;@Field(sort = 0, name = "ident", dataType = DataType.CHARSET_ENCODING_WITH_FIXED_LEN_STRING, lengthInBytes = 16, desc = "ident", version = {1})public String getIdent() {return ident;}@Field(sort = 10, name = "type", dataType = DataType.UNSIGNED_WORD, desc = "type", bigEndian = false, version = {1})public Integer getType() {return type;}@Field(sort = 20, name = "machine", dataType = DataType.UNSIGNED_WORD, desc = "machine", bigEndian = false, version = {1})public Integer getMachine() {return machine;}@Field(sort = 30, name = "version", dataType = DataType.DWORD, desc = "version", bigEndian = false, version = {1})public Integer getVersion() {return version;}@Field(sort = 40, name = "entry", dataType = DataType.QWORD, desc = "entry", bigEndian = false, version = {1})public Long getEntry() {return entry;}@Field(sort = 50, name = "phoff", dataType = DataType.QWORD, desc = "phoff", bigEndian = false, version = {1})public Long getPhoff() {return phoff;}@Field(sort = 60, name = "shoff", dataType = DataType.QWORD, desc = "shoff", bigEndian = false, version = {1})public Long getShoff() {return shoff;}@Field(sort = 70, name = "flags", dataType = DataType.DWORD, desc = "flags", bigEndian = false, version = {1})public Integer getFlags() {return flags;}@Field(sort = 80, name = "ehsize", dataType = DataType.UNSIGNED_WORD, desc = "ehsize", bigEndian = false, version = {1})public Integer getEhsize() {return ehsize;}@Field(sort = 90, name = "phentsize", dataType = DataType.UNSIGNED_WORD, desc = "phentsize", bigEndian = false, version = {1})public Integer getPhentsize() {return phentsize;}@Field(sort = 100, name = "phnum", dataType = DataType.UNSIGNED_WORD, desc = "phnum", bigEndian = false, version = {1})public Integer getPhnum() {return phnum;}@Field(sort = 110, name = "shentsize", dataType = DataType.UNSIGNED_WORD, desc = "shentsize", bigEndian = false, version = {1})public Integer getShentsize() {return shentsize;}@Field(sort = 120, name = "shnum", dataType = DataType.UNSIGNED_WORD, desc = "shnum", bigEndian = false, version = {1})public Integer getShnum() {return shnum;}@Field(sort = 130, name = "shstrndx", dataType = DataType.UNSIGNED_WORD, desc = "shstrndx", bigEndian = false, version = {1})public Integer getShstrndx() {return shstrndx;}public JSONObject getHexRelated() {JSONObject result = new JSONObject();result.put("entry", "0x" + Long.toHexString(entry));result.put("phoff", "0x" + Long.toHexString(phoff));result.put("shoff", "0x" + Long.toHexString(shoff));return result;}public String toString() {return JSON.toJSONString(this);}}

ElfProgramHeader

/*** ElfPhHeader** @author Jerry.X.He* @version 1.0* @date 2022/9/27 10:18*/
@Data
public class ElfProgramHeader implements Serializable {private Integer type;private Integer flags;private Long offset;private Long vaddr;private Long paddr;private Long fileSz;private Long memSz;private Long align;private Long offsetInFile;@Field(sort = 0, name = "type", dataType = DataType.DWORD, desc = "type", bigEndian = false, version = {1})public Integer getType() {return type;}@Field(sort = 10, name = "flags", dataType = DataType.DWORD, desc = "flags", bigEndian = false, version = {1})public Integer getFlags() {return flags;}@Field(sort = 20, name = "offset", dataType = DataType.QWORD, desc = "offset", bigEndian = false, version = {1})public Long getOffset() {return offset;}@Field(sort = 30, name = "vaddr", dataType = DataType.QWORD, desc = "vaddr", bigEndian = false, version = {1})public Long getVaddr() {return vaddr;}@Field(sort = 40, name = "paddr", dataType = DataType.QWORD, desc = "paddr", bigEndian = false, version = {1})public Long getPaddr() {return paddr;}@Field(sort = 50, name = "fileSz", dataType = DataType.QWORD, desc = "fileSz", bigEndian = false, version = {1})public Long getFileSz() {return fileSz;}@Field(sort = 60, name = "memSz", dataType = DataType.QWORD, desc = "memSz", bigEndian = false, version = {1})public Long getMemSz() {return memSz;}@Field(sort = 70, name = "align", dataType = DataType.QWORD, desc = "align", bigEndian = false, version = {1})public Long getAlign() {return align;}public JSONObject getHexRelated() {JSONObject result = new JSONObject();result.put("offset", "0x" + Long.toHexString(offset));result.put("vaddr", "0x" + Long.toHexString(vaddr));result.put("paddr", "0x" + Long.toHexString(paddr));result.put("fileSz", "0x" + Long.toHexString(fileSz));result.put("memSz", "0x" + Long.toHexString(memSz));result.put("offsetInFile", "0x" + Long.toHexString(offsetInFile));return result;}public String toString() {return JSON.toJSONString(this);}}

ElfSegment

/*** ElfSegment** @author Jerry.X.He* @version 1.0* @date 2022/9/27 14:30*/
@Data
public class ElfSegment implements Serializable {protected String name;protected Integer[] bytes;protected Long offsetInFile;@Overridepublic String toString() {List<String> toStringNames = Arrays.asList(".comment", ".dynstr", ".shstrtab", ".strtab");if (toStringNames.contains(name)) {return name + " " + ElfFileCodec.formatOffset(getOffsetInFile()) + " " + new String(ElfFileCodec.transferBytes(bytes));}return name + " " + ElfFileCodec.formatOffset(getOffsetInFile()) + " " + ElfFileCodec.toString(bytes);}}

ElfSectionHeader 

/*** ElfPhHeader** @author Jerry.X.He* @version 1.0* @date 2022/9/27 10:18*/
@Data
public class ElfSectionHeader implements Serializable {private Integer name;private Integer type;private Long flags;private Long address;private Long offset;private Long size;private Integer link;private Integer info;private Long addrAlign;private Long entrySize;@Field(sort = 0, name = "name", dataType = DataType.DWORD, desc = "name", bigEndian = false, version = {1})public Integer getName() {return name;}@Field(sort = 10, name = "type", dataType = DataType.DWORD, desc = "type", bigEndian = false, version = {1})public Integer getType() {return type;}@Field(sort = 20, name = "flags", dataType = DataType.QWORD, desc = "flags", bigEndian = false, version = {1})public Long getFlags() {return flags;}@Field(sort = 30, name = "address", dataType = DataType.QWORD, desc = "address", bigEndian = false, version = {1})public Long getAddress() {return address;}@Field(sort = 40, name = "offset", dataType = DataType.QWORD, desc = "offset", bigEndian = false, version = {1})public Long getOffset() {return offset;}@Field(sort = 50, name = "size", dataType = DataType.QWORD, desc = "size", bigEndian = false, version = {1})public Long getSize() {return size;}@Field(sort = 60, name = "link", dataType = DataType.DWORD, desc = "link", bigEndian = false, version = {1})public Integer getLink() {return link;}@Field(sort = 70, name = "info", dataType = DataType.DWORD, desc = "info", bigEndian = false, version = {1})public Integer getInfo() {return info;}@Field(sort = 80, name = "addrAlign", dataType = DataType.QWORD, desc = "addrAlign", bigEndian = false, version = {1})public Long getAddrAlign() {return addrAlign;}@Field(sort = 90, name = "entrySize", dataType = DataType.QWORD, desc = "entrySize", bigEndian = false, version = {1})public Long getEntrySize() {return entrySize;}public JSONObject getHexRelated() {JSONObject result = new JSONObject();result.put("address", "0x" + Long.toHexString(address));result.put("offset", "0x" + Long.toHexString(offset));result.put("size", "0x" + Long.toHexString(size));result.put("entrySize", "0x" + Long.toHexString(entrySize));return result;}public String toString() {return JSON.toJSONString(this);}}

ElfSegment 有多类实现, 这里不一一列举 

ElfNoteSegment

/*** ElfInterpSegment** @author Jerry.X.He* @version 1.0* @date 2022/9/27 14:31*/
@Data
@ToString(callSuper = true)
public class ElfNoteSegment extends ElfSegment {private Integer nameSize;private Integer descSize;private Integer type;private String nameInNote;private Integer[] desc;}

ElfDynamicSymSegment

/*** ElfDynamicSymSegment** @author Jerry.X.He* @version 1.0* @date 2022/9/27 14:31*/
@Data
@ToString(callSuper = true)
public class ElfDynamicSymSegment extends ElfSegment {private List<ElfSymTabElement> list;@Field(sort = 0, name = "list", dataType = DataType.GENERIC_BEAN_COLLECTION, desc = "list", version = {1})public List<ElfSymTabElement> getList() {return list;}}/*** ElfSymTabElement** @author Jerry.X.He* @version 1.0* @date 2022/9/27 14:31*/
@Data
public class ElfSymTabElement {private String name;// 4bytesprivate Integer nameIdx;// 1byte, bind + typeprivate Integer info;// 1byte, 可见属性private Integer other;// segment idxprivate Integer shNIdx;// 8bytesprivate Long value;// 8bytesprivate Long size;@Field(sort = 0, name = "nameIdx", dataType = DataType.DWORD, desc = "nameIdx", bigEndian = false, version = {1})public Integer getNameIdx() {return nameIdx;}@Field(sort = 10, name = "info", dataType = DataType.BYTE, desc = "info", bigEndian = false, version = {1})public Integer getInfo() {return info;}@Field(sort = 20, name = "other", dataType = DataType.BYTE, desc = "other", bigEndian = false, version = {1})public Integer getOther() {return other;}@Field(sort = 30, name = "shNIdx", dataType = DataType.WORD, desc = "shNIdx", bigEndian = false, version = {1})public Integer getShNIdx() {return shNIdx;}@Field(sort = 40, name = "value", dataType = DataType.QWORD, desc = "value", bigEndian = false, version = {1})public Long getValue() {return value;}@Field(sort = 50, name = "size", dataType = DataType.QWORD, desc = "size", bigEndian = false, version = {1})public Long getSize() {return size;}@Overridepublic String toString() {JSONObject result = new JSONObject();result.put("name", name);result.put("info", info);result.put("other", other);result.put("shNIdx", shNIdx);result.put("value", Long.toHexString(value));result.put("size", size);return result.toString();}
}

相关实体的编码解码如下 

ElfFileCodec

/*** ElfFileCodec** @author Jerry.X.He* @version 1.0* @date 2022/9/27 10:23*/
public class ElfFileCodec extends AbstractCodec<ElfFile, ElfFile> {private AbstractCodec<ElfHeader, ElfHeader> headerCodec = CodecUtils.createCodecForClazz(ElfHeader.class, 1);private AbstractCodec<ElfProgramHeader, ElfProgramHeader> phHeaderCodec = CodecUtils.createCodecForClazz(ElfProgramHeader.class, 1);private AbstractCodec<ElfSectionHeader, ElfSectionHeader> sectionHeaderCodec = CodecUtils.createCodecForClazz(ElfSectionHeader.class, 1);private ElfSegmentCodec segmentCodec = new ElfSegmentCodec();@Overridepublic void encode(ElfFile entity, ByteBuf buf) {}@Overridepublic ElfFile decode(ByteBuf buf) {debugCurrentBufReaderIdx(buf, "before elf header codec");long offsetInFile = buf.readerIndex();ElfHeader header = headerCodec.decode(buf);header.setOffsetInFile(offsetInFile);debugCurrentBufReaderIdx(buf, "after elf header codec");int programNum = header.getPhnum(), sectionNum = header.getShnum();int sectionHeaderSz = sectionHeaderCodec.length() * sectionNum;debugCurrentBufReaderIdx(buf, "before program header codec");List<ElfProgramHeader> programHeaders = new ArrayList<>();for (int i = 0; i < programNum; i++) {offsetInFile = buf.readerIndex();ElfProgramHeader phHeader = phHeaderCodec.decode(buf);phHeader.setOffsetInFile(offsetInFile);programHeaders.add(phHeader);}debugCurrentBufReaderIdx(buf, "after program header codec");debugCurrentBufReaderIdx(buf, "before sections codec");int allRemaining = buf.readableBytes();int sectionBytesSz = allRemaining - sectionHeaderSz;ByteArrayWithExactlyLenCodec byteArrayCodec = new ByteArrayWithExactlyLenCodec(sectionBytesSz);Integer[] sectionBytesInInteger = byteArrayCodec.decode(buf);debugCurrentBufReaderIdx(buf, "after sections codec");debugCurrentBufReaderIdx(buf, "before section header codec");List<ElfSectionHeader> sectionHeaders = new ArrayList<>();for (int i = 0; i < sectionNum; i++) {sectionHeaders.add(sectionHeaderCodec.decode(buf));}debugCurrentBufReaderIdx(buf, "after section header codec");// section headersList<ElfSegment> segments = new ArrayList<>();for (ElfSectionHeader secHeader : sectionHeaders) {int sectionSize = secHeader.getSize().intValue();ByteArrayWithExactlyLenCodec sectionByteArrayCodec = new ByteArrayWithExactlyLenCodec(sectionSize);Integer[] sectionBytes = new Integer[]{};if (secHeader.getOffset() > 0) {buf.readerIndex(secHeader.getOffset().intValue());sectionBytes = (sectionByteArrayCodec.decode(buf));}segmentCodec.setSecHeader(secHeader);ElfSegment elfSegment = segmentCodec.decode(Unpooled.wrappedBuffer(transferBytes(sectionBytes)));elfSegment.setBytes(sectionBytes);elfSegment.setOffsetInFile(secHeader.getOffset());segments.add(elfSegment);}// resolve xx namesresolveRelatedNames(header, sectionHeaders, segments);ElfFile result = new ElfFile();result.setHeader(header);result.setProgramHeaders(programHeaders);result.setSectionBytes(sectionBytesInInteger);result.setSegments(segments);result.setSectionHeaders(sectionHeaders);return result;}private void resolveRelatedNames(ElfHeader header, List<ElfSectionHeader> sectionHeaders, List<ElfSegment> segments) {ElfSegment segStrTab = segments.get(header.getShstrndx());// fill segment namefor (int i = 0; i < segments.size(); i++) {ElfSegment segment = segments.get(i);ElfSectionHeader secHeader = sectionHeaders.get(i);String segName = lookStringInStrTab(segStrTab.getBytes(), secHeader.getName());segment.setName(segName);}ElfDynStrSegment strTab = (ElfDynStrSegment) lookUpSegment(segments, ".strtab");ElfDynStrSegment dynStrTab = (ElfDynStrSegment) lookUpSegment(segments, ".dynstr");// fill symtab nameElfSymTabSegment symTab = (ElfSymTabSegment) lookUpSegment(segments, ".symtab");for (int i = 0; i < symTab.getList().size(); i++) {ElfSymTabElement symtabEle = symTab.getList().get(i);String eleName = lookStringInStrTab(strTab.getBytes(), symtabEle.getNameIdx());symtabEle.setName(eleName);}// fill dynsym nameElfDynamicSymSegment dynSymTab = (ElfDynamicSymSegment) lookUpSegment(segments, ".dynsym");for (int i = 0; i < dynSymTab.getList().size(); i++) {ElfSymTabElement symtabEle = dynSymTab.getList().get(i);String eleName = lookStringInStrTab(dynStrTab.getBytes(), symtabEle.getNameIdx());symtabEle.setName(eleName);}// rela.dynElfRelaSegment relaDynTab = (ElfRelaSegment) lookUpSegment(segments, ".rela.dyn");for (int i = 0; i < relaDynTab.getList().size(); i++) {ElfRelaElement symtabEle = relaDynTab.getList().get(i);String eleName = dynStrTab.getList().get(symtabEle.getNameIdx());symtabEle.setName(eleName);}// rela.pltElfRelaSegment relaPltTab = (ElfRelaSegment) lookUpSegment(segments, ".rela.plt");for (int i = 0; i < relaPltTab.getList().size(); i++) {ElfRelaElement symtabEle = relaPltTab.getList().get(i);String eleName = dynStrTab.getList().get(symtabEle.getNameIdx());symtabEle.setName(eleName);}}public static ElfSegment lookUpSegment(List<ElfSegment> segments, String name) {for (ElfSegment segment : segments) {if (Objects.equals(name, segment.getName())) {return segment;}}return null;}public static byte[] transferBytes(Integer[] bytes) {byte[] result = new byte[bytes.length];int idx = 0;for (Integer b : bytes) {result[idx++] = b.byteValue();}return result;}public static String formatOffset(Long offset) {return String.format("0x00%s", Long.toHexString(offset));}public static String toString(Integer[] bytes) {StringBuilder sb = new StringBuilder();for (int i = 0; i < bytes.length; i++) {String part = ByteBufUtil.hexDump(new byte[]{bytes[i].byteValue()});sb.append(" ");sb.append(part);}return sb.toString();}public static String toAddress(Integer[] bytes) {StringBuilder sb = new StringBuilder();sb.append("0x");for (int i = bytes.length - 1; i >= 0; i--) {String part = ByteBufUtil.hexDump(new byte[]{bytes[i].byteValue()});sb.append(" ");sb.append(part);}return sb.toString();}public static String lookStringInStrTab(Integer[] bytes, int offset) {StringBuilder sb = new StringBuilder();for (int i = offset; i < bytes.length; i++) {if (bytes[i] == 0x00) {break;}sb.append((char) bytes[i].intValue());}return sb.toString();}@Overridepublic boolean isFixedLength() {return false;}@Overridepublic int length() {return 0;}public void debugCurrentBufReaderIdx(ByteBuf buf, String title) {System.out.println(title + " -> " + buf.readerIndex() + " - 0x" + Integer.toHexString(buf.readerIndex()));}}

ElfSegment 有多类实现, 这里不一一列举 

ElfNoteSegmentCodec

/*** ElfAbiTagSegmentCodec** @author Jerry.X.He* @version 1.0* @date 2022/9/27 14:34*/
public class ElfNoteSegmentCodec extends AbstractCodec<ElfNoteSegment, ElfNoteSegment> {private DWordCodec dWordCodec = new DWordCodec(ByteOrder.LITTLE_ENDIAN);private CharsetEncodingStringCodec stringCodec = new CharsetEncodingStringCodec(Constants.CHARSET_UTF8);@Overridepublic void encode(ElfNoteSegment entity, ByteBuf buf) {}@Overridepublic ElfNoteSegment decode(ByteBuf buf) {Integer nameSize = dWordCodec.decode(buf);Integer descSize = dWordCodec.decode(buf);Integer type = dWordCodec.decode(buf);CharsetEncodingStringWithFixedLenCodec nameCodec = new CharsetEncodingStringWithFixedLenCodec(nameSize);String name = nameCodec.decode(buf);ByteArrayWithFixedLenCodec descCodec = new ByteArrayWithFixedLenCodec(descSize);Integer[] desc = descCodec.decode(buf);ElfNoteSegment result = new ElfNoteSegment();result.setNameSize(nameSize);result.setDescSize(descSize);result.setType(type);result.setNameInNote(name);result.setDesc(desc);return result;}@Overridepublic boolean isFixedLength() {return false;}@Overridepublic int length() {return 0;}
}

ElfDynamicSymSegmentCodec

/*** ElfDynamicSymSegmentCodec** @author Jerry.X.He* @version 1.0* @date 2022/9/27 14:34*/
public class ElfDynamicSymSegmentCodec extends AbstractCodec<ElfDynamicSymSegment, ElfDynamicSymSegment> {AbstractCodec<ElfDynamicSymSegment, ElfDynamicSymSegment> codec = CodecUtils.createCodecForClazz(ElfDynamicSymSegment.class, 1);@Overridepublic void encode(ElfDynamicSymSegment entity, ByteBuf buf) {}@Overridepublic ElfDynamicSymSegment decode(ByteBuf buf) {return codec.decode(buf);}@Overridepublic boolean isFixedLength() {return false;}@Overridepublic int length() {return 0;}
}

解析结果


http://www.ppmy.cn/news/8458.html

相关文章

计算机中的时间.

计算机中的时间. 时间是什么概念? 这个好像不用多说,但又耐人寻味. 计算机中的时间,首先要表示清楚当前时间. 当前时间, 在c 语言中有3中表示方法. 1. 用长整数表示.,表示从格林威治0时间到现在的秒数. 这用time()就能得到 2. 用struct timeval 表示,它表示从格林威治0时间到…

【C++基础】07:多态

多态 OVERVIEW多态一、多态1.基本概念&#xff1a;2.E1-计算器类3.纯虚函数&抽象类&#xff1a;4.E2-制作饮品5.虚析构&纯虚析构&#xff1a;6.E3-电脑组装二、运算符重载1.加号运算符重载&#xff1a;2.左移>>运算符重载&#xff1a;3.递增运算符重载&#xff1…

费解的开关(BFS+哈希表+二进制枚举)

费解的开关&#xff08;BFS哈希表二进制枚举&#xff09;一、题目二、思路分析1、算法标签2、思路梳理方法1&#xff1a;BFS哈希表方法2&#xff1a;二进制枚举DFS一、题目 二、思路分析 1、算法标签 这道题考察的是BFS哈希表,DFS二进制枚举 2、思路梳理 方法1&#xff1a;…

【JAVA进阶】包装类,Arrays类,Lambda表达式

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;JAVASE基础 目录 一、包装类 二、Arrays类 三、Lambda表达式 一、包装类 其实就是8种基本数据类型对应的引用类型。 基本数据类型 引用数据类型 byte Byte short Short int Integer l…

C++语言程序设计

C语言程序设计 如需转载请标明出处&#xff1a;http://blog.csdn.net/itas109 文章目录C语言程序设计1. 语言概述1.1 字符集合1.2 词法记号关键字标识符文字操作符(运算符)分隔符空白符2. 数据类型2.1 基本数据类型2.2 常量整型常量实型常量字符常量字符串常量布尔常量2.3 变量…

【Linux】Linux基本指令

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f40c; 个人主页&#xff1a;蜗牛牛啊 &#x1f525; 系列专栏&#xff1a;&#x1f6b2;Linux &#x1f4d5; 学习格言&#xff1a;博观而约取&#xff0c;厚积而薄发 …

Tic-Tac-Toe可能棋局遍历的实现(python)

目录 1. 前言 2. 算法流程 3. 代码实现 4. 一个思考题&#xff1a;代码实现中的一个坑 5. 结果正确吗&#xff1f; 1. 前言 在上一篇博客中&#xff1a;Tic-Tac-Toe可能棋局搜索的实现&#xff08;python&#xff09;_笨牛慢耕的博客-CSDN博客Tic-Tac-Toe中文常译作井字棋…

01月份图形化一级打卡试题

活动时间 从2023年 1月1日至1月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; &#xff08;1&#xff09;小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 &#xff08;2&#xff09;小朋友做完题目后&…