Package modules :: Package processing :: Module apkinfo
[hide private]
[frames] | no frames]

Source Code for Module modules.processing.apkinfo

  1  # Copyright (C) 2010-2013 Claudio Guarnieri. 
  2  # Copyright (C) 2014-2016 Cuckoo Foundation. 
  3  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 
  4  # See the file 'docs/LICENSE' for copying permission. 
  5  # Originally contributed by Check Point Software Technologies, Ltd. 
  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   
28 -class ApkInfo(Processing):
29 """Static android information about analysis session.""" 30
31 - def check_size(self, file_list):
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
43 - def _apk_files(self, apk):
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
56 - def run(self):
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 # manifest["permissions"]=a.get_details_permissions_new() 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 # manifest["receivers_actions"]=a.get__extended_receivers() 83 manifest["providers"] = a.get_providers() 84 manifest["libraries"] = a.get_libraries() 85 apkinfo["manifest"] = manifest 86 # apkinfo["certificate"] = a.get_certificate() 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 # static_calls["dynamic_method_calls"]= analysis.get_show_DynCode(vmx) 98 # static_calls["reflection_method_calls"]= analysis.get_show_ReflectionCode(vmx) 99 # static_calls["permissions_method_calls"]= analysis.get_show_Permissions(vmx) 100 # static_calls["crypto_method_calls"]= analysis.get_show_CryptoCode(vmx) 101 # static_calls["native_method_calls"]= analysis.get_show_NativeMethods(vmx) 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
111 - def get_methods(self, vmx):
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