mirror of
https://github.com/mandiant/capa.git
synced 2025-12-23 15:37:37 -08:00
Merge branch 'master' into capa-explorer-export-json-results
This commit is contained in:
2
.github/pyinstaller/hooks/hook-vivisect.py
vendored
2
.github/pyinstaller/hooks/hook-vivisect.py
vendored
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from PyInstaller.utils.hooks import copy_metadata
|
||||
|
||||
# in order for viv-utils to use pkg_resources to fetch
|
||||
|
||||
1
.github/pyinstaller/pyinstaller.spec
vendored
1
.github/pyinstaller/pyinstaller.spec
vendored
@@ -1,4 +1,5 @@
|
||||
# -*- mode: python -*-
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import re
|
||||
import sys
|
||||
import copy
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import sys
|
||||
import codecs
|
||||
import logging
|
||||
@@ -39,10 +41,13 @@ class Feature(object):
|
||||
return self.value
|
||||
|
||||
def __str__(self):
|
||||
if self.description:
|
||||
return "%s(%s = %s)" % (self.name, self.get_value_str(), self.description)
|
||||
if self.value:
|
||||
if self.description:
|
||||
return "%s(%s = %s)" % (self.name, self.get_value_str(), self.description)
|
||||
else:
|
||||
return "%s(%s)" % (self.name, self.get_value_str())
|
||||
else:
|
||||
return "%s(%s)" % (self.name, self.get_value_str())
|
||||
return "%s" % self.name
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from capa.features import Feature
|
||||
|
||||
|
||||
@@ -8,6 +10,9 @@ class BasicBlock(Feature):
|
||||
def __str__(self):
|
||||
return "basic block"
|
||||
|
||||
def get_value_str(self):
|
||||
return ""
|
||||
|
||||
def freeze_serialize(self):
|
||||
return (self.__class__.__name__, [])
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import abc
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import sys
|
||||
import builtins
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import sys
|
||||
import string
|
||||
import struct
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import struct
|
||||
|
||||
import idc
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import idaapi
|
||||
import idautils
|
||||
|
||||
@@ -36,7 +38,8 @@ def extract_function_loop(f):
|
||||
|
||||
# construct control flow graph
|
||||
for bb in idaapi.FlowChart(f):
|
||||
map(lambda s: edges.append((bb.start_ea, s.start_ea)), bb.succs())
|
||||
for succ in bb.succs():
|
||||
edges.append((bb.start_ea, succ.start_ea))
|
||||
|
||||
if loops.has_loop(edges):
|
||||
yield Characteristic("loop"), f.start_ea
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import sys
|
||||
import string
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import idc
|
||||
import idaapi
|
||||
import idautils
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from networkx import nx
|
||||
from networkx.algorithms.components import strongly_connected_components
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2017 FireEye, Inc. All Rights Reserved.
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
#
|
||||
# strings code from FLOSS, https://github.com/fireeye/flare-floss
|
||||
#
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import types
|
||||
|
||||
import viv_utils
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import string
|
||||
import struct
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import PE.carve as pe_carve # vivisect PE
|
||||
|
||||
import capa.features.extractors.strings
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import vivisect.const
|
||||
|
||||
from capa.features import Characteristic
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import collections
|
||||
|
||||
import envi
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import envi.memory
|
||||
import vivisect.const
|
||||
import envi.archs.i386.disasm
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from capa.features import Feature
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ json format:
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import json
|
||||
import zlib
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from capa.features import Feature
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import os
|
||||
|
||||
_hex = hex
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import sys
|
||||
import codecs
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from collections import deque
|
||||
|
||||
import idc
|
||||
@@ -467,10 +469,13 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel):
|
||||
|
||||
bytes(01 14 02 00 00 00 00 00 C0 00 00 00 00 00 00 46 = CLSID_ShellLink)
|
||||
"""
|
||||
if feature.get("description", ""):
|
||||
return "%s(%s = %s)" % (feature["type"], feature[feature["type"]], feature["description"])
|
||||
if feature[feature["type"]]:
|
||||
if feature.get("description", ""):
|
||||
return "%s(%s = %s)" % (feature["type"], feature[feature["type"]], feature["description"])
|
||||
else:
|
||||
return "%s(%s)" % (feature["type"], feature[feature["type"]])
|
||||
else:
|
||||
return "%s(%s)" % (feature["type"], feature[feature["type"]])
|
||||
return "%s" % feature["type"]
|
||||
|
||||
def render_capa_doc_feature_node(self, parent, feature, locations, doc):
|
||||
""" process capa doc feature node
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from capa.ida.explorer.model import CapaExplorerDataModel
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import idc
|
||||
import idaapi
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import logging
|
||||
import datetime
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
|
||||
36
capa/main.py
36
capa/main.py
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env python2
|
||||
"""
|
||||
identify capabilities in programs.
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
@@ -413,41 +415,37 @@ def main(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description=__doc__, epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
parser.add_argument("sample", type=str, help="Path to sample to analyze")
|
||||
parser.add_argument("sample", type=str, help="path to sample to analyze")
|
||||
parser.add_argument("--version", action="version", version="%(prog)s {:s}".format(capa.version.__version__))
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--rules",
|
||||
type=str,
|
||||
default=RULES_PATH_DEFAULT_STRING,
|
||||
help="Path to rule file or directory, use embedded rules by default",
|
||||
)
|
||||
parser.add_argument("-t", "--tag", type=str, help="Filter on rule meta field values")
|
||||
parser.add_argument("--version", action="store_true", help="Print the executable version and exit")
|
||||
parser.add_argument("-j", "--json", action="store_true", help="Emit JSON instead of text")
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", action="store_true", help="Enable verbose result document (no effect with --json)"
|
||||
help="path to rule file or directory, use embedded rules by default",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-vv", "--vverbose", action="store_true", help="Enable very verbose result document (no effect with --json)"
|
||||
"-f", "--format", choices=[f[0] for f in formats], default="auto", help="select sample format, %s" % format_help
|
||||
)
|
||||
parser.add_argument("-d", "--debug", action="store_true", help="Enable debugging output on STDERR")
|
||||
parser.add_argument("-q", "--quiet", action="store_true", help="Disable all output but errors")
|
||||
parser.add_argument("-t", "--tag", type=str, help="filter on rule meta field values")
|
||||
parser.add_argument("-j", "--json", action="store_true", help="emit JSON instead of text")
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", action="store_true", help="enable verbose result document (no effect with --json)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-vv", "--vverbose", action="store_true", help="enable very verbose result document (no effect with --json)"
|
||||
)
|
||||
parser.add_argument("-d", "--debug", action="store_true", help="enable debugging output on STDERR")
|
||||
parser.add_argument("-q", "--quiet", action="store_true", help="disable all output but errors")
|
||||
parser.add_argument(
|
||||
"--color",
|
||||
type=str,
|
||||
choices=("auto", "always", "never"),
|
||||
default="auto",
|
||||
help="Enable ANSI color codes in results, default: only during interactive session",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f", "--format", choices=[f[0] for f in formats], default="auto", help="Select sample format, %s" % format_help
|
||||
help="enable ANSI color codes in results, default: only during interactive session",
|
||||
)
|
||||
args = parser.parse_args(args=argv)
|
||||
|
||||
if args.version:
|
||||
print(capa.version.__version__)
|
||||
return 0
|
||||
|
||||
if args.quiet:
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
logging.getLogger().setLevel(logging.WARNING)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import json
|
||||
|
||||
import six
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import collections
|
||||
|
||||
import six
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import six
|
||||
import termcolor
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ example::
|
||||
0x10003a13
|
||||
0x10003415
|
||||
0x10003797
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import tabulate
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import collections
|
||||
|
||||
import tabulate
|
||||
@@ -44,12 +46,15 @@ def render_statement(ostream, match, statement, indent=0):
|
||||
# so, we have to inline some of the feature rendering here.
|
||||
|
||||
child = statement["child"]
|
||||
value = rutils.bold2(child[child["type"]])
|
||||
|
||||
if child.get("description"):
|
||||
ostream.write("count(%s(%s = %s)): " % (child["type"], value, child["description"]))
|
||||
if child[child["type"]]:
|
||||
value = rutils.bold2(child[child["type"]])
|
||||
if child.get("description"):
|
||||
ostream.write("count(%s(%s = %s)): " % (child["type"], value, child["description"]))
|
||||
else:
|
||||
ostream.write("count(%s(%s)): " % (child["type"], value))
|
||||
else:
|
||||
ostream.write("count(%s(%s)): " % (child["type"], value))
|
||||
ostream.write("count(%s): " % child["type"])
|
||||
|
||||
if statement["max"] == statement["min"]:
|
||||
ostream.write("%d" % (statement["min"]))
|
||||
@@ -79,11 +84,13 @@ def render_feature(ostream, match, feature, indent=0):
|
||||
|
||||
ostream.write(feature["type"])
|
||||
ostream.write(": ")
|
||||
ostream.write(rutils.bold2(feature[feature["type"]]))
|
||||
|
||||
if "description" in feature:
|
||||
ostream.write(capa.rules.DESCRIPTION_SEPARATOR)
|
||||
ostream.write(feature["description"])
|
||||
if feature[feature["type"]]:
|
||||
ostream.write(rutils.bold2(feature[feature["type"]]))
|
||||
|
||||
if "description" in feature:
|
||||
ostream.write(capa.rules.DESCRIPTION_SEPARATOR)
|
||||
ostream.write(feature["description"])
|
||||
|
||||
render_locations(ostream, match)
|
||||
ostream.write("\n")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import uuid
|
||||
import codecs
|
||||
import logging
|
||||
|
||||
@@ -5,6 +5,8 @@ Use the -i flag to update the rule in-place.
|
||||
Usage:
|
||||
|
||||
$ python capafmt.py -i foo.yml
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import sys
|
||||
import logging
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
# doesn't matter if this gets repeated later on in a hooks file
|
||||
|
||||
# Use a console with emojis support for a better experience
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
# doesn't matter if this gets repeated later on in a hooks file
|
||||
|
||||
# Use a console with emojis support for a better experience
|
||||
|
||||
@@ -19,6 +19,8 @@ and then select the existing capa report from the file system.
|
||||
|
||||
This script will verify that the report matches the workspace.
|
||||
Check the output window for any errors, and/or the summary of changes.
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
|
||||
@@ -4,6 +4,8 @@ Check the given capa rules for style issues.
|
||||
Usage:
|
||||
|
||||
$ python scripts/lint.py rules/
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -5,6 +5,8 @@ migrate rules and their namespaces.
|
||||
example:
|
||||
|
||||
$ python scripts/migrate-rules.py migration.csv ./rules ./new-rules
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import os
|
||||
import csv
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ Example::
|
||||
- set socket configuration
|
||||
- connect TCP socket
|
||||
...
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -55,6 +55,8 @@ Example::
|
||||
insn: 0x10001027: number(0x1)
|
||||
insn: 0x10001027: mnemonic(shl)
|
||||
...
|
||||
|
||||
Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
"""
|
||||
import sys
|
||||
import logging
|
||||
|
||||
2
setup.py
2
setup.py
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import collections
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import textwrap
|
||||
|
||||
import capa.rules
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import textwrap
|
||||
|
||||
import capa.rules
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import textwrap
|
||||
|
||||
import capa.main
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import codecs
|
||||
|
||||
from capa.features.extractors import helpers
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import textwrap
|
||||
|
||||
import capa.main
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
|
||||
|
||||
import viv_utils
|
||||
|
||||
import capa.features
|
||||
|
||||
Reference in New Issue
Block a user