def get_reloc_diff(rinstrs):
"""When reordering relocatable instructions, we also need to update
the relocation info. This function returns a byte diff of the relocation
section."""
diff = []
relocations = {}
# TODO cache relocations
pe = pefile.PE(inp_dump.get_input_file_path(), fast_load=True)
pe.parse_data_directories(directories=[
pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_BASERELOC']])
if pe.OPTIONAL_HEADER.DATA_DIRECTORY[5].Size > 0:
for base_reloc in pe.DIRECTORY_ENTRY_BASERELOC:
for reloc in filter(lambda x: x.type == 3, base_reloc.entries): # HIGHLOW
relocations[reloc.rva] = reloc.struct.get_file_offset()
base = pe.OPTIONAL_HEADER.ImageBase
# now check if we reordered any relocatable data
for rins in filter(lambda x: x.inst_len >= 5, rinstrs):
# print rins.disas, hex(rins.addr), hex(rins.raddr)
# a relocatable ref can be found after the first byte (opcode) and is
# 4 bytes long (no need to check the last three bytes of the instruction)
for rva in xrange(rins.addr - base + 1, rins.addr - base + rins.inst_len - 3):
if rva in relocations:
foff = relocations[rva]
new_rva = rva + rins.raddr - rins.addr
new_rva_h = ((new_rva >> 8) & 0xf) | 3 << 4 # 3 is HIGHLOW
# print "relocations: %x %x %x %x %x %x %x" % (rva, new_rva, rva & 0xff,
# new_rva & 0xff, (rva >> 8) & 0xff, (new_rva >> 8) & 0xff, new_rva_h)
diff.append((foff + 1, chr((rva >> 8) & 0xff), chr(new_rva_h)))
diff.append((foff, chr(rva & 0xff), chr(new_rva & 0xff)))
return diff
评论列表
文章目录