74 lines
3.2 KiB
Python
74 lines
3.2 KiB
Python
from utils import hex_address_to_memory_representation
|
|
import lief
|
|
|
|
def patch_direct_adress_call(pe: lief.PE.Binary, rva: int, instruction_offset: int):
|
|
# We can manually patch the instruction here: FF 15 08 10 00 01 represents `call [0x01001080]`
|
|
new_value = hex_address_to_memory_representation(
|
|
hex(rva + pe.imagebase),
|
|
pe.abstract.header.is_32,
|
|
pe.abstract.header.endianness == lief.Header.ENDIANNESS.LITTLE,
|
|
)
|
|
pe.patch_address(instruction_offset, [0xFF, 0x15] + new_value, lief.Binary.VA_TYPES.RVA)
|
|
|
|
|
|
def patch_direct_adress_jump(pe: lief.PE.Binary, rva: int, instruction_offset: int):
|
|
# We can manually patch the instruction here: FF 15 08 10 00 01 represents `call [0x01001080]`
|
|
new_value = hex_address_to_memory_representation(
|
|
hex(rva + pe.imagebase),
|
|
pe.abstract.header.is_32,
|
|
pe.abstract.header.endianness == lief.Header.ENDIANNESS.LITTLE,
|
|
)
|
|
pe.patch_address(instruction_offset, [0xFF, 0x25] + new_value, lief.Binary.VA_TYPES.RVA)
|
|
|
|
|
|
def patch_instr_to_new_IAT_entry(pe: lief.PE.Binary, call: dict[str, str], rva: int):
|
|
base = pe.imagebase
|
|
instruction_offset = int(call["adress"], 16) - base
|
|
memview = pe.get_content_from_virtual_address(instruction_offset, 2)
|
|
if [memview[0], memview[1]] == [0xFF, 0x15]:
|
|
patch_direct_adress_call(pe, rva, instruction_offset)
|
|
elif [memview[0], memview[1]] == [0xFF, 0x25]:
|
|
patch_direct_adress_jump(pe, rva, instruction_offset)
|
|
|
|
|
|
def patch_addr_found_in_mem(pe: lief.PE.Binary, rva: int, old_addr: str):
|
|
is_32 = pe.abstract.header.is_32
|
|
little_endian = pe.abstract.header.endianness == lief.Header.ENDIANNESS.LITTLE
|
|
# scan memory for reference to old addr
|
|
old_addr_mem_repr = hex_address_to_memory_representation(
|
|
old_addr,
|
|
is_32,
|
|
pe.abstract.header.endianness == lief.Header.ENDIANNESS.LITTLE,
|
|
)
|
|
new_addr = hex_address_to_memory_representation(
|
|
hex(rva + pe.imagebase),
|
|
is_32,
|
|
little_endian,
|
|
)
|
|
adresses_to_patch = []
|
|
for section in pe.sections:
|
|
for i in range(len(section.content)):
|
|
found = True
|
|
for j in range(len(old_addr_mem_repr)):
|
|
if i + j >= len(section.content) or section.content[i + j] != old_addr_mem_repr[j]:
|
|
found = False
|
|
break
|
|
if found:
|
|
old_addr_ref = hex_address_to_memory_representation(
|
|
hex(
|
|
section.virtual_address + i + pe.imagebase,
|
|
),
|
|
is_32,
|
|
little_endian,
|
|
)
|
|
for section in pe.sections:
|
|
for k in range(len(section.content)):
|
|
foundxref = True
|
|
for L in range(len(old_addr_ref)):
|
|
if k + L < len(section.content) and section.content[k + L] != old_addr_ref[L]:
|
|
foundxref = False
|
|
break
|
|
if foundxref:
|
|
adresses_to_patch.append(section.virtual_address + k)
|
|
for addr in adresses_to_patch:
|
|
pe.patch_address(addr, new_addr, lief.Binary.VA_TYPES.RVA)
|