diff --git a/CHANGELOG.md b/CHANGELOG.md index 42fc57f06..bfc82a659 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ ### Bug Fixes - fix circular import error #825 @williballenthin +- fix smda negative number extraction #430 @kn0wl3dge ### capa explorer IDA Pro plugin diff --git a/capa/features/extractors/smda/insn.py b/capa/features/extractors/smda/insn.py index d666728c6..a42db3ce6 100644 --- a/capa/features/extractors/smda/insn.py +++ b/capa/features/extractors/smda/insn.py @@ -84,8 +84,12 @@ def extract_insn_number_features(f, bb, insn): return for operand in operands: try: - yield Number(int(operand, 16)), insn.offset - yield Number(int(operand, 16), bitness=get_bitness(f.smda_report)), insn.offset + # The result of bitwise operations is calculated as though carried out + # in two’s complement with an infinite number of sign bits + value = int(operand, 16) & ((1 << f.smda_report.bitness) - 1) + + yield Number(value), insn.offset + yield Number(value, bitness=get_bitness(f.smda_report)), insn.offset except: continue diff --git a/scripts/show-features.py b/scripts/show-features.py index 2cbacc1f6..a4f7f3b21 100644 --- a/scripts/show-features.py +++ b/scripts/show-features.py @@ -86,7 +86,7 @@ def main(argv=None): argv = sys.argv[1:] parser = argparse.ArgumentParser(description="Show the features that capa extracts from the given sample") - capa.main.install_common_args(parser, wanted={"format", "sample", "signatures"}) + capa.main.install_common_args(parser, wanted={"format", "sample", "signatures", "backend"}) parser.add_argument("-F", "--function", type=lambda x: int(x, 0x10), help="Show features for specific function") args = parser.parse_args(args=argv) @@ -111,7 +111,7 @@ def main(argv=None): should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None) try: extractor = capa.main.get_extractor( - args.sample, args.format, capa.main.BACKEND_VIV, sig_paths, should_save_workspace + args.sample, args.format, args.backend, sig_paths, should_save_workspace ) except capa.main.UnsupportedFormatError: logger.error("-" * 80) diff --git a/tests/fixtures.py b/tests/fixtures.py index e58ffbcbc..5ec434cf1 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -413,6 +413,7 @@ def parametrize(params, values, **kwargs): # insn/number ("mimikatz", "function=0x40105D", capa.features.insn.Number(0xFF), True), ("mimikatz", "function=0x40105D", capa.features.insn.Number(0x3136B0), True), + ("mimikatz", "function=0x401000", capa.features.insn.Number(0x0), True), # insn/number: stack adjustments ("mimikatz", "function=0x40105D", capa.features.insn.Number(0xC), False), ("mimikatz", "function=0x40105D", capa.features.insn.Number(0x10), False), @@ -420,6 +421,9 @@ def parametrize(params, values, **kwargs): ("mimikatz", "function=0x40105D", capa.features.insn.Number(0xFF), True), ("mimikatz", "function=0x40105D", capa.features.insn.Number(0xFF, bitness=BITNESS_X32), True), ("mimikatz", "function=0x40105D", capa.features.insn.Number(0xFF, bitness=BITNESS_X64), False), + # insn/number: negative + ("mimikatz", "function=0x401553", capa.features.insn.Number(0xFFFFFFFF), True), + ("mimikatz", "function=0x43e543", capa.features.insn.Number(0xFFFFFFF0), True), # insn/offset ("mimikatz", "function=0x40105D", capa.features.insn.Offset(0x0), True), ("mimikatz", "function=0x40105D", capa.features.insn.Offset(0x4), True),