Format with black

This commit is contained in:
Flawed
2023-01-17 11:48:11 -08:00
parent 67653635b0
commit e783c72d11
4 changed files with 255 additions and 224 deletions
+6 -4
View File
@@ -27,16 +27,17 @@ desired_names = {
"ActorGauge": None, "ActorGauge": None,
"PlaceFieldMarkerPreset": "PresetWaymark", "PlaceFieldMarkerPreset": "PresetWaymark",
"PlaceFieldMarker": "Waymark", "PlaceFieldMarker": "Waymark",
"SystemLogMessage": None "SystemLogMessage": None,
} }
@click.command() @click.command()
@click.argument("opcodes_file", type=click.File('r')) @click.argument("opcodes_file", type=click.File("r"))
def generate_act_format(opcodes_file): def generate_act_format(opcodes_file):
opcode_mapping = dict() opcode_mapping = dict()
for line in opcodes_file.readlines(): for line in opcodes_file.readlines():
match_groups = re.findall(r'^\s*([^\/].*)=\s*(.*),\s*\/\/.*$', line) match_groups = re.findall(r"^\s*([^\/].*)=\s*(.*),\s*\/\/.*$", line)
if len(match_groups) != 1: if len(match_groups) != 1:
continue continue
@@ -53,9 +54,10 @@ def generate_act_format(opcodes_file):
desired = name desired = name
opcodes = opcode_mapping[name] opcodes = opcode_mapping[name]
if len(opcodes) == 1: if len(opcodes) == 1:
print(f'{desired}|{opcodes[0]:x}') print(f"{desired}|{opcodes[0]:x}")
elif len(opcodes) > 1: elif len(opcodes) > 1:
print(f'{desired}|{[f"{opcode:x}" for opcode in opcodes]}') print(f'{desired}|{[f"{opcode:x}" for opcode in opcodes]}')
if __name__ == "__main__": if __name__ == "__main__":
generate_act_format() generate_act_format()
+13 -5
View File
@@ -2,6 +2,7 @@ import json
import re import re
import click import click
def load_diff_file(f, reverse=False): def load_diff_file(f, reverse=False):
diff = dict() diff = dict()
diff_json = json.load(f) diff_json = json.load(f)
@@ -11,9 +12,12 @@ def load_diff_file(f, reverse=False):
old_key = "new" if reverse else "old" old_key = "new" if reverse else "old"
new_key = "old" if reverse else "new" new_key = "old" if reverse else "new"
for old_opcode in pair[old_key]: for old_opcode in pair[old_key]:
diff[int(old_opcode, 16)] = set((int(new_opcode, 16) for new_opcode in pair[new_key])) diff[int(old_opcode, 16)] = set(
(int(new_opcode, 16) for new_opcode in pair[new_key])
)
return diff return diff
def opcodes_str(opcodes): def opcodes_str(opcodes):
if len(opcodes) == 1: if len(opcodes) == 1:
return hex(list(opcodes)[0]) return hex(list(opcodes)[0])
@@ -22,8 +26,9 @@ def opcodes_str(opcodes):
else: else:
return "UNKNOWN" return "UNKNOWN"
def replace_line_with_new_opcode(line, diff, ver): def replace_line_with_new_opcode(line, diff, ver):
match_groups = re.findall(r'^\s*([^\/].*)=\s*(.*),\s*\/\/.*$', line) match_groups = re.findall(r"^\s*([^\/].*)=\s*(.*),\s*\/\/.*$", line)
if len(match_groups) != 1: if len(match_groups) != 1:
return line return line
@@ -42,14 +47,16 @@ def replace_line_with_new_opcode(line, diff, ver):
@click.command() @click.command()
@click.argument("new_version_string") @click.argument("new_version_string")
@click.argument("diff_file", type=click.File('r')) @click.argument("diff_file", type=click.File("r"))
@click.argument("opcodes_file", type=click.File('r')) @click.argument("opcodes_file", type=click.File("r"))
@click.option("--reverse", is_flag=True) @click.option("--reverse", is_flag=True)
def generate_opcodes_file(new_version_string, diff_file, opcodes_file, reverse): def generate_opcodes_file(new_version_string, diff_file, opcodes_file, reverse):
diff = load_diff_file(diff_file, reverse) diff = load_diff_file(diff_file, reverse)
queued_lines = [] queued_lines = []
for line in opcodes_file.readlines(): for line in opcodes_file.readlines():
queued_lines.append(replace_line_with_new_opcode(line, diff, new_version_string)) queued_lines.append(
replace_line_with_new_opcode(line, diff, new_version_string)
)
new_filename = f"{new_version_string}_opcodes.txt" new_filename = f"{new_version_string}_opcodes.txt"
with open(new_filename, "w+") as f: with open(new_filename, "w+") as f:
@@ -57,5 +64,6 @@ def generate_opcodes_file(new_version_string, diff_file, opcodes_file, reverse):
print("Wrote to", new_filename) print("Wrote to", new_filename)
if __name__ == "__main__": if __name__ == "__main__":
generate_opcodes_file() generate_opcodes_file()
+34 -16
View File
@@ -4,9 +4,10 @@ import re
ZONE_PROTO_DOWN_SIG = "48 89 ? 24 ? ? 48 83 EC 50 8B F2 49 8B" ZONE_PROTO_DOWN_SIG = "48 89 ? 24 ? ? 48 83 EC 50 8B F2 49 8B"
fucked_distance = 0xffffffff fucked_distance = 0xFFFFFFFF
max_size_diff = 10 max_size_diff = 10
def get_opcode_offset(r2): def get_opcode_offset(r2):
orig_loc = r2.cmd("s") # Save original spot orig_loc = r2.cmd("s") # Save original spot
r2.cmd("aei") # Initialize ESIL VM r2.cmd("aei") # Initialize ESIL VM
@@ -22,13 +23,14 @@ def get_opcode_offset(r2):
opcode_offset = regs["rdx"] - regs["rax"] opcode_offset = regs["rdx"] - regs["rax"]
# Clear the ESIL environment # Clear the ESIL environment
r2.cmd('ar0') r2.cmd("ar0")
r2.cmd('aeim-') r2.cmd("aeim-")
r2.cmd('aei-') r2.cmd("aei-")
r2.cmd(f"s {orig_loc}") # Seek back to original spot r2.cmd(f"s {orig_loc}") # Seek back to original spot
return opcode_offset return opcode_offset
def get_longest_switch(switch_cases): def get_longest_switch(switch_cases):
switches = dict() switches = dict()
@@ -55,12 +57,14 @@ def get_longest_switch(switch_cases):
return longest_switch return longest_switch
def get_block_sizes(blocks): def get_block_sizes(blocks):
block_sizes = dict() block_sizes = dict()
for block in blocks: for block in blocks:
block_sizes[block["addr"]] = block["size"] block_sizes[block["addr"]] = block["size"]
return block_sizes return block_sizes
def generate_opcode_db(packet_handler_ea, switch, opcode_offset, block_sizes): def generate_opcode_db(packet_handler_ea, switch, opcode_offset, block_sizes):
opcodes_db = dict() opcodes_db = dict()
@@ -74,6 +78,7 @@ def generate_opcode_db(packet_handler_ea, switch, opcode_offset, block_sizes):
} }
return opcodes_db return opcodes_db
def get_opcodes_db(exe_file): def get_opcodes_db(exe_file):
from utils import eprint, create_r2_byte_pattern, sync_r2_output from utils import eprint, create_r2_byte_pattern, sync_r2_output
@@ -112,18 +117,21 @@ def get_opcodes_db(exe_file):
## STEP 4: Process data ## STEP 4: Process data
packet_handler_switch = get_longest_switch(switch_cases) packet_handler_switch = get_longest_switch(switch_cases)
block_sizes = get_block_sizes(blocks) block_sizes = get_block_sizes(blocks)
opcode_db = generate_opcode_db(packet_handler_ea, packet_handler_switch, opcode_offset, block_sizes) opcode_db = generate_opcode_db(
packet_handler_ea, packet_handler_switch, opcode_offset, block_sizes
)
eprint(f" Loaded {len(opcode_db)} cases from packet handler") eprint(f" Loaded {len(opcode_db)} cases from packet handler")
return opcode_db return opcode_db
def find_closest_rel_ea(opcodes_db, dest): def find_closest_rel_ea(opcodes_db, dest):
closest = fucked_distance closest = fucked_distance
closest_opcode = None closest_opcode = None
for opcode, case in opcodes_db.items(): for opcode, case in opcodes_db.items():
rel_ea = case['rel_ea'] rel_ea = case["rel_ea"]
num = abs(rel_ea - dest) num = abs(rel_ea - dest)
@@ -132,27 +140,30 @@ def find_closest_rel_ea(opcodes_db, dest):
closest_opcode = opcode closest_opcode = opcode
return (closest, closest_opcode) return (closest, closest_opcode)
def get_opcodes_str(opcodes): def get_opcodes_str(opcodes):
return ', '.join([hex(o) for o in opcodes]) return ", ".join([hex(o) for o in opcodes])
def add_match_case(cases, case): def add_match_case(cases, case):
# check if case already exists # check if case already exists
for c in cases: for c in cases:
if c['rel_ea'] == case['rel_ea']: if c["rel_ea"] == case["rel_ea"]:
return return
cases.append(case) cases.append(case)
def find_opcode_matches(old_opcodes_db, new_opcodes_db): def find_opcode_matches(old_opcodes_db, new_opcodes_db):
matches = [] matches = []
new_opcodes = list(new_opcodes_db.keys()) new_opcodes = list(new_opcodes_db.keys())
for k, case in enumerate(old_opcodes_db.values()): for k, case in enumerate(old_opcodes_db.values()):
old_opcodes = case['opcodes'] old_opcodes = case["opcodes"]
# see if we can get a match for the relative ea first # see if we can get a match for the relative ea first
dist, dist_match_opcode = find_closest_rel_ea(new_opcodes_db, case['rel_ea']) dist, dist_match_opcode = find_closest_rel_ea(new_opcodes_db, case["rel_ea"])
if dist == fucked_distance: if dist == fucked_distance:
continue continue
@@ -162,18 +173,22 @@ def find_opcode_matches(old_opcodes_db, new_opcodes_db):
order_match = new_opcodes_db[order_match_opcode] order_match = new_opcodes_db[order_match_opcode]
dist_match = new_opcodes_db[dist_match_opcode] dist_match = new_opcodes_db[dist_match_opcode]
size_diff = abs(dist_match['size'] - case['size']) size_diff = abs(dist_match["size"] - case["size"])
# see if the rva matches for the cases found by the distance and order # see if the rva matches for the cases found by the distance and order
if dist_match['rel_ea'] == order_match['rel_ea'] and size_diff < max_size_diff: if dist_match["rel_ea"] == order_match["rel_ea"] and size_diff < max_size_diff:
matches.append((old_opcodes, order_match["opcodes"])) matches.append((old_opcodes, order_match["opcodes"]))
return matches return matches
@click.command() @click.command()
@click.argument("old_exe", type=click.Path(exists=True, dir_okay=False, resolve_path=True)) @click.argument(
@click.argument("new_exe", type=click.Path(exists=True, dir_okay=False, resolve_path=True)) "old_exe", type=click.Path(exists=True, dir_okay=False, resolve_path=True)
)
@click.argument(
"new_exe", type=click.Path(exists=True, dir_okay=False, resolve_path=True)
)
def minor_patch_diff(old_exe, new_exe): def minor_patch_diff(old_exe, new_exe):
old_opcodes_db = get_opcodes_db(old_exe) old_opcodes_db = get_opcodes_db(old_exe)
new_opcodes_db = get_opcodes_db(new_exe) new_opcodes_db = get_opcodes_db(new_exe)
@@ -184,12 +199,15 @@ def minor_patch_diff(old_exe, new_exe):
for k, v in enumerate(opcodes_found): for k, v in enumerate(opcodes_found):
old, new = v old, new = v
opcodes_object.append({ opcodes_object.append(
{
"old": [hex(o) for o in old], "old": [hex(o) for o in old],
"new": [hex(o) for o in new], "new": [hex(o) for o in new],
}) }
)
print(json.dumps(opcodes_object, indent=2)) print(json.dumps(opcodes_object, indent=2))
if __name__ == "__main__": if __name__ == "__main__":
minor_patch_diff() minor_patch_diff()
+3
View File
@@ -1,9 +1,11 @@
import sys import sys
import time import time
def eprint(*args, **kwargs): def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs) print(*args, file=sys.stderr, **kwargs)
def create_r2_byte_pattern(sig): def create_r2_byte_pattern(sig):
tokens = sig.split() tokens = sig.split()
r2_tokens = [] r2_tokens = []
@@ -14,6 +16,7 @@ def create_r2_byte_pattern(sig):
r2_tokens.append(token) r2_tokens.append(token)
return "".join(r2_tokens) return "".join(r2_tokens)
def sync_r2_output(r2): def sync_r2_output(r2):
""" """
For some fucking reason r2pipe output gets desynced from the start, For some fucking reason r2pipe output gets desynced from the start,