Merge pull request #115 from fireeye/fix-102

#102 #87
This commit is contained in:
Moritz
2020-07-07 15:02:11 +02:00
committed by GitHub
4 changed files with 15 additions and 8 deletions

View File

@@ -7,7 +7,6 @@ from capa.features import MAX_BYTES_FEATURE_SIZE, Bytes, String, Characteristic
from capa.features.insn import Number, Offset, Mnemonic
from capa.features.extractors.viv.indirect_calls import NotFoundError, resolve_indirect_call
# security cookie checks may perform non-zeroing XORs, these are expected within a certain
# byte range within the first and returning basic blocks, this helps to reduce FP features
SECURITY_COOKIE_BYTES_DELTA = 0x40

View File

@@ -22,7 +22,7 @@ class Number(Feature):
class Offset(Feature):
def __init__(self, value, description=None):
super(Offset, self).__init__([value])
super(Offset, self).__init__([value], description)
self.value = value
def get_args_str(self):

View File

@@ -82,7 +82,7 @@ def render_feature(ostream, match, feature, indent=0):
ostream.write(rutils.bold2(feature[feature["type"]]))
if "description" in feature:
ostream.write(" = ")
ostream.write(capa.rules.DESCRIPTION_SEPARATOR)
ostream.write(feature["description"])
render_locations(ostream, match)

View File

@@ -207,22 +207,30 @@ def parse_feature(key):
raise InvalidRule("unexpected statement: %s" % key)
# this is the separator between a feature value and its description
# when using the inline description syntax, like:
#
# number: 42 = ENUM_FAVORITE_NUMBER
DESCRIPTION_SEPARATOR = " = "
def parse_description(s, value_type, description=None):
"""
s can be an int or a string
"""
if value_type != "string" and isinstance(s, str) and " = " in s:
if value_type != "string" and isinstance(s, six.string_types) and DESCRIPTION_SEPARATOR in s:
if description:
raise InvalidRule(
'unexpected value: "%s", only one description allowed (inline description with ` = `)' % s
'unexpected value: "%s", only one description allowed (inline description with `%s`)'
% (s, DESCRIPTION_SEPARATOR)
)
value, description = s.split(" = ", 1)
value, _, description = s.rpartition(DESCRIPTION_SEPARATOR)
if description == "":
raise InvalidRule('unexpected value: "%s", description cannot be empty' % s)
else:
value = s
if isinstance(value, str):
if isinstance(value, six.string_types):
if value_type == "bytes":
try:
value = codecs.decode(value.replace(" ", ""), "hex")
@@ -801,7 +809,7 @@ class RuleSet(object):
rules_filtered = set([])
for rule in rules:
for k, v in rule.meta.items():
if isinstance(v, str) and tag in v:
if isinstance(v, six.string_types) and tag in v:
logger.debug('using rule "%s" and dependencies, found tag in meta.%s: %s', rule.name, k, v)
rules_filtered.update(set(capa.rules.get_rules_and_dependencies(rules, rule.name)))
break