lib.common.abstracts

Package lib :: Package common :: Module abstracts |
[hide private]
[frames] | no frames]

# Source Code for Module lib.common.abstracts

      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
      6  import glob
      7  import os
      8
      9  from _winreg import CreateKey, SetValueEx, CloseKey, REG_DWORD, REG_SZ
     10
     11  from lib.api.process import Process
     12  from lib.common.exceptions import CuckooPackageError
     13
     14 -class Package(object):
     15      """Base abstract analysis package."""
     16      PATHS = []
     17      REGKEYS = []
     18
     19 -    def __init__(self, options={}, analyzer=None):
     20          """@param options: options dict."""
     21          self.options = options
     22          self.analyzer = analyzer
     23          self.pids = []
     24
     25          # Fetch the current working directory, defaults to $TEMP.
     26          if "curdir" in options:
     27              self.curdir = os.path.expandvars(options["curdir"])
     28          else:
     29              self.curdir = os.getenv("TEMP")
     30
     31 -    def set_pids(self, pids):
     32          """Update list of monitored PIDs in the package context.
     33          @param pids: list of pids.
     34          """
     35          self.pids = pids
     36
     37 -    def start(self, target):
     38          """Run analysis package.
     39          @raise NotImplementedError: this method is abstract.
     40          """
     41          raise NotImplementedError
     42
     43 -    def check(self):
     44          """Check."""
     45          return True
     46
     47 -    def enum_paths(self):
     48          """Enumerate available paths."""
     49          basepaths = {
     50              "System32": [
     51                  os.path.join(os.getenv("SystemRoot"), "System32"),
     52                  os.path.join(os.getenv("SystemRoot"), "SysWOW64"),
     53              ],
     54              "ProgramFiles": [
     55                  os.getenv("ProgramFiles").replace(" (x86)", ""),
     56                  os.getenv("ProgramFiles(x86)"),
     57              ],
     58              "HomeDrive": [
     59                  # os.path.join() doesn't work well if you give it just "C:"
     60                  # so manually append a backslash.
     61                  os.getenv("HomeDrive") + "\\",
     62              ],
     63          }
     64
     65          for path in self.PATHS:
     66              basedir = path[0]
     67              for basepath in basepaths.get(basedir, [basedir]):
     68                  if not basepath or not os.path.isdir(basepath):
     69                      continue
     70
     71                  yield os.path.join(basepath, *path[1:])
     72
     73 -    def get_path(self, application):
     74          """Search for the application in all available paths.
     75          @param applicaiton: application executable name
     76          @return: executable path
     77          """
     78          for path in self.enum_paths():
     79              if os.path.isfile(path):
     80                  return path
     81
     82          raise CuckooPackageError("Unable to find any %s executable." %
     83                                   application)
     84
     85 -    def get_path_glob(self, application):
     86          """Search for the application in all available paths with glob support.
     87          @param applicaiton: application executable name
     88          @return: executable path
     89          """
     90          for path in self.enum_paths():
     91              for path in glob.iglob(path):
     92                  if os.path.isfile(path):
     93                      return path
     94
     95          raise CuckooPackageError("Unable to find any %s executable." %
     96                                   application)
     97
     98 -    def move_curdir(self, filepath):
     99          """Move a file to the current working directory so it can be executed
    100          from there.
    101          @param filepath: the file to be moved
    102          @return: the new filepath
    103          """
    104          outpath = os.path.join(self.curdir, os.path.basename(filepath))
    105          os.rename(filepath, outpath)
    106          return outpath
    107
    108 -    def init_regkeys(self, regkeys):
    109          """Initializes the registry to avoid annoying popups, configure
    110          settings, etc.
    111          @param regkeys: the root keys, subkeys, and key/value pairs.
    112          """
    113          for rootkey, subkey, values in regkeys:
    114              key_handle = CreateKey(rootkey, subkey)
    115
    116              for key, value in values.items():
    117                  if isinstance(value, str):
    118                      SetValueEx(key_handle, key, 0, REG_SZ, value)
    119                  elif isinstance(value, int):
    120                      SetValueEx(key_handle, key, 0, REG_DWORD, value)
    121                  elif isinstance(value, dict):
    122                      self.init_regkeys([
    123                          [rootkey, "%s\\%s" % (subkey, key), value],
    124                      ])
    125                  else:
    126                      raise CuckooPackageError("Invalid value type: %r" % value)
    127
    128              CloseKey(key_handle)
    129
    130 -    def execute(self, path, args, mode=None, maximize=False, env=None,
    131                  source=None, trigger=None):
    132          """Starts an executable for analysis.
    133          @param path: executable path
    134          @param args: executable arguments
    135          @param mode: monitor mode - which functions to instrument
    136          @param maximize: whether the GUI should start maximized
    137          @param env: additional environment variables
    138          @param source: parent process of our process
    139          @param trigger: trigger to indicate analysis start
    140          @return: process pid
    141          """
    142          dll = self.options.get("dll")
    143          free = self.options.get("free")
    144
    145          source = source or self.options.get("from")
    146          mode = mode or self.options.get("mode")
    147
    148          if not trigger and self.options.get("trigger"):
    149              if self.options["trigger"] == "exefile":
    150                  trigger = "file:%s" % path
    151
    152          # Setup pre-defined registry keys.
    153          self.init_regkeys(self.REGKEYS)
    154
    155          p = Process()
    156          if not p.execute(path=path, args=args, dll=dll, free=free,
    157                           curdir=self.curdir, source=source, mode=mode,
    158                           maximize=maximize, env=env, trigger=trigger):
    159              raise CuckooPackageError(
    160                  "Unable to execute the initial process, analysis aborted."
    161              )
    162
    163          return p.pid
    164
    165 -    def package_files(self):
    166          """A list of files to upload to host.
    167          The list should be a list of tuples (<path on guest>, <name of file in package_files folder>).
    168          (package_files is a folder that will be created in analysis folder).
    169          """
    170          return None
    171
    172 -    def finish(self):
    173          """Finish run.
    174          If specified to do so, this method dumps the memory of
    175          all running processes.
    176          """
    177          if self.options.get("procmemdump"):
    178              for pid in self.pids:
    179                  p = Process(pid=pid)
    180                  p.dump_memory()
    181
    182          return True
    183
    184 -class Auxiliary(object):
    185 -    def __init__(self, options={}, analyzer=None):
    186          self.options = options
    187          self.analyzer = analyzer
    188