Add ability to modify the similarity matrix to force matches

This commit is contained in:
Flawed
2023-10-03 00:59:44 -07:00
parent 54ee199a07
commit 9dc9416d4f
3 changed files with 59 additions and 13 deletions
+13 -1
View File
@@ -15,7 +15,13 @@ from utils import HexIntParamType
is_flag=True, is_flag=True,
help="Prints a column of the similarity matrix given a new opcode", help="Prints a column of the similarity matrix given a new opcode",
) )
def debug_similarity_matrix(similarity_json_file, opcode, reverse): @click.option(
"--accept",
default=None,
help="Modifies the similarity matrix file by accepting the match between the opcode argument and the argument to this option",
type=HexIntParamType(),
)
def debug_similarity_matrix(similarity_json_file, opcode, reverse, accept):
""" """
Given an old opcode, debug prints a row of the similarity matrix generated Given an old opcode, debug prints a row of the similarity matrix generated
from generate_similarity_matrix.py. from generate_similarity_matrix.py.
@@ -26,6 +32,12 @@ def debug_similarity_matrix(similarity_json_file, opcode, reverse):
entries = dict() entries = dict()
similarity = Similarity(similarity_json_file) similarity = Similarity(similarity_json_file)
if accept is not None:
similarity.accept(opcode, accept)
similarity.write_to_file(similarity_json_file)
return
if reverse: if reverse:
print("Checking column of matrix since --reverse was provided") print("Checking column of matrix since --reverse was provided")
for old_opcode in similarity.old_opcodes: for old_opcode in similarity.old_opcodes:
+15 -11
View File
@@ -99,6 +99,20 @@ def print_banner(text):
print("") print("")
def write_matrix_to_file(output_file, old_opcodes, new_opcodes, similarity_matrix):
with open(output_file, "w+") as f:
json.dump(
{
"old_opcodes": old_opcodes,
"new_opcodes": new_opcodes,
"matrix": similarity_matrix,
},
f,
indent=4,
)
print_banner(f"Output written to {output_file}")
@click.command() @click.command()
@click.argument( @click.argument(
"old_traces", type=click.Path(exists=True, file_okay=False, resolve_path=True) "old_traces", type=click.Path(exists=True, file_okay=False, resolve_path=True)
@@ -166,17 +180,7 @@ def generate_similarity_matrix(old_traces, new_traces, output_file):
csm, old_trace_data, new_trace_data csm, old_trace_data, new_trace_data
) )
with open(output_file, "w+") as f: write_matrix_to_file(output_file, old_opcodes, new_opcodes, similarity_matrix)
json.dump(
{
"old_opcodes": old_opcodes,
"new_opcodes": new_opcodes,
"matrix": similarity_matrix,
},
f,
indent=4,
)
print_banner(f"Output written to {output_file}")
if __name__ == "__main__": if __name__ == "__main__":
+31 -1
View File
@@ -4,6 +4,7 @@ import numpy as np
from vtable_diff import extract_opcode_data from vtable_diff import extract_opcode_data
from utils import eprint from utils import eprint
from generate_similarity_matrix import write_matrix_to_file
def needleman_wunsch(old_seq, new_seq, similarity, gap_penalty): def needleman_wunsch(old_seq, new_seq, similarity, gap_penalty):
@@ -103,6 +104,21 @@ class Similarity:
j = self.new_opcodes[new_opcode] j = self.new_opcodes[new_opcode]
return self.matrix[i][j] return self.matrix[i][j]
def accept(self, old_opcode, new_opcode):
if old_opcode not in self.old_opcodes:
self.warnings.add(
f"WARNING: Could not find old opcode {hex(old_opcode)} in similarity matrix"
)
return
if new_opcode not in self.new_opcodes:
self.warnings.add(
f"WARNING: Could not find new opcode {hex(new_opcode)} in similarity matrix"
)
return
i = self.old_opcodes[old_opcode]
j = self.new_opcodes[new_opcode]
self.matrix[i][j] = 1
def get_confident_matches(self, threshold=0.1): def get_confident_matches(self, threshold=0.1):
""" """
Returns matches in the form of [(old,new), ...] that are confidently Returns matches in the form of [(old,new), ...] that are confidently
@@ -149,6 +165,14 @@ class Similarity:
for warning in self.warnings: for warning in self.warnings:
eprint(warning) eprint(warning)
def write_to_file(self, output_file):
write_matrix_to_file(
output_file,
list(self.old_opcodes.keys()),
list(self.new_opcodes.keys()),
self.matrix.tolist(),
)
@click.command() @click.command()
@click.argument( @click.argument(
@@ -220,7 +244,13 @@ def vtable_alignment(old_exe, new_exe, similarity_json_file):
for old, new in alignment: for old, new in alignment:
if old in matched_old and matched_old[old] != new: if old in matched_old and matched_old[old] != new:
truth = matched_old[old] truth = matched_old[old]
eprint(f"Mismatch detected! {hex(old)} => {hex(truth)}, got {hex(new)}") mismatch_text = ""
if new is not None:
mismatch_text = hex(new)
eprint(
f"Mismatch detected! {hex(old)} => {hex(truth)}, got {mismatch_text}"
)
mismatched_old.add(old) mismatched_old.add(old)
mismatched_new[truth] = Placeholder(old, truth) mismatched_new[truth] = Placeholder(old, truth)