From 5c2bb2ef2df8964cbe0c318dd37a2174e032c823 Mon Sep 17 00:00:00 2001 From: Seliaste Date: Tue, 24 Mar 2026 11:20:28 +0100 Subject: [PATCH] added support for 64 bits and big-endian --- iat.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/iat.py b/iat.py index f0c17a4..570855d 100644 --- a/iat.py +++ b/iat.py @@ -18,9 +18,21 @@ def get_used_functions_from_dll(dllname,calls): return res def patch_call_to_new_IAT_entry(pe: lief.PE.Binary, call: dict[str,str], rva: int): - instruction_offset = int(call["adress"],16)-0x1000000 + base = pe.imagebase + instruction_offset = int(call["adress"],16)-base # We can manually patch the instruction here: FF 15 08 10 00 01 represents `call [0x01001080]` - pe.patch_address(instruction_offset, [0xFF,0x15,int(hex(rva)[4:6],16),int(hex(rva)[2:4],16),0x00,0x01], lief.Binary.VA_TYPES.RVA) + + adress_size = 4 if pe.abstract.header.is_32 else 8 + is_little_endian = pe.abstract.header.endianness == lief.Header.ENDIANNESS.LITTLE + new_value = [0x00]*adress_size + hex_adress = hex(rva + pe.imagebase)[::-1][:-2] # reversing order and stripping zero + for i in range(0,adress_size): + byte_str = hex_adress[i*2:(i+1)*2][::-1] + new_value[i] += int(byte_str,16) + if(not is_little_endian): + new_value = new_value[::-1] # reverse byte order for big endian + pe.patch_address(instruction_offset, [0xFF,0x15] + new_value, lief.Binary.VA_TYPES.RVA) + def patch_calls_to_new_IAT(pe: lief.PE.Binary, imp: lief.PE.Import, entry:lief.PE.ImportEntry, rva: int): # print(f"{imp.name}!{entry.name}: 0x{rva:010x}") @@ -40,12 +52,17 @@ with open("rsc/upx-hostname.exe.bin_iat_wave1.json", "r") as iat_json_input: calls:list[dict[str,str]] = iat_data["calls"] wave_entry = int(iat_data["entry"],16) +# Define all sections as writeable, to help with some weird stuff we're seeing +for section in pe.sections: + section.characteristics_lists.append(lief.PE.Section.CHARACTERISTICS.MEM_WRITE) + section.characteristics_lists.append(lief.PE.Section.CHARACTERISTICS.MEM_EXECUTE) + # patch entrypoint entrypoint_format = int(hex(wave_entry)[-4:],16) pe.optional_header.addressof_entrypoint = entrypoint_format # remove all current imports -pe.remove_all_imports() +# pe.remove_all_imports() # recreate all DLL imports for dll in get_used_dlls(calls):