forked from alexMyG/AndroPyTool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAPT_4_launch_flowdroid.py
122 lines (87 loc) · 3.85 KB
/
APT_4_launch_flowdroid.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os
import sys
import argparse
import subprocess
from tqdm import tqdm
from threading import Timer
from termcolor import colored
from os.path import join as join_dir
from argparse import RawTextHelpFormatter
working_directory = os.getcwd() + "/"
kill = lambda process: process.kill()
MAX_TIME_ANALYSIS = 5 # Minutes
FLOWDROID_FOLDER = working_directory + "FlowDroid/"
# FlowDroid authors recommend to use the official platforms downloaded from Google, not the ones from GitHub, for better
# performance
ANDROID_PLATFORMS_FOLDER = working_directory + 'FlowDroid/android-platforms/platforms'
MAX_MEMORY = 10 # GIGABYTES
LIBRARIES_FLOWDROID = "soot-trunk.jar:soot-infoflow.jar:soot-infoflow-android.jar:slf4j-api-1.7.5.jar:slf4j-simple-" \
"1.7.5.jar:axml-2.0.jar"
FLOWDROID_MAIN_CALL = "soot.jimple.infoflow.android.TestApps.Test"
# https://github.com/secure-software-engineering/soot-infoflow-android/wiki
def print_message(message, with_color, color):
if with_color:
print colored(message, color)
else:
print message
def get_call_flowdroid(apk_path):
flowdroid_call_list = ["timeout",
str(MAX_TIME_ANALYSIS * 60),
"java", # A list to later build a string space separated
"-Xmx" + str(MAX_MEMORY) + "g",
"-cp",
LIBRARIES_FLOWDROID,
FLOWDROID_MAIN_CALL,
apk_path,
ANDROID_PLATFORMS_FOLDER]
return " ".join(flowdroid_call_list)
def main():
parser = argparse.ArgumentParser(
description="Launches FlowDroid\n\n", formatter_class=RawTextHelpFormatter)
parser.add_argument('-s', '--source', help='Source directory for APKs', required=True)
parser.add_argument('-o', '--output', help='Output directory', required=True)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
run_flowdroid(source_directory=args.source,
output_folder=args.output)
def run_flowdroid(source_directory, output_folder, with_color=True):
"""
Executes flowdroid over a set of samples
Parameters
----------
:param source_directory: Folder containing apk files
:param output_folder: Folder where files generated by FlowDroid are saved
:param with_color: If colors are used to print messages
"""
if not os.path.exists(source_directory):
print print_message("Folder not found!", with_color, 'red')
if not os.path.exists(output_folder):
os.makedirs(output_folder)
list_apks = []
for path, subdirs, files in os.walk(source_directory):
for name in files:
if name.endswith(".apk"):
list_apks.append(os.path.join(path, name))
for apk_path in tqdm(list_apks):
apk_id = os.path.basename(apk_path)
#print "RUNNING FLOWDROID FOR: " + str(apk_id)
if os.path.isfile(join_dir(output_folder, apk_id.replace(".apk", ".json"))) or "assets" in apk_id:
continue
flowdroid_call = get_call_flowdroid(apk_path)
origen_wd = os.getcwd()
os.chdir(os.path.join(os.path.abspath(sys.path[0]), FLOWDROID_FOLDER))
process = subprocess.Popen(flowdroid_call, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT) # , env={'PATH': FLOWDROID_FOLDER})
os.chdir(origen_wd) # get back to our original working directory
timer = Timer(MAX_TIME_ANALYSIS * 59, kill, [process])
try:
timer.start()
stdout, stderr = process.communicate()
finally:
timer.cancel()
with open(join_dir(output_folder, apk_id.replace(".apk", ".json")), "w") as output:
output.write(str(stdout))
if __name__ == '__main__':
main()