Ejemplo n.º 1
0
 def getStructMemberSize(self, member):
     if member in self.halfMembers:
         size = const.elfDataTypes.Elf32_Half
     elif member in self.longMembers:
         size = const.elfDataTypes.Elf32_Addr  # == Off == Sword == Word
     elif member in self.byteMembers:
         size = const.elfDataTypes.unsigned_char
     else:
         utils.raiseElfManipulatorError(self.__class__.__name__ + "." +
                                        member + " does not exist.")
     return size
Ejemplo n.º 2
0
 def setSectionAttribute(self, attribute):
     if attribute in [
             const.sectionFlags.SHF_WRITE, const.sectionFlags.SHF_ALLOC,
             const.sectionFlags.SHF_EXECINSTR, const.sectionFlags.SHF_MERGE,
             const.sectionFlags.SHF_STRINGS,
             const.sectionFlags.SHF_INFO_LINK,
             const.sectionFlags.SHF_LINK_ORDER,
             const.sectionFlags.SHF_GROUP, const.sectionFlags.SHF_TLS,
             const.sectionFlags.SHF_OS_NONCONFORMING,
             const.sectionFlags.SHF_MASKOS, const.sectionFlags.SHF_MASKPROC
     ]:
         self.sh_flags |= attribute
     else:
         utils.raiseElfManipulatorError("No such section attribute")
Ejemplo n.º 3
0
 def setStructMemberSizes(self):
     utils.raiseElfManipulatorError(
         "Subclass must implement elfStruct::setStructMemberSizes")
Ejemplo n.º 4
0
    def setAndValidateStructMembers(self):
        if (self.verbose):
            print "============================================================"
            print " ** VERBOSE DEBUG MSG ** SECTION HEADER (Elf32_Shdr)"
            print "============================================================"

        ##  This member specifies the name of the section. Its value is an index
        #   into the section header string table section, giving the location of
        #   a null terminated string.
        self.sh_name = self.getStructMember("sh_name")

        ##  This member categorizes the section's contents and semantics.
        self.sh_type = self.getStructMember("sh_type")
        if (self.sh_type not in [
                const.sectionTypes.SHT_NULL, const.sectionTypes.SHT_PROGBITS,
                const.sectionTypes.SHT_NOBITS, const.sectionTypes.SHT_STRTAB,
                const.sectionTypes.SHT_SYMTAB
        ]):
            #utils.raiseElfManipulatorError("Elf32_Shdr.sh_type failed validation.")
            if self.verbose:
                print "Skip Elf32_Shdr.sh_type validation for dynamic loading"

        ##  Sections support 1-bit flags that describe miscellaneous attributes.
        self.sh_flags = self.getStructMember("sh_flags")

        ##  If the section will appear in the memory image of a process, this
        #   member gives the address at which the section's first byte should
        #   reside. Otherwise, the member contains 0.
        self.sh_addr = self.getStructMember("sh_addr")

        ##  This member's value gives the byte offset from the beginning of the
        #   file to the first byte in the section. One section type, SHT_NOBITS,
        #   occupies no space in the file, and its sh_offset member locates the
        #   conceptual placement in the file.
        self.sh_offset = self.getStructMember("sh_offset")

        ##  This member gives the section's size in bytes. Unless the section
        #   type is SHT_NOBITS, the section occupies sh_size bytes in the file.
        #   A section of type SHT_NOBITS may have a non-zero size, but it
        #   occupies no space in the file.
        self.sh_size = self.getStructMember("sh_size")

        ##  This member holds a section header table index link, whose
        #   interpretation depends on the section type.
        self.sh_link = self.getStructMember("sh_link")
        # Print out detailed interpretation
        if (self.verbose):
            if (self.sh_type == const.sectionTypes.SHT_DYNAMIC):
                print "\tThe section header index of the string table used by entries in the section"
            elif (self.sh_type == const.sectionTypes.SHT_HASH):
                print "\tThe section header index of the symbol table to which the hash table applies"
            elif (self.sh_type == const.sectionTypes.SHT_REL
                  or self.sh_type == const.sectionTypes.SHT_RELA):
                print "\tThe section header index of the associated symbol table"
            elif (self.sh_type == const.sectionTypes.SHT_SYMTAB
                  or self.sh_type == const.sectionTypes.SHT_SYMTAB):
                print "\tThe section header index of the associated string table"
            else:
                print "\tSHN_UNDEF"

        ##  This member holds extra information, whose interpretation depends on
        #   the section type.
        self.sh_info = self.getStructMember("sh_info")
        # Print out detailed interpretation
        if (self.verbose):
            if (self.sh_type == const.sectionTypes.SHT_DYNAMIC):
                print "\t0"
            elif (self.sh_type == const.sectionTypes.SHT_HASH):
                print "\t0"
            elif (self.sh_type == const.sectionTypes.SHT_REL
                  or self.sh_type == const.sectionTypes.SHT_RELA):
                print "\tThe section header index of the section to which the relocation applies"
            elif (self.sh_type == const.sectionTypes.SHT_SYMTAB
                  or self.sh_type == const.sectionTypes.SHT_DYNSYM):
                print "\tOne greater than the symbol table index of the last local symbol (binding STB_LOCAL)"
            else:
                print "\t0"

        ##  Some sections have address alignment constraints. For example, if a
        #   section holds a doubleword, the system must ensure doubleword
        #   alignment for the entire section. That is, the value of sh_addr must
        #   be congruent to 0, modulo the value of sh_addralign. Currently, only
        #   0 and positive integral powers of two are allowed. Values 0 and 1
        #   mean the section has no alignment constraints.
        self.sh_addralign = self.getStructMember("sh_addralign")
        if (self.sh_addralign not in [0, 1]):
            if (self.sh_addr % self.sh_addralign):
                # debug print:
                # section_values = [
                #     (i, getattr(self, i))
                #     for i in self.__dict__.keys()
                #     if (
                #         (
                #             i.startswith('sh_')
                #             or i == 'idx'
                #         )
                #         and not hasattr(getattr(self, i), '__call__')
                #     )
                # ]
                # print 'section attributes: %r' % (dict(section_values),)
                # utils.raiseElfManipulatorError("Elf32_Shdr.sh_addralign failed validation.")
                # utils.raiseElfManipulatorWarning("Elf32_Shdr.sh_addralign failed validation.")
                print "Elf32_Shdr.sh_addralign failed validation."
            if not utils.isPowerOfTwo(self.sh_addralign):
                utils.raiseElfManipulatorError(
                    "Elf32_Shdr.sh_addralign failed validation.")

        ##  Some sections hold a table of fixed-size entries, such as a symbol
        #   table. For such a section, this member gives the size in bytes of
        #   each entry. The member contains 0 if the section does not hold a
        #   table of fixed-size entries.
        self.sh_entsize = self.getStructMember("sh_entsize")

        ##  This member contains the contents of the section.
        if self.sh_type != const.sectionTypes.SHT_NOBITS:
            self.contents = utils.getDataFromELF(self.elf, self.sh_offset,
                                                 self.sh_size)
Ejemplo n.º 5
0
    def setAndValidateStructMembers(self):
        if (self.verbose):
            print "============================================================"
            print " ** VERBOSE DEBUG MSG ** ELF HEADER (Elf32_Ehdr)"
            print "============================================================"

        ##  The initial bytes mark the file as an object file and provide
        #   machine-independent data with which to decode and interpret
        #   the file's contents.
        self.e_ident = []

        # Magic number identifying the file as an ELF object file
        self.e_ident.append(self.getStructMember("e_ident[EI_MAG0]"))
        if (self.e_ident[const.elfIdentification.EI_MAG0] != ord('\x7f')):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_MAG0] failed validation.")
        self.e_ident.append(self.getStructMember("e_ident[EI_MAG1]"))
        if (self.e_ident[const.elfIdentification.EI_MAG1] != ord('E')):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_MAG1] failed validation.")
        self.e_ident.append(self.getStructMember("e_ident[EI_MAG2]"))
        if (self.e_ident[const.elfIdentification.EI_MAG2] != ord('L')):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_MAG2] failed validation.")
        self.e_ident.append(self.getStructMember("e_ident[EI_MAG3]"))
        if (self.e_ident[const.elfIdentification.EI_MAG3] != ord('F')):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_MAG3] failed validation.")

        # Class should be 32-bit object
        self.e_ident.append(self.getStructMember("e_ident[EI_CLASS]"))
        if (self.e_ident[const.elfIdentification.EI_CLASS] !=
                const.elfClass.ELFCLASS32):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_CLASS] failed validation.")

        # Data encoding should be LITTLE-ENDIAN
        # Example:
        #            ---- ----
        # 0x0102    | 02 | 01 |
        #            ---- ----
        self.e_ident.append(self.getStructMember("e_ident[EI_DATA]"))
        utils.setElfEncoding(self.e_ident[const.elfIdentification.EI_DATA])

        # Version should be current
        self.e_ident.append(self.getStructMember("e_ident[EI_VERSION]"))
        if (self.e_ident[const.elfIdentification.EI_VERSION] !=
                const.elfVersion.EV_CURRENT):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_VERSION] failed validation.")

        # OSABI should be UNIX - System V
        self.e_ident.append(self.getStructMember("e_ident[EI_OSABI]"))
        if (self.e_ident[const.elfIdentification.EI_OSABI] !=
                const.elfOSABI.UNIX_SYSTEM_V):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_OSABI] failed validation.")

        # ABI version should be 0
        self.e_ident.append(self.getStructMember("e_ident[EI_ABIVERSION]"))
        if (self.e_ident[const.elfIdentification.EI_ABIVERSION] !=
                const.elfABIVersion.ZERO):
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_ident[EI_ABIVERSION] failed validation.")

        # Remaining bytes of the ELF identifier are don't cares (zeros)
        self.structOffset += const.elfIdentification.EI_NIDENT - const.elfIdentification.EI_PAD

        ##  This member identifies the object file type. Should be executable.
        self.e_type = self.getStructMember("e_type")
        if self.e_type != const.elfType.ET_EXEC:
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_type failed validation.")

        ##  This member's value specifies the required architecture for an
        #   individual file. Should be Qualcomm Hexagon.
        self.e_machine = self.getStructMember("e_machine")
        if self.e_machine != const.elfMachineType.EM_ARM:
            utils.raiseElfManipulatorError(
                "Elf32_Ehdr.e_machine failed validation.", self.e_machine)

        ##  This member identifies the object file version.
        self.e_version = self.getStructMember("e_version")

        ##  This member gives the virtual address to which the system first
        #   transfers control, thus starting the process. If the file has no
        #   associated entry point, this member holds zero.
        self.e_entry = self.getStructMember("e_entry")

        ##  This member holds the program header table's file offset in bytes.
        #   If the file has no program header table, this member holds zero.
        self.e_phoff = self.getStructMember("e_phoff")

        ##  This member holds the section header table's file offset in bytes.
        #   If the file has no section header table, this member holds zero.
        self.e_shoff = self.getStructMember("e_shoff")

        ##  This member holds processor-specific flags associated with the file.
        #   Flag names take the form EF_machine_flag. Flags should indicate that
        #   both the version of the Hexagon processor that the object file was
        #   created for AND the highest version of the Hexagon processor that
        #   the object file contains for is V5
        self.e_flags = self.getStructMember("e_flags")

        ##  This member holds the ELF header's size in bytes.
        self.e_ehsize = self.getStructMember("e_ehsize")

        ##  This member holds the size in bytes of one entry in the file's
        #   program header table; all entries are the same size.
        self.e_phentsize = self.getStructMember("e_phentsize")

        ##  This member holds the number of entries in the program header table.
        #   Thus the product of e_phentsize and e_phnum gives the table's size
        #   in bytes. If a file has no program header table, e_phnum holds the
        #   value zero.
        self.e_phnum = self.getStructMember("e_phnum")

        ##  This member holds a section header's size in bytes. A section header
        #   is one entry in the section header table; all entries are the same
        #   size.
        self.e_shentsize = self.getStructMember("e_shentsize")

        ##  This member holds the number of entries in the section header table.
        #   Thus the product of e_shentsize and e_shnum gives the section header
        #   table's size in bytes. If a file has no section header table,
        #   e_shnum holds the value zero.
        self.e_shnum = self.getStructMember("e_shnum")

        ##  This member holds the section header table index of the entry
        #   associated with the section name string table. If the file has no
        #   section name string table, this member holds the value SHN_UNDEF.
        self.e_shstrndx = self.getStructMember("e_shstrndx")
Ejemplo n.º 6
0
 def flushToELF(self, elfFileHandle, offset):
     utils.raiseElfManipulatorError(
         "Subclass must implement elfStruct::flushToELF")
Ejemplo n.º 7
0
 def setAndValidateStructMembers(self):
     utils.raiseElfManipulatorError(
         "Subclass must implement elfStruct::setAndValidateStructMembers")