mirror of
https://github.com/mandiant/capa.git
synced 2026-02-04 19:12:01 -08:00
parse mbc fields
This commit is contained in:
@@ -179,18 +179,15 @@ def render_mbc(doc, ostream):
|
||||
if not rule["meta"].get("mbc"):
|
||||
continue
|
||||
|
||||
mbcs = rule["meta"]["mbc"]
|
||||
if not isinstance(mbcs, list):
|
||||
raise ValueError("invalid rule: MBC mapping is not a list")
|
||||
for mbc in rule["meta"]["mbc"]:
|
||||
id = mbc.get("id")
|
||||
objective = mbc.get("objective")
|
||||
behavior = mbc.get("behavior")
|
||||
method = mbc.get("method")
|
||||
|
||||
for mbc in mbcs:
|
||||
objective, _, rest = mbc.partition("::")
|
||||
if "::" in rest:
|
||||
behavior, _, rest = rest.partition("::")
|
||||
method, _, id = rest.rpartition(" ")
|
||||
if method:
|
||||
objectives[objective].add((behavior, method, id))
|
||||
else:
|
||||
behavior, _, id = rest.rpartition(" ")
|
||||
objectives[objective].add((behavior, id))
|
||||
|
||||
rows = []
|
||||
@@ -199,10 +196,10 @@ def render_mbc(doc, ostream):
|
||||
for spec in sorted(behaviors):
|
||||
if len(spec) == 2:
|
||||
behavior, id = spec
|
||||
inner_rows.append("%s %s" % (rutils.bold(behavior), id))
|
||||
inner_rows.append("%s [%s]" % (rutils.bold(behavior), id))
|
||||
elif len(spec) == 3:
|
||||
behavior, method, id = spec
|
||||
inner_rows.append("%s::%s %s" % (rutils.bold(behavior), method, id))
|
||||
inner_rows.append("%s::%s [%s]" % (rutils.bold(behavior), method, id))
|
||||
else:
|
||||
raise RuntimeError("unexpected MBC spec format")
|
||||
rows.append(
|
||||
|
||||
@@ -281,6 +281,42 @@ def parse_description(s, value_type, description=None):
|
||||
return value, description
|
||||
|
||||
|
||||
def parse_meta(meta):
|
||||
"""
|
||||
further process meta items such as MBC
|
||||
"""
|
||||
mbcs = meta.get("mbc", [])
|
||||
if not isinstance(mbcs, list):
|
||||
raise InvalidRule("MBC mapping must be a list")
|
||||
|
||||
if mbcs:
|
||||
meta["mbc"] = [parse_canonical_mbc(mbc) for mbc in mbcs]
|
||||
|
||||
# TODO att&ck
|
||||
|
||||
return meta
|
||||
|
||||
|
||||
def parse_canonical_mbc(mbc):
|
||||
"""
|
||||
parse capa's canonical MBC representation: `OBJECTIVE::Behavior::Method [Identifier]`
|
||||
"""
|
||||
objective, _, rest = mbc.partition("::")
|
||||
if "::" in rest:
|
||||
behavior, _, rest = rest.partition("::")
|
||||
method, _, id = rest.rpartition(" ")
|
||||
else:
|
||||
behavior, _, id = rest.rpartition(" ")
|
||||
method = ""
|
||||
return {
|
||||
"id": id.lstrip("[").rstrip("]"),
|
||||
"objective": objective,
|
||||
"behavior": behavior,
|
||||
"method": method,
|
||||
# TODO "micro-behavior": "",
|
||||
}
|
||||
|
||||
|
||||
def pop_statement_description_entry(d):
|
||||
"""
|
||||
extracts the description for statements and removes the description entry from the document
|
||||
@@ -577,7 +613,9 @@ class Rule(object):
|
||||
if scope not in SUPPORTED_FEATURES.keys():
|
||||
raise InvalidRule("{:s} is not a supported scope".format(scope))
|
||||
|
||||
return cls(name, scope, build_statements(statements[0], scope), d["rule"]["meta"], definition)
|
||||
meta = parse_meta(d["rule"]["meta"])
|
||||
|
||||
return cls(name, scope, build_statements(statements[0], scope), meta, definition)
|
||||
|
||||
@staticmethod
|
||||
@lru_cache()
|
||||
|
||||
Reference in New Issue
Block a user