def encode(self, encoder, name_index_map, section_index_map): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) assert encoder.bitness in [32, 64] assert self.name in name_index_map from peachpy.formats.elf.section import SectionIndex assert self.section is None or isinstance( self.section, SectionIndex) or self.section in section_index_map name_index = name_index_map[self.name] section_index = SectionIndex.absolute if self.section is not None: if isinstance(self.section, SectionIndex): section_index = self.section else: section_index = section_index_map[self.section] if encoder.bitness == 32: return encoder.uint32(name_index) + \ encoder.uint32(self.value) + \ encoder.uint32(self.size) + \ encoder.uint8((self.binding << 4) | (self.type & 0xF)) + \ encoder.uint8(0) + \ encoder.uint16(section_index) else: return encoder.uint32(name_index) + \ encoder.uint8((self.binding << 4) | (self.type & 0xF)) + \ encoder.uint8(0) + \ encoder.uint16(section_index) + \ encoder.uint64(self.value) + \ encoder.uint64(self.size)
def encode(self, encoder, name_index_map, section_index_map): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) assert encoder.bitness in [32, 64] assert self.name in name_index_map from peachpy.formats.elf.section import SectionIndex assert self.section is None or isinstance(self.section, SectionIndex) or self.section in section_index_map name_index = name_index_map[self.name] section_index = SectionIndex.absolute if self.section is not None: if isinstance(self.section, SectionIndex): section_index = self.section else: section_index = section_index_map[self.section] if encoder.bitness == 32: return encoder.uint32(name_index) + \ encoder.uint32(self.value) + \ encoder.uint32(self.size) + \ encoder.uint8((self.binding << 4) | (self.type & 0xF)) + \ encoder.uint8(0) + \ encoder.uint16(section_index) else: return encoder.uint32(name_index) + \ encoder.uint8((self.binding << 4) | (self.type & 0xF)) + \ encoder.uint8(0) + \ encoder.uint16(section_index) + \ encoder.uint64(self.value) + \ encoder.uint64(self.size)
def encode_entry(self, encoder, symbol_index_map, section_address=0): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) assert self.symbol in symbol_index_map symbol_index = symbol_index_map[self.symbol] return encoder.uint32(section_address + self.offset) + \ encoder.uint32(symbol_index) + \ encoder.uint16(self.type)
def encode_header(self, encoder, name_index_map, section_index_map, offset, address=None, link_section=None, info=None, content_size=0, entry_size=0): import peachpy.encoder from peachpy.util import is_uint64, is_uint32 assert isinstance(encoder, peachpy.encoder.Encoder) assert isinstance(name_index_map, dict) assert section_index_map is None or isinstance(section_index_map, dict) assert offset is None or is_uint64(offset) assert address is None or is_uint64(address) assert link_section is None or isinstance(link_section, Section) assert info is None or is_uint64(info) assert is_uint64(content_size) assert is_uint32(entry_size) assert encoder.bitness in [32, 64] if encoder.bitness == 32: assert offset is None or is_uint32(offset) assert address is None or is_uint32(address) assert self.name is None or self.name in name_index_map assert section_index_map is not None or link_section is None name_index = name_index_map.get(self.name, 0) if address is None: address = 0 if offset is None: offset = 0 link = 0 if link_section is not None: link = section_index_map[link_section] if info is None: info = 0 return encoder.uint32(name_index) + \ encoder.uint32(self.type) + \ encoder.unsigned_offset(self.flags) + \ encoder.unsigned_offset(address) + \ encoder.unsigned_offset(offset) + \ encoder.unsigned_offset(content_size) + \ encoder.uint32(link) + \ encoder.uint32(info) + \ encoder.unsigned_offset(self.alignment) + \ encoder.unsigned_offset(entry_size)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) if self.abi.pointer_size == 4: return encoder.uint32(self.string_index) + \ encoder.uint8(self.type | self.visibility) + \ encoder.uint8(self.section_index) + \ encoder.uint16(self.description | self.flags) + \ encoder.uint32(self.value) else: return encoder.uint32(self.string_index) + \ encoder.uint8(self.type | self.visibility) + \ encoder.uint8(self.section_index) + \ encoder.uint16(self.description | self.flags) + \ encoder.uint64(self.value)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) if self.abi.elf_class == ElfClass.Class32: return encoder.uint32(self.name_index) + \ encoder.uint32(self.value) + \ encoder.uint32(self.content_size) + \ encoder.uint8((self.binding << 4) | (self.type & 0xF)) + \ encoder.uint8(0) + \ encoder.uint16(self.section_index) else: return encoder.uint32(self.name_index) + \ encoder.uint8((self.binding << 4) | (self.type & 0xF)) + \ encoder.uint8(0) + \ encoder.uint16(self.section_index) + \ encoder.uint64(self.value) + \ encoder.uint64(self.content_size)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness, self.abi.elf_bitness) return self.identification.as_bytearray + \ encoder.uint16(self.file_type) + \ encoder.uint16(self.abi.elf_machine_type) + \ encoder.uint32(self.file_version) + \ encoder.unsigned_offset(self.entry_address or 0) + \ encoder.unsigned_offset(self.program_header_table_offset or 0) + \ encoder.unsigned_offset(self.section_header_table_offset or 0) + \ encoder.uint32(self.flags) + \ encoder.uint16(self.file_header_size) + \ encoder.uint16(self.program_header_entry_size) + \ encoder.uint16(self.program_header_entries_count) + \ encoder.uint16(self.section_header_entry_size) + \ encoder.uint16(self.section_header_entries_count) + \ encoder.uint16(self.section_name_string_table_index)
def encode(self, encoder, section_index_map, symbol_index_map): from peachpy.formats.macho.section import Section from peachpy.util import ilog2 symbol = 0 if isinstance(self.symbol, Symbol): # Set "external" bit (bit 27) if referencing an external symbol symbol = symbol_index_map[self.symbol] | 0x8000000 elif isinstance(self.symbol, Section): symbol = section_index_map[self.symbol] if self.is_pc_relative: # Set "pc_relative" bit (bit 24) if the relocation is relative to the program counter symbol |= 0x1000000 log2_size = ilog2(self.size) symbol |= log2_size << 25 symbol |= self.type << 28 return encoder.uint32(self.offset) + encoder.uint32(symbol)
def encode(self, encoder, name_index_map, section_index_map, section_address_map): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) assert self.name in name_index_map assert self.section is None or self.section in section_index_map name_index = name_index_map[self.name] section_index = 0 if self.section is not None: section_index = section_index_map[self.section] if encoder.bitness == 32: return encoder.uint32(name_index) + \ encoder.uint8(self.type | self.visibility) + \ encoder.uint8(section_index) + \ encoder.uint16(self.description | self.flags) + \ encoder.uint32(self.value) else: return encoder.uint32(name_index) + \ encoder.uint8(self.type | self.visibility) + \ encoder.uint8(section_index) + \ encoder.uint16(self.description | self.flags) + \ encoder.uint64(self.value + section_address_map[self.section])
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) return encoder.uint32(self.id) + \ encoder.uint32(self.size) + \ encoder.uint32(self.symbol_offset or 0) + \ encoder.uint32(self.symbol_count) + \ encoder.uint32(self.string_offset or 0) + \ encoder.uint32(self.string_size)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) bytes = encoder.uint32(self.magic) + \ encoder.uint32(self.cpu_type) + \ encoder.uint32(self.cpu_subtype) + \ encoder.uint32(self.file_type) + \ encoder.uint32(self.command_count) + \ encoder.uint32(self.command_size) + \ encoder.uint32(self.flags) if self.abi.pointer_size == 8: bytes += bytearray(4) return bytes
def encode_command(self, encoder, symbol_offset_map, string_offset): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) command_id = 0x2 symbols_offset = 0 if self.symbols: symbols_offset = symbol_offset_map[self.symbols[0]] return encoder.uint32(command_id) + \ encoder.uint32(SymbolTable.command_size) + \ encoder.uint32(symbols_offset) + \ encoder.uint32(len(self.symbols)) + \ encoder.uint32(string_offset) + \ encoder.uint32(self.string_table.size)
def encode_command(self, encoder, offset, address, relocations_offset): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) if len(self.relocations) == 0: relocations_offset = 0 if encoder.bitness == 32: return encoder.fixed_string(self.section_name, 16) + \ encoder.fixed_string(self.segment_name, 16) + \ encoder.uint32(address) + \ encoder.uint32(self.content_size) + \ encoder.uint32(offset) + \ encoder.uint32(self.log2_alignment) + \ encoder.uint32(relocations_offset) + \ encoder.uint32(self.relocations_count) + \ encoder.uint32(self.type | self.attributes) + \ bytearray(8) else: return encoder.fixed_string(self.section_name, 16) + \ encoder.fixed_string(self.segment_name, 16) + \ encoder.uint64(address) + \ encoder.uint64(self.content_size) + \ encoder.uint32(offset) + \ encoder.uint32(self.log2_alignment) + \ encoder.uint32(relocations_offset) + \ encoder.uint32(self.relocations_count) + \ encoder.uint32(self.type | self.attributes) + \ bytearray(12)
def encode_command(self, encoder, section_offset_map, section_address_map, section_relocations_map): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) offset = section_offset_map[self.sections[0]] memory_size = sum(section.content_size for section in self.sections) file_size = sum(section.content_size for section in self.sections) address = 0 if self.sections: address = section_address_map[self.sections[0]] # TODO: combine the two cases if encoder.bitness == 32: command_id = 0x1 command_size = 56 + len(self.sections) * 68 command = encoder.uint32(command_id) + \ encoder.uint32(command_size) + \ encoder.fixed_string(self.name, 16) + \ encoder.uint32(address) + \ encoder.uint32(memory_size) + \ encoder.uint32(offset) + \ encoder.uint32(file_size) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(len(self.sections)) + \ encoder.uint32(self.flags) else: command_id = 0x19 command_size = 72 + len(self.sections) * 80 command = encoder.uint32(command_id) + \ encoder.uint32(command_size) + \ encoder.fixed_string(self.name, 16) + \ encoder.uint64(address) + \ encoder.uint64(memory_size) + \ encoder.uint64(offset) + \ encoder.uint64(file_size) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(len(self.sections)) + \ encoder.uint32(self.flags) for section in self.sections: command += section.encode_command( encoder, section_offset_map[section], section_address_map[section], section_relocations_map.get(section)) from peachpy.x86_64.abi import system_v_x86_64_abi return command
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) if self.abi.pointer_size == 4: return ( encoder.fixed_string(self.name, 16) + encoder.fixed_string(self.segment_name, 16) + encoder.uint32(self.address or 0) + encoder.uint32(self.content_size) + encoder.uint32(self.offset) + encoder.uint32(self.alignment) + encoder.uint32(self.relocation_offset or 0) + encoder.uint32(self.relocation_count) + encoder.uint32(self.type | self.attributes) + bytearray(8) ) else: return ( encoder.fixed_string(self.name, 16) + encoder.fixed_string(self.segment_name, 16) + encoder.uint64(self.address or 0) + encoder.uint64(self.content_size) + encoder.uint32(self.offset) + encoder.uint32(self.alignment) + encoder.uint32(self.relocation_offset or 0) + encoder.uint32(self.relocation_count) + encoder.uint32(self.type | self.attributes) + bytearray(12) )
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) if self.abi.pointer_size == 4: return encoder.uint32(self.id) + \ encoder.uint32(self.size) + \ encoder.fixed_string(self.name, 16) + \ encoder.uint32(self.address or 0) + \ encoder.uint32(self.memory_size) + \ encoder.uint32(self.offset) + \ encoder.uint32(self.file_size) + \ encoder.uint32(MemoryProtection.Default) + \ encoder.uint32(MemoryProtection.Default) + \ encoder.uint32(self.section_count) + \ encoder.uint32(self.flags) else: return encoder.uint32(self.id) + \ encoder.uint32(self.size) + \ encoder.fixed_string(self.name, 16) + \ encoder.uint64(self.address or 0) + \ encoder.uint64(self.memory_size) + \ encoder.uint64(self.offset) + \ encoder.uint64(self.file_size) + \ encoder.uint32(MemoryProtection.Default) + \ encoder.uint32(MemoryProtection.Default) + \ encoder.uint32(self.section_count) + \ encoder.uint32(self.flags)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) if self.abi.elf_class == ElfClass.Class32: return encoder.uint32(self.name_index) + \ encoder.uint32(self.content_type) + \ encoder.uint32(self.flags) + \ encoder.uint32(self.address or 0) + \ encoder.uint32(self.offset or 0) + \ encoder.uint32(self.content_size) + \ encoder.uint32(self.link_index) + \ encoder.uint32(self.info) + \ encoder.uint32(self.address_alignment) + \ encoder.uint32(self.entry_size) else: return encoder.uint32(self.name_index) + \ encoder.uint32(self.content_type) + \ encoder.uint64(self.flags) + \ encoder.uint64(self.address or 0) + \ encoder.uint64(self.offset or 0) + \ encoder.uint64(self.content_size) + \ encoder.uint32(self.link_index or 0) + \ encoder.uint32(self.info) + \ encoder.uint64(self.address_alignment) + \ encoder.uint64(self.entry_size)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) return encoder.uint32(self.id) + encoder.uint32(self.size)
def as_bytearray(self): import peachpy.encoder encoder = peachpy.encoder.Encoder(self.abi.endianness) if self.abi.pointer_size == 4: return encoder.fixed_string(self.name, 16) + \ encoder.fixed_string(self.segment_name, 16) + \ encoder.uint32(self.address or 0) + \ encoder.uint32(self.content_size) + \ encoder.uint32(self.offset) + \ encoder.uint32(self.alignment) + \ encoder.uint32(self.relocation_offset or 0) + \ encoder.uint32(self.relocation_count) + \ encoder.uint32(self.type | self.attributes) + \ bytearray(8) else: return encoder.fixed_string(self.name, 16) + \ encoder.fixed_string(self.segment_name, 16) + \ encoder.uint64(self.address or 0) + \ encoder.uint64(self.content_size) + \ encoder.uint32(self.offset) + \ encoder.uint32(self.alignment) + \ encoder.uint32(self.relocation_offset or 0) + \ encoder.uint32(self.relocation_count) + \ encoder.uint32(self.type | self.attributes) + \ bytearray(12)
def encode_command(self, encoder, section_offset_map, section_address_map, section_relocations_map): import peachpy.encoder assert isinstance(encoder, peachpy.encoder.Encoder) offset = section_offset_map[self.sections[0]] memory_size = sum(section.content_size for section in self.sections) file_size = sum(section.content_size for section in self.sections) address = 0 if self.sections: address = section_address_map[self.sections[0]] # TODO: combine the two cases if encoder.bitness == 32: command_id = 0x1 command_size = 56 + len(self.sections) * 68 command = encoder.uint32(command_id) + \ encoder.uint32(command_size) + \ encoder.fixed_string(self.name, 16) + \ encoder.uint32(address) + \ encoder.uint32(memory_size) + \ encoder.uint32(offset) + \ encoder.uint32(file_size) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(len(self.sections)) + \ encoder.uint32(self.flags) else: command_id = 0x19 command_size = 72 + len(self.sections) * 80 command = encoder.uint32(command_id) + \ encoder.uint32(command_size) + \ encoder.fixed_string(self.name, 16) + \ encoder.uint64(address) + \ encoder.uint64(memory_size) + \ encoder.uint64(offset) + \ encoder.uint64(file_size) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(MemoryProtection.default) + \ encoder.uint32(len(self.sections)) + \ encoder.uint32(self.flags) for section in self.sections: command += section.encode_command(encoder, section_offset_map[section], section_address_map[section], section_relocations_map.get(section)) from peachpy.x86_64.abi import system_v_x86_64_abi return command