added support for 64 bits and big-endian
This commit is contained in:
parent
0adfe97012
commit
5c2bb2ef2d
1 changed files with 20 additions and 3 deletions
23
iat.py
23
iat.py
|
|
@ -18,9 +18,21 @@ def get_used_functions_from_dll(dllname,calls):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def patch_call_to_new_IAT_entry(pe: lief.PE.Binary, call: dict[str,str], rva: int):
|
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]`
|
# 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):
|
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}")
|
# 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"]
|
calls:list[dict[str,str]] = iat_data["calls"]
|
||||||
wave_entry = int(iat_data["entry"],16)
|
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
|
# patch entrypoint
|
||||||
entrypoint_format = int(hex(wave_entry)[-4:],16)
|
entrypoint_format = int(hex(wave_entry)[-4:],16)
|
||||||
pe.optional_header.addressof_entrypoint = entrypoint_format
|
pe.optional_header.addressof_entrypoint = entrypoint_format
|
||||||
|
|
||||||
# remove all current imports
|
# remove all current imports
|
||||||
pe.remove_all_imports()
|
# pe.remove_all_imports()
|
||||||
|
|
||||||
# recreate all DLL imports
|
# recreate all DLL imports
|
||||||
for dll in get_used_dlls(calls):
|
for dll in get_used_dlls(calls):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue