mirror of
https://github.com/mandiant/capa.git
synced 2025-12-19 18:45:00 -08:00
tests: fix scripts using json document
This commit is contained in:
@@ -99,10 +99,10 @@ def serialize_address(a: Address) -> Any:
|
|||||||
elif isinstance(a, capa.features.address.DNTokenOffsetAddress):
|
elif isinstance(a, capa.features.address.DNTokenOffsetAddress):
|
||||||
return ("dn token offset", a.token, a.offset)
|
return ("dn token offset", a.token, a.offset)
|
||||||
|
|
||||||
elif a == capa.features.address.NO_ADDRESS:
|
elif a == capa.features.address.NO_ADDRESS or isinstance(a, capa.features.address._NoAddress):
|
||||||
return ("no address",)
|
return ("no address",)
|
||||||
|
|
||||||
elif isinstance(a, capa.features.address.Address):
|
elif isinstance(a, capa.features.address.Address) and not issubclass(type(a), capa.features.address.Address):
|
||||||
raise ValueError("don't use an Address instance directly")
|
raise ValueError("don't use an Address instance directly")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ def serialize_address(a: Address) -> Any:
|
|||||||
elif isinstance(a, capa.features.address.DNTokenOffsetAddress):
|
elif isinstance(a, capa.features.address.DNTokenOffsetAddress):
|
||||||
return ("dn token offset", a.token, a.offset)
|
return ("dn token offset", a.token, a.offset)
|
||||||
|
|
||||||
elif a == capa.features.address.NO_ADDRESS:
|
elif a == capa.features.address.NO_ADDRESS or isinstance(a, capa.features.address._NoAddress):
|
||||||
return ("no address",)
|
return ("no address",)
|
||||||
|
|
||||||
elif isinstance(a, capa.features.address.Address):
|
elif isinstance(a, capa.features.address.Address) and not issubclass(type(a), capa.features.address.Address):
|
||||||
raise ValueError("don't use an Address instance directly")
|
raise ValueError("don't use an Address instance directly")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -62,9 +62,10 @@ import capa.engine
|
|||||||
import capa.helpers
|
import capa.helpers
|
||||||
import capa.features
|
import capa.features
|
||||||
import capa.exceptions
|
import capa.exceptions
|
||||||
|
import capa.render.verbose
|
||||||
import capa.render.utils as rutils
|
import capa.render.utils as rutils
|
||||||
import capa.features.freeze
|
import capa.features.freeze
|
||||||
import capa.render.result_document
|
import capa.render.result_document as rd
|
||||||
from capa.helpers import get_file_taste
|
from capa.helpers import get_file_taste
|
||||||
|
|
||||||
logger = logging.getLogger("capa.show-capabilities-by-function")
|
logger = logging.getLogger("capa.show-capabilities-by-function")
|
||||||
@@ -90,31 +91,36 @@ def render_matches_by_function(doc):
|
|||||||
- connect to HTTP server
|
- connect to HTTP server
|
||||||
"""
|
"""
|
||||||
functions_by_bb = {}
|
functions_by_bb = {}
|
||||||
for function, info in doc["meta"]["analysis"]["layout"]["functions"].items():
|
functions_by_bb = {}
|
||||||
for bb in info["matched_basic_blocks"]:
|
for finfo in doc["meta"]["analysis"]["layout"]["functions"]:
|
||||||
functions_by_bb[bb] = function
|
faddress = rd.deserialize_address(finfo["address"])
|
||||||
|
|
||||||
|
for bb in finfo["matched_basic_blocks"]:
|
||||||
|
bbaddress = rd.deserialize_address(bb["address"])
|
||||||
|
functions_by_bb[bbaddress] = faddress
|
||||||
|
|
||||||
ostream = rutils.StringIO()
|
ostream = rutils.StringIO()
|
||||||
|
|
||||||
matches_by_function = collections.defaultdict(set)
|
matches_by_function = collections.defaultdict(set)
|
||||||
for rule in rutils.capability_rules(doc):
|
for rule in rutils.capability_rules(doc):
|
||||||
if rule["meta"]["scope"] == capa.rules.FUNCTION_SCOPE:
|
if rule["meta"]["scope"] == capa.rules.FUNCTION_SCOPE:
|
||||||
for va in rule["matches"].keys():
|
for addr, _ in rule["matches"]:
|
||||||
matches_by_function[va].add(rule["meta"]["name"])
|
addr = rd.deserialize_address(addr)
|
||||||
|
matches_by_function[addr].add(rule["meta"]["name"])
|
||||||
elif rule["meta"]["scope"] == capa.rules.BASIC_BLOCK_SCOPE:
|
elif rule["meta"]["scope"] == capa.rules.BASIC_BLOCK_SCOPE:
|
||||||
for va in rule["matches"].keys():
|
for addr, _ in rule["matches"]:
|
||||||
function = functions_by_bb[va]
|
function = functions_by_bb[rd.deserialize_address(addr)]
|
||||||
matches_by_function[function].add(rule["meta"]["name"])
|
matches_by_function[function].add(rule["meta"]["name"])
|
||||||
else:
|
else:
|
||||||
# file scope
|
# file scope
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for va, feature_count in sorted(doc["meta"]["analysis"]["feature_counts"]["functions"].items()):
|
for f in doc["meta"]["analysis"]["feature_counts"]["functions"]:
|
||||||
va = int(va)
|
addr = rd.deserialize_address(f["address"])
|
||||||
if not matches_by_function.get(va, {}):
|
if not matches_by_function.get(addr, {}):
|
||||||
continue
|
continue
|
||||||
ostream.writeln("function at 0x%X with %d features: " % (va, feature_count))
|
ostream.writeln("function at %s with %d features: " % (capa.render.verbose.format_address(addr), f["count"]))
|
||||||
for rule_name in sorted(matches_by_function[va]):
|
for rule_name in sorted(matches_by_function[addr]):
|
||||||
ostream.writeln(" - " + rule_name)
|
ostream.writeln(" - " + rule_name)
|
||||||
|
|
||||||
return ostream.getvalue()
|
return ostream.getvalue()
|
||||||
@@ -187,7 +193,7 @@ def main(argv=None):
|
|||||||
# - when not an interactive session, and disable coloring
|
# - when not an interactive session, and disable coloring
|
||||||
# renderers should use coloring and assume it will be stripped out if necessary.
|
# renderers should use coloring and assume it will be stripped out if necessary.
|
||||||
colorama.init()
|
colorama.init()
|
||||||
doc = capa.render.result_document.convert_capabilities_to_result_document(meta, rules, capabilities)
|
doc = rd.convert_capabilities_to_result_document(meta, rules, capabilities)
|
||||||
print(render_matches_by_function(doc))
|
print(render_matches_by_function(doc))
|
||||||
colorama.deinit()
|
colorama.deinit()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user