def as_bytearray(self): import six from peachpy.formats.elf.file import FileHeader from peachpy.formats.elf.section import Section, StringSection, SymbolSection from peachpy.util import roundup file_header = FileHeader(self.abi) file_header.section_header_table_offset = file_header.size file_header.section_header_entries_count = len(self.sections) file_header.section_name_string_table_index = 1 data = file_header.as_bytearray # Collect strings from sections for section in self.sections: self.shstrtab.add(section.name) if isinstance(section, StringSection): pass elif isinstance(section, SymbolSection): for symbol in six.iterkeys(section.symbol_index_map): self.strtab.add(symbol.name) # Layout sections data_offset = file_header.size + Section.get_header_size( self.abi) * len(self.sections) section_offsets = [] for section in self.sections: if section.alignment != 0: data_offset = roundup(data_offset, section.alignment) section_offsets.append(data_offset) data_offset += section.get_content_size(self.abi) from peachpy.encoder import Encoder encoder = Encoder(self.abi.endianness, self.abi.elf_bitness) section_index_map = { section: index for index, section in enumerate(self.sections) } # Write section headers for section, offset in zip(self.sections, section_offsets): data += section.encode_header(encoder, self.shstrtab._string_index_map, section_index_map, offset) # Write section content for section in self.sections: padding = bytearray( roundup(len(data), section.alignment) - len(data)) data += padding data += section.encode_content(encoder, self.strtab._string_index_map, section_index_map, self.symtab.symbol_index_map) return data
def as_bytearray(self): from peachpy.encoder import Encoder return Encoder.uint16le(self.abi.mscoff_machine_type) + \ Encoder.uint16le(self.section_count) + \ Encoder.uint32le(self.timestamp or 0) + \ Encoder.uint32le(self.symbol_table_offset or 0) + \ Encoder.uint32le(self.symbol_count) + \ Encoder.uint16le(0) + \ Encoder.uint16le(self.flags)
def as_bytearray(self): from peachpy.encoder import Encoder from peachpy.util import is_int if is_int(self.name): entry = Encoder.uint32le(0) + Encoder.uint32le(self.name) else: entry = Encoder.fixed_string(self.name, 8) return entry + \ Encoder.uint32le(self.value) + \ Encoder.uint16le(self.section_index) + \ Encoder.uint16le(self.symbol_type) + \ Encoder.uint8(self.storage_class) + \ Encoder.uint8(self.auxiliary_entries)
def encode(self): from peachpy.formats.macho.file import MachHeader from peachpy.formats.macho.symbol import Relocation from peachpy.util import roundup from peachpy.encoder import Encoder bitness = {4: 32, 8: 64}[self.abi.pointer_size] encoder = Encoder(self.abi.endianness, bitness) mach_header = MachHeader(self.abi) mach_header.commands_size = self.symbol_table.command_size mach_header.commands_count = 1 for segment in self.segments: mach_header.commands_size += segment.get_command_size(self.abi) mach_header.commands_count += 1 symbol_offset_map = dict() section_offset_map = dict() section_address_map = dict() section_relocations_map = dict() # Layout the commands data_offset = mach_header.get_size(self.abi) for segment in self.segments: data_offset += segment.get_command_size(self.abi) data_offset += self.symbol_table.command_size # Layout section data data_address = 0 for segment in self.segments: for section in segment.sections: data_offset = roundup(data_offset, section.alignment) data_address = roundup(data_address, section.alignment) section_offset_map[section] = data_offset section_address_map[section] = data_address data_offset += section.content_size data_address += section.content_size data_offset = roundup(data_offset, self.abi.pointer_size) # Layout the relocations for segment in self.segments: for section in segment.sections: if section.relocations: section_relocations_map[section] = data_offset data_offset += Relocation.size * len(section.relocations) # Layout the symbols for symbol in self.symbol_table.symbols: symbol_offset_map[symbol] = data_offset data_offset += symbol.get_entry_size(self.abi) # Layout the strings string_table_offset = data_offset # Create map: section->index section_index = 1 section_index_map = dict() for segment in self.segments: for section in segment.sections: section_index_map[section] = section_index section_index += 1 # Create map: symbol->index symbol_index_map = { symbol: index for index, symbol in enumerate(self.symbol_table.symbols) } # Write Mach-O header data = mach_header.encode(encoder) # Write commands for segment in self.segments: data += segment.encode_command(encoder, section_offset_map, section_address_map, section_relocations_map) data += self.symbol_table.encode_command(encoder, symbol_offset_map, string_table_offset) # Write section data for segment in self.segments: for section in segment.sections: padding = bytearray( roundup(len(data), section.alignment) - len(data)) data += padding + section.content padding = bytearray( roundup(len(data), self.abi.pointer_size) - len(data)) data += padding # Write relocations for segment in self.segments: for section in segment.sections: for relocation in section.relocations: data += relocation.encode(encoder, section_index_map, symbol_index_map) # Write symbols for symbol in self.symbol_table.symbols: data += symbol.encode(encoder, self.string_table.string_index_map, section_index_map, section_address_map) # Write string table data += self.string_table.encode() return data
def as_hex(self): from peachpy.encoder import Encoder, Endianness bytestring = self.encode(Encoder(Endianness.Little)) return "".join("%02X" % byte for byte in bytestring)
def encode(self): from peachpy.encoder import Encoder encoder = Encoder(self.abi.endianness) # Collect names that need to be encoded in the string table import codecs for section in self.sections: if len(codecs.encode(section.name, "utf8")) > 8: self.string_table.add(section.name) for symbol in self.symbols: if len(codecs.encode(symbol.name, "utf8")) > 8: self.string_table.add(symbol.name) # Layout sections offsets from peachpy.formats.mscoff.section import Section section_offset_map = dict() symbol_table_offset = Image.file_header_size + len( self.sections) * Section.header_size data_offset = symbol_table_offset + self.string_table.size for symbol in self.symbols: data_offset += symbol.entry_size for section in self.sections: section_offset_map[section] = data_offset data_offset += section.content_size # Layout section relocations from peachpy.formats.mscoff.symbol import Relocation section_relocations_map = dict() for section in self.sections: if section.relocations: section_relocations_map[section] = data_offset data_offset += Relocation.entry_size * len(section.relocations) section_index_map = { section: index + 1 for index, section in enumerate(self.sections) } symbol_index_map = { symbol: index for index, symbol in enumerate(self.symbols) } # Write file header timestamp = 0 file_flags = 0 data = encoder.uint16(self.abi.mscoff_machine_type) + \ encoder.uint16(len(self.sections)) + \ encoder.uint32(timestamp) + \ encoder.uint32(symbol_table_offset) + \ encoder.uint32(len(self.symbols)) + \ encoder.uint16(0) + \ encoder.uint16(file_flags) # Write section headers for section in self.sections: data += section.encode_header(encoder, self.string_table._strings, section_offset_map[section], section_relocations_map.get(section)) # Write symbol table and string table (immediately follows symbols table) for symbol in self.symbols: data += symbol.encode_entry(encoder, self.string_table._strings, section_index_map) data += self.string_table.encode() # Write section content for section in self.sections: data += section.content # Write section relocations for section in self.sections: for relocation in section.relocations: data += relocation.encode_entry(encoder, symbol_index_map) return data
def encode(self): from peachpy.encoder import Encoder encoder = Encoder(self.abi.endianness) # Collect names that need to be encoded in the string table import codecs for section in self.sections: if len(codecs.encode(section.name, "utf8")) > 8: self.string_table.add(section.name) for symbol in self.symbols: if len(codecs.encode(symbol.name, "utf8")) > 8: self.string_table.add(symbol.name) # Layout sections offsets from peachpy.formats.mscoff.section import Section section_offset_map = dict() symbol_table_offset = Image.file_header_size + len(self.sections) * Section.header_size data_offset = symbol_table_offset + self.string_table.size for symbol in self.symbols: data_offset += symbol.entry_size for section in self.sections: section_offset_map[section] = data_offset data_offset += section.content_size # Layout section relocations from peachpy.formats.mscoff.symbol import Relocation section_relocations_map = dict() for section in self.sections: if section.relocations: section_relocations_map[section] = data_offset data_offset += Relocation.entry_size * len(section.relocations) section_index_map = {section: index + 1 for index, section in enumerate(self.sections)} symbol_index_map = {symbol: index for index, symbol in enumerate(self.symbols)} # Write file header timestamp = 0 file_flags = 0 data = encoder.uint16(self.abi.mscoff_machine_type) + \ encoder.uint16(len(self.sections)) + \ encoder.uint32(timestamp) + \ encoder.uint32(symbol_table_offset) + \ encoder.uint32(len(self.symbols)) + \ encoder.uint16(0) + \ encoder.uint16(file_flags) # Write section headers for section in self.sections: data += section.encode_header(encoder, self.string_table._strings, section_offset_map[section], section_relocations_map.get(section)) # Write symbol table and string table (immediately follows symbols table) for symbol in self.symbols: data += symbol.encode_entry(encoder, self.string_table._strings, section_index_map) data += self.string_table.encode() # Write section content for section in self.sections: data += section.content # Write section relocations for section in self.sections: for relocation in section.relocations: data += relocation.encode_entry(encoder, symbol_index_map) return data
def as_bytearray(self): from peachpy.encoder import Encoder from peachpy.util import is_int if is_int(self.name): header = Encoder.fixed_string("/" + str(self.name), 8) else: header = Encoder.fixed_string(self.name, 8) return header + \ Encoder.uint32le(self.memory_size) + \ Encoder.uint32le(self.memory_address) + \ Encoder.uint32le(self.content_size) + \ Encoder.uint32le(self.content_offset) + \ Encoder.uint32le(self.relocations_offset or 0) + \ Encoder.uint32le(self.line_numbers_offset or 0) + \ Encoder.uint16le(self.relocations_count) + \ Encoder.uint16le(self.line_numbers_count) + \ Encoder.uint32le(self.flags)