mirror of
https://github.com/mandiant/capa.git
synced 2025-12-22 07:10:29 -08:00
import-to-ida: use existing result document json parser
This commit is contained in:
@@ -29,13 +29,16 @@ Unless required by applicable law or agreed to in writing, software distributed
|
|||||||
See the License for the specific language governing permissions and limitations under the License.
|
See the License for the specific language governing permissions and limitations under the License.
|
||||||
"""
|
"""
|
||||||
import binascii
|
import binascii
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import ida_nalt
|
import ida_nalt
|
||||||
import ida_funcs
|
import ida_funcs
|
||||||
import ida_kernwin
|
import ida_kernwin
|
||||||
|
|
||||||
|
import capa.rules
|
||||||
|
import capa.features.freeze
|
||||||
|
import capa.render.result_document
|
||||||
|
|
||||||
logger = logging.getLogger("capa")
|
logger = logging.getLogger("capa")
|
||||||
|
|
||||||
|
|
||||||
@@ -65,40 +68,37 @@ def main():
|
|||||||
if not path:
|
if not path:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(path, "rb") as f:
|
result_doc = capa.render.result_document.ResultDocument.parse_file(path)
|
||||||
doc = json.loads(f.read().decode("utf-8"))
|
meta, capabilities = result_doc.to_capa()
|
||||||
|
|
||||||
if "meta" not in doc or "rules" not in doc:
|
|
||||||
logger.error("doesn't appear to be a capa report")
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# in IDA 7.4, the MD5 hash may be truncated, for example:
|
# in IDA 7.4, the MD5 hash may be truncated, for example:
|
||||||
# wanted: 84882c9d43e23d63b82004fae74ebb61
|
# wanted: 84882c9d43e23d63b82004fae74ebb61
|
||||||
# found: b'84882C9D43E23D63B82004FAE74EBB6\x00'
|
# found: b'84882C9D43E23D63B82004FAE74EBB6\x00'
|
||||||
#
|
#
|
||||||
# see: https://github.com/idapython/bin/issues/11
|
# see: https://github.com/idapython/bin/issues/11
|
||||||
a = doc["meta"]["sample"]["md5"].lower()
|
a = meta["sample"]["md5"].lower()
|
||||||
b = binascii.hexlify(ida_nalt.retrieve_input_file_md5()).decode("ascii").lower()
|
b = binascii.hexlify(ida_nalt.retrieve_input_file_md5()).decode("ascii").lower()
|
||||||
if not a.startswith(b):
|
if not a.startswith(b):
|
||||||
logger.error("sample mismatch")
|
logger.error("sample mismatch")
|
||||||
return -2
|
return -2
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
for rule in doc["rules"].values():
|
for name in capabilities.keys():
|
||||||
if rule["meta"].get("lib"):
|
rule = result_doc.rules[name]
|
||||||
|
if rule.meta.lib:
|
||||||
continue
|
continue
|
||||||
if rule["meta"].get("capa/subscope"):
|
if rule.meta.is_subscope_rule:
|
||||||
continue
|
continue
|
||||||
if rule["meta"]["scope"] != "function":
|
if rule.meta.scope != capa.rules.Scope.FUNCTION:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
name = rule["meta"]["name"]
|
ns = rule.meta.namespace
|
||||||
ns = rule["meta"].get("namespace", "")
|
|
||||||
for address, match in rule["matches"]:
|
for address, _ in rule.matches:
|
||||||
if address["type"] != "absolute":
|
if address.type != capa.features.freeze.AddressType.ABSOLUTE:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
va = address["value"]
|
va = address.value
|
||||||
rows.append((ns, name, va))
|
rows.append((ns, name, va))
|
||||||
|
|
||||||
# order by (namespace, name) so that like things show up together
|
# order by (namespace, name) so that like things show up together
|
||||||
|
|||||||
Reference in New Issue
Block a user