def test_basic(self): sio = BytesIO(b'abcdef') with preserve_stream_pos(sio): sio.seek(4) self.assertEqual(sio.tell(), 0) sio.seek(5) with preserve_stream_pos(sio): sio.seek(0) self.assertEqual(sio.tell(), 5)
def test_basic(self): sio = BytesIO('abcdef') with preserve_stream_pos(sio): sio.seek(4) self.assertEqual(stream.tell(), 0) sio.seek(5) with preserve_stream_pos(sio): sio.seek(0) self.assertEqual(stream.tell(), 5)
def get_jumptable(instrs, stream, function_start, function_end): # get info: jump table start address (jt_addr) and how it is formatted (location_method) lea_instr, i = get_lea(instrs) if not i: return None jt_addr = lea_instr["ptr_address"] location_method, offset_size = get_location_method(instrs, i) # get entries with preserve_stream_pos(stream): stream.seek(jt_addr) jmp_addr = get_jump_address(location_method, jt_addr, offset_size, stream) jmp_index = 0 # maps the jumpTo address x to an array of the jump table indexes that map to x jumps = {} prev_jmp_addr = -1 while function_start <= jmp_addr <= function_end: jumps = upsert(jumps, hex(jmp_addr), jmp_index, hex(prev_jmp_addr)) prev_jmp_addr = jmp_addr jmp_addr = get_jump_address(location_method, jt_addr, offset_size, stream) jmp_index += 1 # format jumps res = [] for addr in jumps: res.append({"address": addr, "indices": jumps[addr]}) res.sort(key=lambda x: x["indices"][0]) # strings (aka ranges) will be last return res
def get_elfdata_mapping(self, elffile: ELFFile) -> bytes: elfdata_mapping = bytearray() # pick up elf header with preserve_stream_pos(elffile.stream): elffile.stream.seek(0) elf_header = elffile.stream.read(elffile['e_ehsize']) elfdata_mapping.extend(elf_header) # pick up loadable sections and relocate them if needed for sec in elffile.iter_sections(): if sec['sh_flags'] & SH_FLAGS.SHF_ALLOC: # pad aggregated elf data to the offset of the current section elfdata_mapping.extend( b'\x00' * (sec['sh_offset'] - len(elfdata_mapping))) # aggregate section data elfdata_mapping.extend(sec.data()) return bytes(elfdata_mapping)