Ticket #167: elf_with_sfs.diff
| File elf_with_sfs.diff, 10.9 kB (added by nneonneo <nneonneo@gmail.com>, 1 year ago) |
|---|
-
program/elf.py
old new 5 5 Creation date: 08 may 2006 6 6 """ 7 7 8 from hachoir_parser import Parser9 from hachoir_core.field import (FieldSet, ParserError, 10 UInt8, UInt16, UInt32, Enum,11 String, Bytes)12 from hachoir_core.text_handler import textHandler, hexadecimal 8 from hachoir_parser import HachoirParser 9 from hachoir_core.field import (FieldSet, ParserError, RootSeekableFieldSet, 10 Bit, PaddingBits, UInt8, UInt16, UInt32, Enum, 11 String, RawBytes, Bytes) 12 from hachoir_core.text_handler import textHandler, hexadecimal, filesizeHandler 13 13 from hachoir_core.endian import LITTLE_ENDIAN, BIG_ENDIAN 14 14 15 15 class ElfHeader(FieldSet): … … 47 47 yield Bytes(self, "signature", 4, r'ELF signature ("\x7fELF")') 48 48 yield Enum(UInt8(self, "class", "Class"), self.CLASS_NAME) 49 49 yield Enum(UInt8(self, "endian", "Endian"), self.ENDIAN_NAME) 50 yield UInt8(self, "file_version", "File version") 51 yield String(self, "pad", 8, "Pad") 52 yield UInt8(self, "nb_ident", "Size of ident[]") 50 yield UInt8(self, "file_version", "File version (1)") 51 yield String(self, "pad", 9, "Pad") 53 52 yield Enum(UInt16(self, "type", "File type"), self.TYPE_NAME) 54 53 yield Enum(UInt16(self, "machine", "Machine type"), self.MACHINE_NAME) 55 yield UInt32(self, "version", "ELF format version ")56 yield UInt32(self, "entry", "Number of entries")54 yield UInt32(self, "version", "ELF format version (1)") 55 yield textHandler(UInt32(self, "entry", "Virtual address to entry point"), hexadecimal) 57 56 yield UInt32(self, "phoff", "Program header offset") 58 57 yield UInt32(self, "shoff", "Section header offset") 59 58 yield UInt32(self, "flags", "Flags") … … 61 60 yield UInt16(self, "phentsize", "Program header entry size") 62 61 yield UInt16(self, "phnum", "Program header entry count") 63 62 yield UInt16(self, "shentsize", "Section header entry size") 64 yield UInt16(self, "shnum", "Section header entr ecount")65 yield UInt16(self, "shstrndx", "Section header str tabindex")63 yield UInt16(self, "shnum", "Section header entry count") 64 yield UInt16(self, "shstrndx", "Section header string table index") 66 65 67 def isValid(self):66 def validate(self): 68 67 if self["signature"].value != "\x7FELF": 69 68 return "Wrong ELF signature" 70 69 if self["class"].value not in self.CLASS_NAME: 71 70 return "Unknown class" 72 71 if self["endian"].value not in self.ENDIAN_NAME: 73 72 return "Unknown endian (%s)" % self["endian"].value 74 return ""73 return True 75 74 75 class SectionHeader32Flags(UInt32): 76 def createDescription(self): 77 val = self.value 78 desc = [] 79 if val & 0x1: 80 desc.append("Writable") 81 else: 82 desc.append("Not writable") 83 if val & 0x2: 84 desc.append("In memory") 85 else: 86 desc.append("Not in memory") 87 if val & 0x4: 88 desc.append("Executable") 89 else: 90 desc.append("Not executable") 91 if val & 0xFFFFFFF8: 92 desc.append("Extra: %08X" % (val & 0xFFFFFFF8)) 93 return ", ".join(desc) 94 76 95 class SectionHeader32(FieldSet): 77 96 static_size = 40*8 78 TYPE_NAME = { 79 8: "BSS" 80 } 97 class TypeNameClass(dict): 98 def __getitem__(self, key): 99 if dict.__contains__(self, key): 100 return dict.__getitem__(self, key) 101 if 0x70000000 <= key <= 0x7FFFFFFF: 102 return "Processor-specific data (0x%08X)" % key 103 elif 0x80000000 <= key <= 0xFFFFFFFF: 104 return "Application-specific data (0x%08X)" % key 105 else: 106 return str(key) 107 def __contains__(self, key): 108 return dict.__contains__(self, key) or 0x70000000 <= key <= 0xFFFFFFFF 81 109 110 TYPE_NAME = TypeNameClass({ 111 0: "Inactive", 112 1: "Program bits", 113 2: "Symbol table", 114 3: "String table", 115 4: "Relocation entries (with explicit addends)", 116 5: "Symbol hash table", 117 6: "Dynamic linking information", 118 7: "Note", 119 8: "No bits section", 120 9: "Relocation entries (without explicit addends)", 121 10:"Reserved", 122 11:"Dynamic linking symbol table", 123 0x60000000: 'SHT_LOOS', 124 0x6ffffffb: 'SHT_LOSUNW', 125 0x6ffffffc: 'SHT_SUNW_syminfo', 126 0x6ffffffd: 'SHT_GNU_verdef', 127 0x6ffffffe: 'SHT_GNU_verneed', 128 0x6fffffff: 'SHT_GNU_versym', 129 0x6fffffff: 'SHT_HISUNW', 130 0x6fffffff: 'SHT_HIOS', 131 }) 132 82 133 def createFields(self): 83 yield UInt32(self, "name ", "Name")134 yield UInt32(self, "name_offset", "Name (as an offset into the section header string table)") 84 135 yield Enum(UInt32(self, "type", "Type"), self.TYPE_NAME) 85 yield UInt32(self, "flags", "Flags") 86 yield textHandler(UInt32(self, "VMA", "Virtual memory address"), hexadecimal) 87 yield textHandler(UInt32(self, "LMA", "Logical memory address (in file)"), hexadecimal) 88 yield textHandler(UInt32(self, "size", "Size"), hexadecimal) 89 yield UInt32(self, "link", "Link") 90 yield UInt32(self, "info", "Information") 136 yield SectionHeader32Flags(self, "flags") 137 yield textHandler(UInt32(self, "addr", "Address of section in memory"), hexadecimal) 138 yield UInt32(self, "offset", "Offset to section from file start") 139 yield UInt32(self, "size", "Size") 140 link_desc = "Link (not used for this section type)" 141 info_desc = "Info (not used for this section type)" 142 if self["type"].value == 5: # hash table 143 link_desc = "Link (section header index of the symbol table to which this hash table applies)" 144 elif self["type"].value == 6: # dynamic linking info 145 link_desc = "Link (section header index of the string table used by the entries in this section)" 146 elif self["type"].value in (4, 9): # relocation entries 147 link_desc = "Link (section header index of the associated symbol table)" 148 info_desc = "Info (section header index of the section to which the relocation applies)" 149 elif self["type"].value in (2, 11): # symbol tables 150 link_desc = "Link (section header index of the associated string table)" 151 info_desc = "Info (symbol table index of the last local symbol, plus one)" 152 yield UInt32(self, "link", link_desc) 153 yield UInt32(self, "info", info_desc) 91 154 yield UInt32(self, "addr_align", "Address alignment") 92 yield UInt32(self, "entry_size", " Entry size")155 yield UInt32(self, "entry_size", "Size of each entry (if this section is a table of fixed-size entries)") 93 156 94 157 def createDescription(self): 158 offset = self["/section[%s]"%self["/header/shstrndx"].value].address + (self["name_offset"].value*8) 159 name = "" 160 while 1: 161 c=self.stream.readBytes(offset, 1) 162 if c=="\0": 163 break 164 offset += 8 165 name += c 166 95 167 return "Section header (name: %s, type: %s)" % \ 96 ( self["name"].value, self["type"].display)168 (name, self["type"].display) 97 169 98 170 class ProgramHeader32(FieldSet): 99 171 TYPE_NAME = { 100 3: "Dynamic library" 172 0: "Unused", 173 1: "Loadable segment", 174 2: "Dynamic linking information", 175 3: "Program interpreter path", 176 4: "Auxiliary information (note)", 177 5: "Reserved", 178 6: "Program header", 101 179 } 102 180 static_size = 32*8 103 181 104 182 def createFields(self): 105 yield Enum(UInt16(self, "type", "Type"), ProgramHeader32.TYPE_NAME) 106 yield UInt16(self, "flags", "Flags") 107 yield UInt32(self, "offset", "Offset") 108 yield textHandler(UInt32(self, "vaddr", "V. address"), hexadecimal) 109 yield textHandler(UInt32(self, "paddr", "P. address"), hexadecimal) 110 yield UInt32(self, "file_size", "File size") 111 yield UInt32(self, "mem_size", "Memory size") 112 yield UInt32(self, "align", "Alignment") 113 yield UInt32(self, "xxx", "???") 183 yield Enum(UInt32(self, "type", "Type"), self.TYPE_NAME) 184 yield UInt32(self, "offset", "File offset to segment") 185 yield textHandler(UInt32(self, "vaddr", "Virtual address of segment"), hexadecimal) 186 yield textHandler(UInt32(self, "paddr", "Physical address of segment"), hexadecimal) 187 yield filesizeHandler(UInt32(self, "file_size", "Size of file image of segment")) 188 yield UInt32(self, "mem_size", "Size of memory image of segment") 189 yield UInt32(self, "flags", "Segment-specific flags") 190 yield UInt32(self, "align", "Alignment requirements") 114 191 115 192 def createDescription(self): 116 193 return "Program Header (%s)" % self["type"].display … … 131 208 # chunk = self.doRead("section[]", "Section", (FormatChunk, "string[0]")) 132 209 # chunk.description = "ELF section (in file: %s..%s)" % (ofs, ofs+size) 133 210 134 class ElfFile( Parser):211 class ElfFile(HachoirParser, RootSeekableFieldSet): 135 212 PARSER_TAGS = { 136 213 "id": "elf", 137 214 "category": "program", … … 147 224 "description": "ELF Unix/BSD program/library" 148 225 } 149 226 endian = LITTLE_ENDIAN 227 def __init__(self, stream, **args): 228 RootSeekableFieldSet.__init__(self, None, "root", stream, None, stream.askSize(self)) 229 HachoirParser.__init__(self, stream, **args) 150 230 151 231 def validate(self): 152 err = self["header"].isValid() 153 if err: 154 return err 155 return True 232 return self["header"].validate() 156 233 157 234 def createFields(self): 158 235 # Choose the right endian depending on endian specified in header … … 174 251 #chunk.description = "Sections (use an evil hack to manage share same data on differents parts)" 175 252 #assert self.current_size//8 == self["header/shoff"].value 176 253 else: 177 raw = self.seekByte(self["header/shoff"].value , "raw[]", relative=False)254 raw = self.seekByte(self["header/shoff"].value)#, "raw[]", relative=False) 178 255 if raw: 179 256 yield raw 180 257 258 position = self["header/shoff"].value 259 181 260 for index in xrange(self["header/shnum"].value): 182 yield SectionHeader32(self, "section_header[]") 261 self.seekByte(position) 262 header = SectionHeader32(self, "section_header[]") 263 yield header 264 position += header.size // 8 265 if header["type"].value != 8 and header["size"].value: 266 self.seekByte(header["offset"].value) 267 yield RawBytes(self, "section[%i]"%index, header["size"].value) 183 268 184 269 def createDescription(self): 185 270 return "ELF Unix/BSD program/library: %s" % (