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