diff --git a/capa/features/extractors/ida/file.py b/capa/features/extractors/ida/file.py index b75c34752..5ca2370d5 100644 --- a/capa/features/extractors/ida/file.py +++ b/capa/features/extractors/ida/file.py @@ -95,7 +95,14 @@ def extract_file_import_names(): - importname """ for (ea, info) in capa.features.extractors.ida.helpers.get_file_imports().items(): - if info[1]: + if info[1] and info[2]: + # e.g. in mimikatz: ('cabinet', 'FCIAddFile', 11L) + # extract by name here and by ordinal below + for name in capa.features.extractors.helpers.generate_symbols(info[0], info[1]): + yield Import(name), ea + dll = info[0] + symbol = "#%d" % (info[2]) + elif info[1]: dll = info[0] symbol = info[1] elif info[2]: diff --git a/tests/fixtures.py b/tests/fixtures.py index ff861875d..3d8ff617e 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -427,6 +427,12 @@ def parametrize(params, values, **kwargs): ("mimikatz", "function=0x4556E5", capa.features.Characteristic("calls to"), False), ] +FEATURE_PRESENCE_TESTS_IDA = [ + # file/imports + # IDA can recover more names of APIs imported by ordinal + ("mimikatz", "file", capa.features.file.Import("cabinet.FCIAddFile"), True), +] + FEATURE_COUNT_TESTS = [ ("mimikatz", "function=0x40E5C2", capa.features.basicblock.BasicBlock(), 7), ("mimikatz", "function=0x4702FD", capa.features.Characteristic("calls from"), 0), diff --git a/tests/test_ida_features.py b/tests/test_ida_features.py index b227775e2..51de21390 100644 --- a/tests/test_ida_features.py +++ b/tests/test_ida_features.py @@ -44,7 +44,7 @@ def get_ida_extractor(_path): @pytest.mark.skip(reason="IDA Pro tests must be run within IDA") def test_ida_features(): - for (sample, scope, feature, expected) in FEATURE_PRESENCE_TESTS: + for (sample, scope, feature, expected) in FEATURE_PRESENCE_TESTS + FEATURE_PRESENCE_TESTS_IDA: id = make_test_id((sample, scope, feature, expected)) try: