modules.processing.apkinfo

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