From f9543b52ce7bc10b3c474936d9ce2b7404a278a2 Mon Sep 17 00:00:00 2001 From: Flawed <33593723+ff14wed@users.noreply.github.com> Date: Tue, 5 Aug 2025 17:33:18 -0700 Subject: [PATCH] Add more divergent branching to handle 7.3+ --- generate_act_format.py | 1 + generate_deep_traces.py | 11 ++++++++--- minor_patch_diff.py | 43 ++++++++++++++++++++++++++++++++++------- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/generate_act_format.py b/generate_act_format.py index db0d2d8..0a23baa 100644 --- a/generate_act_format.py +++ b/generate_act_format.py @@ -7,6 +7,7 @@ desired_names = { "StatusEffectList2": None, "StatusEffectList3": None, "BossStatusEffectList": None, + "StatusEffectList4": "StatusEffectListForay3", "Effect": "Ability1", "AoeEffect8": "Ability8", "AoeEffect16": "Ability16", diff --git a/generate_deep_traces.py b/generate_deep_traces.py index 6db7ea2..91c6271 100644 --- a/generate_deep_traces.py +++ b/generate_deep_traces.py @@ -4,12 +4,13 @@ import pathlib import semver from minor_patch_diff import ( + get_opcode_offset_7_30, get_sem_ver, get_opcode_offset, get_opcode_offset_7_20, get_correct_switch, get_zone_proto_down_sig, - get_opcode_offset_sig + get_opcode_offset_sig, ) @@ -166,7 +167,9 @@ def extract_opcode_data(exe_file): packet_handler_ea = int(opcode_offset_target, 16) r2.cmd(f"s {opcode_offset_target}") # Seek to target - if semver.compare(sem_ver, "7.2.0") >= 0: + if semver.compare(sem_ver, "7.3.0") >= 0: + opcode_offset = get_opcode_offset_7_30(r2) + elif semver.compare(sem_ver, "7.2.0") >= 0: opcode_offset = get_opcode_offset_7_20(r2) else: opcode_offset = get_opcode_offset(r2) @@ -178,7 +181,9 @@ def extract_opcode_data(exe_file): fn_graph = r2.cmdj(f"pdrj") ## STEP 4: Process data - switch_ea, packet_handler_switch = get_correct_switch(packet_handler_ea, switch_cases) + switch_ea, packet_handler_switch = get_correct_switch( + packet_handler_ea, switch_cases + ) eprint(f" Found switch at {switch_ea}") opcodes_db, blocks = generate_opcodes_db( diff --git a/minor_patch_diff.py b/minor_patch_diff.py index fe23160..2ea275d 100644 --- a/minor_patch_diff.py +++ b/minor_patch_diff.py @@ -8,23 +8,28 @@ max_size_diff = 10 def get_sem_ver(exe_file: str): - res = re.match(".*ffxiv_dx11\.(\d).(\d)(\d)(\w?)\.exe", exe_file) + res = re.match(".*ffxiv_dx11\.(\d).(\d)(\d)(\w?)(\d?)\.exe", exe_file) sem_ver = f"{res.group(1)}.{res.group(2)}.{res.group(3)}" if res.group(4) != "": sem_ver = f"{sem_ver}+{res.group(4)}" return sem_ver + def get_zone_proto_down_sig(sem_ver: str): - if semver.compare(sem_ver, "7.2.0") >= 0: + if semver.compare(sem_ver, "7.3.0") >= 0: + return "48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 0F B7 68 ?" + elif semver.compare(sem_ver, "7.2.0") >= 0: return "40 55 53 56 57 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 0F B7 78 ?" - # return "E8 ? ? ? ? 41 83 C7 9A EB 1B" elif semver.compare(sem_ver, "6.4.0") >= 0: return "40 53 56 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 44 24 ? 8B F2" else: return "48 89 ? 24 ? ? 48 83 EC 50 8B F2 49 8B" + def get_opcode_offset_sig(sem_ver: str): - if semver.compare(sem_ver, "7.2.0") >= 0: + if semver.compare(sem_ver, "7.3.0") >= 0: + return "E8 ? ? ? ? 41 83 C5 ? 49 8B FC" + elif semver.compare(sem_ver, "7.2.0") >= 0: return "E8 ? ? ? ? 41 83 C7 ? EB 1B" elif semver.compare(sem_ver, "6.4.0") >= 0: return "40 53 56 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 44 24 ? 8B F2" @@ -32,12 +37,33 @@ def get_opcode_offset_sig(sem_ver: str): return "48 89 ? 24 ? ? 48 83 EC 50 8B F2 49 8B" +def get_opcode_offset_7_30(r2): + orig_loc = r2.cmd("s") # Save original spot + r2.cmd("aei") # Initialize ESIL VM + r2.cmd("aeim") # Initialize ESIL VM stack + r2.cmd("aeip") # Initialize ESIL VM IP to curseek + r2.cmd("aeso") # step over call + r2.cmd("aer r13=0x500") # set r15 to some arbitrary number + r2.cmd("aeso") # step + + regs = r2.cmdj("arj") + opcode_offset = 0x500 - regs["r13"] + + # Clear the ESIL environment + r2.cmd("ar0") + r2.cmd("aeim-") + r2.cmd("aei-") + r2.cmd(f"s {orig_loc}") # Seek back to original spot + + return opcode_offset + + def get_opcode_offset_7_20(r2): orig_loc = r2.cmd("s") # Save original spot r2.cmd("aei") # Initialize ESIL VM r2.cmd("aeim") # Initialize ESIL VM stack r2.cmd("aeip") # Initialize ESIL VM IP to curseek - r2.cmd("aeso") # step over call + r2.cmd("aeso") # step over call r2.cmd("aer r15=0x500") # set r15 to some arbitrary number r2.cmd("aeso") # step @@ -52,6 +78,7 @@ def get_opcode_offset_7_20(r2): return opcode_offset + def get_opcode_offset(r2): orig_loc = r2.cmd("s") # Save original spot r2.cmd("aei") # Initialize ESIL VM @@ -99,7 +126,7 @@ def get_correct_switch(approx_ea, switch_cases): longest_switch = dict() for switch_ea in switches: int_switch_ea = int(switch_ea, 16) - if int_switch_ea < approx_ea or int_switch_ea > approx_ea+0x100: + if int_switch_ea < approx_ea or int_switch_ea > approx_ea + 0x100: continue if len(switches[switch_ea].keys()) > len(longest_switch): found_switch = switch_ea @@ -174,7 +201,9 @@ def extract_opcode_data(exe_file): eprint(f" Grabbed blocks from packet handler") ## STEP 4: Process data - switch_ea, packet_handler_switch = get_correct_switch(packet_handler_ea, switch_cases) + switch_ea, packet_handler_switch = get_correct_switch( + packet_handler_ea, switch_cases + ) eprint(f" Found switch at {switch_ea}") block_sizes = get_block_sizes(blocks)