1
2
3
4
5
6
7 import hashlib
8 import os
9 import logging
10
11 from zipfile import BadZipfile
12
13 from lib.cuckoo.common.objects import File
14 from lib.cuckoo.common.abstracts import Processing
15 from lib.cuckoo.common.exceptions import CuckooProcessingError
16
17 try:
18 from androguard.core.bytecodes.apk import APK
19 from androguard.core.bytecodes.dvm import DalvikVMFormat
20 from androguard.core.analysis.analysis import uVMAnalysis
21 from androguard.core.analysis import analysis
22 HAVE_ANDROGUARD = True
23 except ImportError:
24 HAVE_ANDROGUARD = False
25
26 log = logging.getLogger(__name__)
27
29 """Static android information about analysis session."""
30
32 for file in file_list:
33 if "classes.dex" in file["name"]:
34 if("decompilation_threshold" in self.options):
35 if file["size"] < self.options.decompilation_threshold:
36 return True
37 else:
38 return False
39 else:
40 return True
41 return False
42
44 """Returns a list of files in the APK."""
45 ret = []
46 for fname, filetype in apk.get_files_types().items():
47 buf = apk.zip.read(fname)
48 ret.append({
49 "name": fname,
50 "md5": hashlib.md5(buf).hexdigest(),
51 "size": len(buf),
52 "type": filetype,
53 })
54 return ret
55
57 """Run androguard to extract static android information
58 @return: list of static features
59 """
60 self.key = "apkinfo"
61 apkinfo = {}
62
63 if "file" not in self.task["category"] or not HAVE_ANDROGUARD:
64 return
65
66 f = File(self.task["target"])
67 if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type():
68 if not os.path.exists(self.file_path):
69 raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path)
70
71 try:
72 a = APK(self.file_path)
73 if a.is_valid_APK():
74 manifest = {}
75 apkinfo["files"] = self._apk_files(a)
76 manifest["package"] = a.get_package()
77
78 manifest["main_activity"] = a.get_main_activity()
79 manifest["activities"] = a.get_activities()
80 manifest["services"] = a.get_services()
81 manifest["receivers"] = a.get_receivers()
82
83 manifest["providers"] = a.get_providers()
84 manifest["libraries"] = a.get_libraries()
85 apkinfo["manifest"] = manifest
86
87 static_calls = {}
88 if self.check_size(apkinfo["files"]):
89 vm = DalvikVMFormat(a.get_dex())
90 vmx = uVMAnalysis(vm)
91
92 static_calls["all_methods"] = self.get_methods(vmx)
93 static_calls["is_native_code"] = analysis.is_native_code(vmx)
94 static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx)
95 static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx)
96
97
98
99
100
101
102 else:
103 log.warning("Dex size bigger than: %s",
104 self.options.decompilation_threshold)
105 apkinfo["static_method_calls"] = static_calls
106 except (IOError, OSError, BadZipfile) as e:
107 raise CuckooProcessingError("Error opening file %s" % e)
108
109 return apkinfo
110
112 methods = []
113 for i in vmx.get_methods():
114 method = {}
115 i.create_tags()
116 if not i.tags.empty():
117 proto = i.method.proto.replace("(", "").replace(";", "")
118 protos = proto.split(")")
119 params = protos[0].split(" ")
120 method["class"] = i.method.get_class_name().replace(";", "")
121 method["name"] = i.method.name
122 if params and params[0]:
123 method["params"] = params
124 method["return"] = protos[1]
125 methods.append(method)
126 return methods
127