Skip to content

Commit

Permalink
Merge pull request mandiant#215 from fireeye/fix/assert-ida-version-e…
Browse files Browse the repository at this point in the history
…xplorer

capa explorer plugin: assert IDA version
  • Loading branch information
mr-tz authored Jul 31, 2020
2 parents c26c8d5 + 418e825 commit 0f908da
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
36 changes: 33 additions & 3 deletions capa/ida/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@
import datetime

import idc
import six
import idaapi
import idautils

import capa

logger = logging.getLogger("capa")

SUPPORTED_IDA_VERSIONS = [
"7.1",
"7.2",
"7.3",
"7.4",
"7.5",
]

# file type names as returned by idaapi.get_file_type_name()
SUPPORTED_FILE_TYPES = [
"Portable executable for 80386 (PE)",
Expand All @@ -29,6 +38,19 @@ def inform_user_ida_ui(message):
idaapi.info("%s. Please refer to IDA Output window for more information." % message)


def is_supported_ida_version():
version = idaapi.get_kernel_version()
if version not in SUPPORTED_IDA_VERSIONS:
warning_msg = "This plugin does not support your IDA Pro version"
logger.warning(warning_msg)
logger.warning(
"Your IDA Pro version is: %s. Supported versions are: %s." % (version, ", ".join(SUPPORTED_IDA_VERSIONS))
)
capa.ida.helpers.inform_user_ida_ui(warning_msg)
return False
return True


def is_supported_file_type():
file_type = idaapi.get_file_type_name()
if file_type not in SUPPORTED_FILE_TYPES:
Expand Down Expand Up @@ -63,13 +85,21 @@ def get_func_start_ea(ea):


def collect_metadata():
md5 = idautils.GetInputFileMD5()
if not isinstance(md5, six.string_types):
md5 = capa.features.bytes_to_str(md5)

sha256 = idaapi.retrieve_input_file_sha256()
if not isinstance(sha256, six.string_types):
sha256 = capa.features.bytes_to_str(sha256)

return {
"timestamp": datetime.datetime.now().isoformat(),
# "argv" is not relevant here
"sample": {
"md5": capa.features.bytes_to_str(idautils.GetInputFileMD5()),
# "sha1" not easily accessible
"sha256": capa.features.bytes_to_str(idaapi.retrieve_input_file_sha256()),
"md5": md5,
"sha1": "", # not easily accessible
"sha256": sha256,
"path": idaapi.get_input_file_path(),
},
"analysis": {"format": idaapi.get_file_type_name(), "extractor": "ida",},
Expand Down
3 changes: 3 additions & 0 deletions capa/ida/ida_capa_explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,9 @@ def main():
""" TODO: move to idaapi.plugin_t class """
logging.basicConfig(level=logging.INFO)

if not capa.ida.helpers.is_supported_ida_version():
return -1

if not capa.ida.helpers.is_supported_file_type():
return -1

Expand Down
6 changes: 5 additions & 1 deletion capa/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,9 @@ def ida_main():
logging.basicConfig(level=logging.INFO)
logging.getLogger().setLevel(logging.INFO)

if not capa.ida.helpers.is_supported_ida_version():
return -1

if not capa.ida.helpers.is_supported_file_type():
return -1

Expand All @@ -636,14 +639,15 @@ def ida_main():
rules = get_rules(rules_path)
rules = capa.rules.RuleSet(rules)

meta = collect_metadata([], "", rules_path, format, "IdaExtractor")
meta = capa.ida.helpers.collect_metadata()

capabilities, counts = find_capabilities(rules, capa.features.extractors.ida.IdaFeatureExtractor())
meta["analysis"].update(counts)

if has_file_limitation(rules, capabilities, is_standalone=False):
capa.ida.helpers.inform_user_ida_ui("capa encountered warnings during analysis")

colorama.init(strip=True)
print(capa.render.render_default(meta, rules, capabilities))


Expand Down

0 comments on commit 0f908da

Please sign in to comment.