From d9b1df165f9daad6a5229718ecd0ee50a5ef6bf1 Mon Sep 17 00:00:00 2001 From: Xusheng Date: Mon, 16 Nov 2020 17:51:46 +0800 Subject: add support for type xref and variable xref --- suite/binaries | 2 +- suite/generator.py | 26 ++++++++++++++++ suite/testcommon.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) (limited to 'suite') diff --git a/suite/binaries b/suite/binaries index 9ccb8fe2..596cd751 160000 --- a/suite/binaries +++ b/suite/binaries @@ -1 +1 @@ -Subproject commit 9ccb8fe2925388881eddf2c09902ba2103f0eee6 +Subproject commit 596cd75165649589d821ca3c26c7f4c7eba269c9 diff --git a/suite/generator.py b/suite/generator.py index 75a83ad6..bae35016 100755 --- a/suite/generator.py +++ b/suite/generator.py @@ -241,6 +241,32 @@ def generate(test_store, outdir, exclude_binaries): unittest = UnitTestFile(os.path.join(outdir, "unit.py"), outdir, test_store) oracle = OracleTestFile(os.path.join(outdir, "oracle")) + # check all files to see if there is any newly added ones. + # If so, create a zip archive for it and delete the original file + allfiles = sorted(testcommon.get_file_list(test_store)) + for progress, testfile in enumerate(allfiles): + oraclefile = None + zip_only = False + if testfile.endswith(".gitignore"): + continue + if testfile.endswith(".pkl"): + continue + elif testfile.endswith(".DS_Store"): + continue + elif testfile.endswith(".zip"): + continue + else: + if os.path.exists(testfile + ".zip"): + # We've got a zip file for it, skip + continue + + # create the zip archive for the file + if not os.path.exists(testfile + ".zip"): + with zipfile.ZipFile(testfile + ".zip", "w") as zf: + zf.write(testfile, os.path.relpath(testfile, start=os.path.dirname(__file__))) + + os.unlink(testfile) + # Generate the tests that don't involve binaries but do involve oracles builder = testcommon.TestBuilder(test_store) tests = builder.methods() diff --git a/suite/testcommon.py b/suite/testcommon.py index c7a48c77..fc936d59 100644 --- a/suite/testcommon.py +++ b/suite/testcommon.py @@ -1000,6 +1000,94 @@ class TestBuilder(Builder): finally: self.delete_package("helloworld") + def test_type_xref(self): + """Type xref failure""" + + def dump_type_xref_info(type_name, code_refs, data_refs, type_refs, offset = None): + retinfo = [] + if offset is None: + for ref in code_refs: + retinfo.append('type {} is referenced by code {}'.format(type_name, ref)) + for ref in data_refs: + retinfo.append('type {} is referenced by data {}'.format(type_name, ref)) + for ref in type_refs: + retinfo.append('type {} is referenced by type {}'.format(type_name, ref)) + else: + for ref in code_refs: + retinfo.append('type field {}, offset {} is referenced by code {}'.format(type_name, hex(offset), ref)) + for ref in data_refs: + retinfo.append('type field {}, offset {} is referenced by data {}'.format(type_name, hex(offset), ref)) + for ref in type_refs: + retinfo.append('type field {}, offset {} is referenced by type {}'.format(type_name, hex(offset), ref)) + + return retinfo + + retinfo = [] + file_name = self.unpackage_file("type_xref.bndb") + if not os.path.exists(file_name): + return retinfo + + with BinaryViewType.get_view_of_file(file_name) as bv: + if bv is None: + return retinfo + + types = bv.types + test_types = ['A', 'B', 'C', 'D', 'E', 'F'] + for test_type in test_types: + code_refs = bv.get_code_refs_for_type(test_type) + data_refs = bv.get_data_refs_for_type(test_type) + type_refs = bv.get_type_refs_for_type(test_type) + retinfo.extend(dump_type_xref_info(test_type, code_refs, data_refs, type_refs)) + + t = types[test_type] + if not t: + continue + + for member in t.structure.members: + offset = member.offset + code_refs = bv.get_code_refs_for_type_field(test_type, offset) + data_refs = bv.get_data_refs_for_type_field(test_type, offset) + type_refs = bv.get_type_refs_for_type_field(test_type, offset) + retinfo.extend(dump_type_xref_info(test_type, code_refs, data_refs, type_refs, offset)) + + self.delete_package("type_xref.bndb") + return fixOutput(sorted(retinfo)) + + def test_variable_xref(self): + """Variable xref failure""" + + def dump_var_xref_info(var, var_refs): + retinfo = [] + for ref in var_refs: + retinfo.append('var {} is referenced at {}'.format(repr(var), repr(ref))) + return retinfo + + retinfo = [] + file_name = self.unpackage_file("type_xref.bndb") + if not os.path.exists(file_name): + return retinfo + + with BinaryViewType.get_view_of_file(file_name) as bv: + if bv is None: + return retinfo + + func = bv.get_function_at(0x1169) + for var in func.vars: + mlil_refs = func.get_mlil_var_refs(var) + retinfo.extend(dump_var_xref_info(var, mlil_refs)) + hlil_refs = func.get_hlil_var_refs(var) + retinfo.extend(dump_var_xref_info(var, hlil_refs)) + + mlil_range_var_refs = func.get_mlil_var_refs_from(0x1175, 0x8c) + for ref in mlil_range_var_refs: + retinfo.append("var {} is referenced at {}".format(ref.var, ref.src)) + + hlil_range_var_refs = func.get_hlil_var_refs_from(0x1175, 0x8c) + for ref in hlil_range_var_refs: + retinfo.append("var {} is referenced at {}".format(ref.var, ref.src)) + + self.delete_package("type_xref.bndb") + return fixOutput(sorted(retinfo)) class VerifyBuilder(Builder): """ The VerifyBuilder is for tests that verify -- cgit v1.3.1