forked from avast/retdec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathretdec-fileinfo.py
105 lines (78 loc) · 3.41 KB
/
retdec-fileinfo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env python3
"""A wrapper for fileinfo that:
- uses also external YARA patterns,
- is able to analyze archives (.a/.lib files).
"""
from __future__ import print_function
import argparse
import importlib
import os
import sys
utils = importlib.import_module('retdec-utils')
utils.check_python_version()
utils.ensure_script_is_being_run_from_installed_retdec()
try:
retdec_archive_decompiler = importlib.import_module('retdec-archive-decompiler')
ArchiveDecompiler = retdec_archive_decompiler.ArchiveDecompiler
except ImportError:
ArchiveDecompiler = None
sys.stdout = utils.Unbuffered(sys.stdout)
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
FILEINFO = os.path.join(SCRIPT_DIR, 'retdec-fileinfo')
INSTALL_SHARE_YARA_DIR = os.path.join(SCRIPT_DIR, '..', 'share', 'retdec', 'support', 'generic', 'yara_patterns')
FILEINFO_EXTERNAL_YARA_PRIMARY_CRYPTO_DATABASES = [
os.path.join(INSTALL_SHARE_YARA_DIR, 'signsrch', 'signsrch.yara'),
os.path.join(INSTALL_SHARE_YARA_DIR, 'signsrch', 'signsrch.yarac')]
FILEINFO_EXTERNAL_YARA_EXTRA_CRYPTO_DATABASES = [
os.path.join(INSTALL_SHARE_YARA_DIR, 'signsrch', 'signsrch_regex.yara'),
os.path.join(INSTALL_SHARE_YARA_DIR, 'signsrch', 'signsrch_regex.yarac')]
def parse_args():
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument('-j', '--json',
dest='json',
action='store_true',
help='Set to forward --json to the archive decompilation script.')
parser.add_argument('--use-external-patterns',
dest='external_patterns',
action='store_true',
help='Should use external patterns')
return parser.parse_known_args()
def get_input_file(unknownargs):
"""Find path to the input file.
We take the first parameter that does not start with a dash. This is a
simplification and may not work in all cases. A proper solution would
need to parse fileinfo parameters, which would be complex.
"""
for arg in unknownargs:
if not arg.startswith('-'):
return arg
return None
def main():
args, unknownargs = parse_args()
input = get_input_file(unknownargs)
# When analyzing an archive, use the archive decompilation script `--list`
# instead of `fileinfo` because fileinfo is currently unable to analyze
# archives.
if input and utils.has_archive_signature(input):
archive_decompiler_args = [input, '--list']
if args.json:
archive_decompiler_args.append('--json')
assert ArchiveDecompiler is not None, "You need to install RetDec with Decompiler in order to analyze archives"
decompiler = ArchiveDecompiler(archive_decompiler_args)
sys.exit(decompiler.decompile_archive())
# We are not analyzing an archive, so proceed to fileinfo.
fileinfo_params = unknownargs
if args.json:
fileinfo_params.append('--json')
for par in FILEINFO_EXTERNAL_YARA_PRIMARY_CRYPTO_DATABASES:
fileinfo_params.extend(['--crypto', par])
if args.external_patterns:
for par in FILEINFO_EXTERNAL_YARA_EXTRA_CRYPTO_DATABASES:
fileinfo_params.extend(['--crypto', par])
_, ret, _ = utils.CmdRunner.run_cmd([FILEINFO] + fileinfo_params)
sys.exit(ret)
if __name__ == "__main__":
main()