diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a628b9d..daa6bd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - ### Bug Fixes +- fix: add return after zero-offset yield in extract_insn_offset_features so Offset(0) is not emitted twice @williballenthin - fix: use f-string in binexport2 extractor so unexpected global feature value appears in ValueError message @williballenthin - fix: correct scale/displacement expressions in get_operand_phrase_info 5-expression branch (used expression3 operator instead of expression4 value) @williballenthin - fix: use HasField instead of truthiness in _index_vertex_edges so call-graph edges to/from vertex 0 are not silently dropped @williballenthin diff --git a/capa/features/extractors/binexport2/arch/intel/insn.py b/capa/features/extractors/binexport2/arch/intel/insn.py index 36fd8cc6..8cc1be40 100644 --- a/capa/features/extractors/binexport2/arch/intel/insn.py +++ b/capa/features/extractors/binexport2/arch/intel/insn.py @@ -136,6 +136,7 @@ def extract_insn_offset_features( yield Offset(0), ih.address yield OperandOffset(match.operand_index, 0), ih.address + return value = mask_immediate(fhi.arch, match.expression.immediate) if is_address_mapped(be2, value): diff --git a/tests/fixtures.py b/tests/fixtures.py index 2b8c2918..12d79c14 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -1544,6 +1544,22 @@ FEATURE_COUNT_TESTS_GHIDRA = [ ("mimikatz", "function=0x401000", capa.features.basicblock.BasicBlock(), 3), ] +FEATURE_COUNT_TESTS_BE2_INTEL = [ + # 0x401125: MOV [EDI], CX -- matches OFFSET_ZERO_PATTERNS, must yield Offset(0) exactly once + ( + "mimikatz", + "function=0x40105d,bb=0x401125,insn=0x401125", + capa.features.insn.Offset(0), + 1, + ), + ( + "mimikatz", + "function=0x40105d,bb=0x401125,insn=0x401125", + capa.features.insn.OperandOffset(1, 0), + 1, + ), +] + def do_test_feature_presence(get_extractor, sample, scope, feature, expected): extractor = get_extractor(sample) diff --git a/tests/test_binexport_features.py b/tests/test_binexport_features.py index 2695230c..25b13a80 100644 --- a/tests/test_binexport_features.py +++ b/tests/test_binexport_features.py @@ -446,3 +446,14 @@ def test_binexport_feature_counts_ghidra(sample, scope, feature, expected): sample = sample.parent / "binexport2" / (sample.name + ".ghidra.BinExport") assert sample.exists() fixtures.do_test_feature_count(fixtures.get_binexport_extractor, sample, scope, feature, expected) + + +@fixtures.parametrize( + "sample,scope,feature,expected", + fixtures.FEATURE_COUNT_TESTS_BE2_INTEL, + indirect=["sample", "scope"], +) +def test_binexport_feature_counts_intel(sample, scope, feature, expected): + sample = sample.parent / "binexport2" / (sample.name + ".ghidra.BinExport") + assert sample.exists() + fixtures.do_test_feature_count(fixtures.get_binexport_extractor, sample, scope, feature, expected)