mirror of
https://github.com/mandiant/capa.git
synced 2026-02-04 11:07:53 -08:00
mirror show-capabilities-by-function to enable multiple backends
This commit is contained in:
@@ -71,9 +71,11 @@ import argparse
|
||||
import capa.main
|
||||
import capa.rules
|
||||
import capa.engine
|
||||
import capa.helpers
|
||||
import capa.features
|
||||
import capa.features.freeze
|
||||
import capa.features.extractors.viv
|
||||
|
||||
logger = logging.getLogger("capa.show-features")
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
@@ -95,17 +97,55 @@ def main(argv=None):
|
||||
"-f", "--format", choices=[f[0] for f in formats], default="auto", help="Select sample format, %s" % format_help
|
||||
)
|
||||
parser.add_argument("-F", "--function", type=lambda x: int(x, 0x10), help="Show features for specific function")
|
||||
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")
|
||||
args = parser.parse_args(args=argv)
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
if args.quiet:
|
||||
logging.basicConfig(level=logging.ERROR)
|
||||
logging.getLogger().setLevel(logging.ERROR)
|
||||
elif args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
if args.format == "freeze":
|
||||
# disable vivisect-related logging, it's verbose and not relevant for capa users
|
||||
capa.main.set_vivisect_log_level(logging.CRITICAL)
|
||||
|
||||
try:
|
||||
taste = capa.helpers.get_file_taste(args.sample)
|
||||
except IOError as e:
|
||||
logger.error("%s", str(e))
|
||||
return -1
|
||||
|
||||
if (args.format == "freeze") or (args.format == "auto" and capa.features.freeze.is_freeze(taste)):
|
||||
with open(args.sample, "rb") as f:
|
||||
extractor = capa.features.freeze.load(f.read())
|
||||
else:
|
||||
vw = capa.main.get_workspace(args.sample, args.format)
|
||||
extractor = capa.features.extractors.viv.VivisectFeatureExtractor(vw, args.sample)
|
||||
try:
|
||||
extractor = capa.main.get_extractor(args.sample, args.format)
|
||||
except capa.main.UnsupportedFormatError:
|
||||
logger.error("-" * 80)
|
||||
logger.error(" Input file does not appear to be a PE file.")
|
||||
logger.error(" ")
|
||||
logger.error(
|
||||
" capa currently only supports analyzing PE files (or shellcode, when using --format sc32|sc64)."
|
||||
)
|
||||
logger.error(" If you don't know the input file type, you can try using the `file` utility to guess it.")
|
||||
logger.error("-" * 80)
|
||||
return -1
|
||||
except capa.main.UnsupportedRuntimeError:
|
||||
logger.error("-" * 80)
|
||||
logger.error(" Unsupported runtime or Python interpreter.")
|
||||
logger.error(" ")
|
||||
logger.error(" capa supports running under Python 2.7 using Vivisect for binary analysis.")
|
||||
logger.error(" It can also run within IDA Pro, using either Python 2.7 or 3.5+.")
|
||||
logger.error(" ")
|
||||
logger.error(" If you're seeing this message on the command line, please ensure you're running Python 2.7.")
|
||||
logger.error("-" * 80)
|
||||
return -1
|
||||
|
||||
if not args.function:
|
||||
for feature, va in extractor.extract_file_features():
|
||||
@@ -118,15 +158,13 @@ def main(argv=None):
|
||||
|
||||
if args.function:
|
||||
if args.format == "freeze":
|
||||
functions = filter(lambda f: f == args.function, functions)
|
||||
functions = tuple(filter(lambda f: f == args.function, functions))
|
||||
else:
|
||||
functions = filter(lambda f: f.va == args.function, functions)
|
||||
functions = tuple(filter(lambda f: capa.helpers.oint(f) == args.function, functions))
|
||||
|
||||
if args.function not in [f.va for f in functions]:
|
||||
print("0x%X not a function, creating it" % args.function)
|
||||
vw.makeFunction(args.function)
|
||||
functions = extractor.get_functions()
|
||||
functions = filter(lambda f: f.va == args.function, functions)
|
||||
if args.function not in [capa.helpers.oint(f) for f in functions]:
|
||||
print("0x%X not a function" % args.function)
|
||||
return -1
|
||||
|
||||
if len(functions) == 0:
|
||||
print("0x%X not a function")
|
||||
|
||||
Reference in New Issue
Block a user