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
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")
def setStructMemberSizes(self): utils.raiseElfManipulatorError( "Subclass must implement elfStruct::setStructMemberSizes")
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)
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")
def flushToELF(self, elfFileHandle, offset): utils.raiseElfManipulatorError( "Subclass must implement elfStruct::flushToELF")
def setAndValidateStructMembers(self): utils.raiseElfManipulatorError( "Subclass must implement elfStruct::setAndValidateStructMembers")