Ticket #167: elf_without_sfs.diff

File elf_without_sfs.diff, 8.8 kB (added by nneonneo <nneonneo@gmail.com>, 1 year ago)

Patch (not using SeekableFieldSet?) to hachoir-parser/hachoir_parser/program/elf.py

  • program/elf.py

    old new  
    77 
    88from hachoir_parser import Parser 
    99from hachoir_core.field import (FieldSet, ParserError, 
    10     UInt8, UInt16, UInt32, Enum, 
     10    Bit, PaddingBits, UInt8, UInt16, UInt32, Enum, 
    1111    String, Bytes) 
    12 from hachoir_core.text_handler import textHandler, hexadecimal 
     12from hachoir_core.text_handler import textHandler, hexadecimal, filesizeHandler 
    1313from hachoir_core.endian import LITTLE_ENDIAN, BIG_ENDIAN 
    1414 
    1515class ElfHeader(FieldSet): 
     
    4747        yield Bytes(self, "signature", 4, r'ELF signature ("\x7fELF")') 
    4848        yield Enum(UInt8(self, "class", "Class"), self.CLASS_NAME) 
    4949        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") 
    5352        yield Enum(UInt16(self, "type", "File type"), self.TYPE_NAME) 
    5453        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
    5756        yield UInt32(self, "phoff", "Program header offset") 
    5857        yield UInt32(self, "shoff", "Section header offset") 
    5958        yield UInt32(self, "flags", "Flags") 
     
    6160        yield UInt16(self, "phentsize", "Program header entry size") 
    6261        yield UInt16(self, "phnum", "Program header entry count") 
    6362        yield UInt16(self, "shentsize", "Section header entry size") 
    64         yield UInt16(self, "shnum", "Section header entre count") 
    65         yield UInt16(self, "shstrndx", "Section header strtab index") 
     63        yield UInt16(self, "shnum", "Section header entry count") 
     64        yield UInt16(self, "shstrndx", "Section header string table index") 
    6665 
    67     def isValid(self): 
     66    def validate(self): 
    6867        if self["signature"].value != "\x7FELF": 
    6968            return "Wrong ELF signature" 
    7069        if self["class"].value not in self.CLASS_NAME: 
    7170            return "Unknown class" 
    7271        if self["endian"].value not in self.ENDIAN_NAME: 
    7372            return "Unknown endian (%s)" % self["endian"].value 
    74         return "" 
     73        return True 
    7574 
     75class 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 
    7695class SectionHeader32(FieldSet): 
    7796    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 
    81109 
     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 
    82133    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)") 
    84135        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) 
    91154        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)") 
    93156 
    94157    def createDescription(self): 
    95158        return "Section header (name: %s, type: %s)" % \ 
    96             (self["name"].value, self["type"].display) 
     159            (self["name_offset"].value, self["type"].display) 
    97160 
    98161class ProgramHeader32(FieldSet): 
    99162    TYPE_NAME = { 
    100         3: "Dynamic library" 
     163        0: "Unused", 
     164        1: "Loadable segment", 
     165        2: "Dynamic linking information", 
     166        3: "Program interpreter path", 
     167        4: "Auxiliary information (note)", 
     168        5: "Reserved", 
     169        6: "Program header", 
    101170    } 
    102171    static_size = 32*8 
    103172 
    104173    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", "???") 
     174        yield Enum(UInt32(self, "type", "Type"), self.TYPE_NAME) 
     175        yield UInt32(self, "offset", "File offset to segment") 
     176        yield textHandler(UInt32(self, "vaddr", "Virtual address of segment"), hexadecimal) 
     177        yield textHandler(UInt32(self, "paddr", "Physical address of segment"), hexadecimal) 
     178        yield filesizeHandler(UInt32(self, "file_size", "Size of file image of segment")) 
     179        yield UInt32(self, "mem_size", "Size of memory image of segment") 
     180        yield UInt32(self, "flags", "Segment-specific flags") 
     181        yield UInt32(self, "align", "Alignment requirements") 
    114182 
    115183    def createDescription(self): 
    116184        return "Program Header (%s)" % self["type"].display 
     
    149217    endian = LITTLE_ENDIAN 
    150218 
    151219    def validate(self): 
    152         err = self["header"].isValid() 
    153         if err: 
    154             return err 
    155         return True 
     220        return self["header"].validate() 
    156221 
    157222    def createFields(self): 
    158223        # Choose the right endian depending on endian specified in header