diff --git a/generate_diff_offset.py b/generate_diff_offset.py new file mode 100644 index 0000000..85d3494 --- /dev/null +++ b/generate_diff_offset.py @@ -0,0 +1,43 @@ +import click +import json + + +@click.command() +@click.argument("diff_file", type=click.File("r")) +@click.argument("offset", type=int) +def generate_diff_offset(diff_file, offset): + """ + Given a diff file, produces another diff file where the matches + are offset by OFFSET. + + Example: + python generate_diff_offset.py -- diff.json -1 > offset.diff.json + """ + diff_json = json.load(diff_file) + olds = [] + news = [] + for pair in diff_json: + if "old" not in pair or "new" not in pair: + continue + olds.append(pair["old"]) + news.append(pair["new"]) + + if offset < 0: + news = [[] for _ in range(-offset)] + news + if offset > 0: + olds = [[] for _ in range(offset)] + olds + + opcodes_object = [] + for old, new in zip(olds, news): + opcodes_object.append( + { + "old": old, + "new": new, + } + ) + + print(json.dumps(opcodes_object, indent=2)) + + +if __name__ == "__main__": + generate_diff_offset() diff --git a/sanity_check.py b/sanity_check.py index 50af5ce..9a3aa30 100644 --- a/sanity_check.py +++ b/sanity_check.py @@ -35,13 +35,22 @@ def sanity_check(vtable_diff, minor_patch_diff): for old_opcode, new_opcodes in diff2.items(): if old_opcode not in diff1: if len(new_opcodes) < 50: - print(f"Missing old opcode in vtable diff: {old_opcode}") + print(f"Missing old opcode in vtable diff: {hex(old_opcode)}") all_good = False continue other_new_opcodes = diff1[old_opcode] - if list(other_new_opcodes)[0] not in new_opcodes: - print(f"vtable diff mismatch for case {old_opcode} => {other_new_opcodes}") + vtable_new_opcode = None + if len(other_new_opcodes) > 0: + vtable_new_opcode = list(other_new_opcodes)[0] + elif len(new_opcodes) == 0: + continue + + if vtable_new_opcode not in new_opcodes: + new_text = ( + hex(vtable_new_opcode) if vtable_new_opcode is not None else "None" + ) + print(f"vtable diff mismatch for case {hex(old_opcode)} => {new_text}") all_good = False if all_good: diff --git a/vtable_alignment.py b/vtable_alignment.py index f3c4a50..7eb2c64 100644 --- a/vtable_alignment.py +++ b/vtable_alignment.py @@ -135,6 +135,7 @@ class Similarity: rev_top_matches = rev_scores[new_op] if ( rev_top_matches[0][0] == old_op + and rev_top_matches[0][1] > 0 and rev_top_matches[0][1] - rev_top_matches[1][1] >= threshold ): matches.append((old_op, new_op)) @@ -203,7 +204,7 @@ def vtable_alignment(old_exe, new_exe, similarity_json_file): filter(lambda x: x[0] in old_seq_set and x[1] in new_seq_set, matches) ) - eprint(f"Found {len(matches)} confident matches") + eprint(f'Found {len(matches)} "confident" matches') eprint("Running initial alignment...") alignment, score = needleman_wunsch(old_seq, new_seq, similarity, -1)