def import_module(module_name): global MODULE_COUNTER import api_internal from ipython_shell import add_command try: already_imported = False for mod in modules: if module_name == modules[mod][0]: already_imported = True break if not already_imported: pp_print("[*] Importing %s\n" % module_name) mod = __import__(module_name, fromlist=['']) mod.initialize_callbacks( MODULE_COUNTER, functools.partial( api_internal.print_internal, module_name)) # Add commands declared by the module for element in dir(mod): if element.startswith("do_"): add_command(element[3:], getattr(mod, element)) modules[MODULE_COUNTER] = (module_name, mod) MODULE_COUNTER += 1 else: pp_warning("[*] Module %s already imported\n" % module_name) except Exception as e: pp_error("[!] Could not initialize python module due to exception\n") pp_error(" %s\n" % str(e)) return
def reload_module(_id): try: if _id in modules: modules[_id].reload() else: pp_warning("[*] The module number specified (%d) has not been imported\n" % _id) except Exception as e: pp_error("[!] Could not reload python module due to exception\n") pp_error(" %s\n" % str(e)) return
def unload(self): from ipython_shell import remove_command if self.__loaded is True: pp_print("[*] Unloading %s\n" % self.__module_name) # Add commands declared by the module for element in dir(self.__module): if element.startswith("do_"): remove_command(element[3:]) self.__module.clean() self.__loaded = False else: pp_warning("[*] Module %d is not loaded!\n" % self.__id)
def unload_module(mod): from ipython_shell import remove_command if isinstance(mod, int) and mod in modules: pp_print("[*] Unloading %s\n" % modules[mod][0]) # Add commands declared by the module for element in dir(modules[mod][1]): if element.startswith("do_"): remove_command(element[3:]) modules[mod][1].clean() # Remove module from list del modules[mod] else: pp_warning("[*] Module not loaded!\n")
def function_wrapper_old(f, callback_type, *args, **kwargs): global DISABLE_DEPRECATION_WARNINGS try: if not DISABLE_DEPRECATION_WARNINGS: from utils import pp_warning pp_warning("You are using a deprecated callback format.\n" + \ "Switch to new style callback format, that will become the default in the future.\n" + \ "See the documentation of CallbackManager for further reference.\n") # Set to True, so that we don't repeat the same message again and again DISABLE_DEPRECATION_WARNINGS = True # We need to treat each callback separately if callback_type == CallbackManager.BLOCK_BEGIN_CB: f(kwargs["cpu_index"], kwargs["cpu"], kwargs["tb"]) elif callback_type == CallbackManager.BLOCK_END_CB: f(kwargs["cpu_index"], kwargs["cpu"], kwargs["tb"], kwargs["cur_pc"], kwargs["next_pc"]) elif callback_type == CallbackManager.INSN_BEGIN_CB: f(kwargs["cpu_index"], kwargs["cpu"]) elif callback_type == CallbackManager.INSN_END_CB: f(kwargs["cpu_index"], kwargs["cpu"]) elif callback_type == CallbackManager.MEM_READ_CB: f(kwargs["cpu_index"], kwargs["vaddr"], kwargs["size"], kwargs["haddr"]) elif callback_type == CallbackManager.MEM_WRITE_CB: f(kwargs["cpu_index"], kwargs["vaddr"], kwargs["size"], kwargs["haddr"], kwargs["data"]) elif callback_type == CallbackManager.KEYSTROKE_CB: f(kwargs["keycode"]) elif callback_type == CallbackManager.NIC_REC_CB: f(kwargs["buf"], kwargs["size"], kwargs["cur_pos"], kwargs["start"], kwargs["stop"]) elif callback_type == CallbackManager.NIC_SEND_CB: f(kwargs["addr"], kwargs["size"], kwargs["buf"]) elif callback_type == CallbackManager.OPCODE_RANGE_CB: f(kwargs["cpu_index"], kwargs["cpu"], kwargs["cur_pc"], kwargs["next_pc"]) elif callback_type == CallbackManager.TLB_EXEC_CB: f(kwargs["cpu"], kwargs["vaddr"]) elif callback_type == CallbackManager.CREATEPROC_CB: f(kwargs["pid"], kwargs["pgd"], kwargs["name"]) elif callback_type == CallbackManager.REMOVEPROC_CB: f(kwargs["pid"], kwargs["pgd"], kwargs["name"]) elif callback_type == CallbackManager.CONTEXTCHANGE_CB: f(kwargs["old_pgd"], kwargs["new_pgd"]) elif callback_type == CallbackManager.LOADMODULE_CB: f(kwargs["pid"], kwargs["pgd"], kwargs["base"], kwargs["size"], kwargs["name"], kwargs["fullname"]) elif callback_type == CallbackManager.REMOVEMODULE_CB: f(kwargs["pid"], kwargs["pgd"], kwargs["base"], kwargs["size"], kwargs["name"], kwargs["fullname"]) else: raise Exception("Unsupported callback type!") except Exception as e: from utils import pp_error pp_error("\nException occurred when calling callback function %s - %s\n\n" % (str(f), str(e))) finally: return
def dereference_target_long(addr, pgd, long_size): import api typ = "<I" if long_size == 4 else "<Q" try: buff = api.r_va(pgd, addr, long_size) except: buff = "\x00" * long_size pp_debug("Could not dereference TARGET_LONG in interproc_callbacks.py") if len(buff) == 0: pp_warning( "[interproc_callbacks.py:dereference_target_long] Error while dereferencing parameter with address %x" % addr) return 0 return struct.unpack(typ, buff)[0]
def reload(self): import api_internal from ipython_shell import add_command if self.__module is not None: pp_print("[*] Reloading python module %s\n" % self.__module_name) if self.__loaded is True: self.unload() reload(self.__module) # Add again commands and call initialize_callbacks: self.__module.initialize_callbacks(self.__id, functools.partial(api_internal.print_internal, self.__module_name)) # Add commands declared by the module for element in dir(self.__module): if element.startswith("do_"): add_command(element[3:], getattr(self.__module, element)) self.__loaded = True else: pp_warning("[!] The module was not correctly imported!\n")
def import_module(module_name): global MODULE_COUNTER try: already_imported = False for mod in modules: if modules[mod].get_module_name() == module_name: already_imported = True break if not already_imported: MODULE_COUNTER += 1 modules[MODULE_COUNTER] = Module(MODULE_COUNTER, module_name) modules[MODULE_COUNTER].load() else: pp_warning("[*] Module %s already imported, did you want to reload it instead?\n" % module_name) except Exception as e: pp_error("[!] Could not initialize python module due to exception\n") pp_error(" %s\n" % str(e)) return
def unload_module(_id): try: if _id in modules: modules[_id].unload() else: pp_warning("[*] The module number specified (%d) has not been imported\n" % _id) pp_warning("[*] Possible ids:") for i in modules: pp_warning(" %s - %s" % (str(i),str(type(i)))) except Exception as e: pp_error("[!] Could not unload python module due to exception\n") pp_error(" %s\n" % str(e)) return
def linux_insert_module(task, pid, pgd, base, size, basename, fullname, update_symbols=False): from utils import ConfigurationManager as conf_m import volatility.obj as obj from vmi import add_symbols from vmi import get_symbols from vmi import has_symbols from vmi import add_module from vmi import has_module from vmi import get_module from vmi import Module from api_internal import dispatch_module_load_callback from api_internal import dispatch_module_remove_callback import api import hashlib pgd_for_memory_read = conf_m.addr_space.vtop(task.mm.pgd) or task.mm.pgd # Create module, use 0 as checksum as it is irrelevant here mod = Module(base, size, pid, pgd, 0, basename, fullname) #Module load/del notification if has_module(pid, pgd, base): ex_mod = get_module(pid, pgd, base) if ex_mod.get_size() != size or \ ex_mod.get_checksum() != checksum or \ ex_mod.get_name() != basename or \ ex_mod.get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback(pid, pgd, base, ex_mod.get_size(), ex_mod.get_name(), ex_mod.get_fullname()) add_module(pid, pgd, base, mod) dispatch_module_load_callback(pid, pgd, base, size, basename, fullname) else: # Just notify of module load dispatch_module_load_callback(pid, pgd, base, size, basename, fullname) add_module(pid, pgd, base, mod) # Mark the module as present get_module(pid, pgd, base).set_present() if update_symbols: # Compute the checksum of the ELF Header, as a way to avoid name # collisions on the symbol cache. May extend this hash to other parts # of the binary if necessary in the future. elf_hdr = obj.Object("elf_hdr", offset=base, vm=task.get_process_address_space()) if elf_hdr.is_valid(): elf_hdr_size = elf_hdr.elf_obj.size() buf = "" try: buf = api.r_va(pgd_for_memory_read, base, elf_hdr_size) except: pp_warning("Could not read ELF header at address %x" % base) if not has_symbols(fullname): syms = {} # Fetch symbols for sym in elf_hdr.symbols(): if sym.st_value == 0 or (sym.st_info & 0xf) != 2: continue sym_name = elf_hdr.symbol_name(sym) sym_offset = sym.st_value if sym_name in syms: if syms[sym_name] != sym_offset: # There are cases in which the same import is present twice, such as in this case: # nm /lib/x86_64-linux-gnu/libpthread-2.24.so | grep "pthread_getaffinity_np" # 00000000000113f0 T pthread_getaffinity_np@GLIBC_2.3.3 # 00000000000113a0 T # pthread_getaffinity_np@@GLIBC_2.3.4 sym_name = sym_name + "_" while sym_name in syms and syms[ sym_name] != sym_offset: sym_name = sym_name + "_" if sym_name not in syms: syms[sym_name] = sym_offset else: syms[sym_name] = sym_offset add_symbols(fullname, syms) mod.set_symbols(get_symbols(fullname)) return None
def linux_insert_module(task, pid, pgd, base, size, basename, fullname, update_symbols=False): from utils import ConfigurationManager as conf_m import volatility.obj as obj from vmi import modules from vmi import symbols from vmi import Module from api_internal import dispatch_module_load_callback from api_internal import dispatch_module_remove_callback import api import hashlib pgd_for_memory_read = conf_m.addr_space.vtop(task.mm.pgd) or task.mm.pgd # Create module, use 0 as checksum as it is irrelevant here mod = Module(base, size, pid, pgd, 0, basename, fullname) # Add an entry in the module list, if necessary if (pid, pgd) not in modules: modules[(pid, pgd)] = {} #Module load/del notification if base in modules[(pid, pgd)]: if modules[(pid, pgd)][base].get_size() != size or \ modules[(pid, pgd)][base].get_checksum() != checksum or \ modules[(pid, pgd)][base].get_name() != basename or \ modules[(pid, pgd)][base].get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback(pid, pgd, base, modules[(pid, pgd)][base].get_size(), modules[(pid, pgd)][base].get_name(), modules[(pid, pgd)][base].get_fullname()) del modules[(pid, pgd)][base] dispatch_module_load_callback(pid, pgd, base, size, basename, fullname) modules[(pid, pgd)][base] = mod else: # Just notify of module load dispatch_module_load_callback(pid, pgd, base, size, basename, fullname) modules[(pid, pgd)][base] = mod # Mark the module as present modules[(pid, pgd)][base].set_present() if update_symbols: # Compute the checksum of the ELF Header, as a way to avoid name # collisions on the symbol cache. May extend this hash to other parts # of the binary if necessary in the future. elf_hdr = obj.Object( "elf_hdr", offset=base, vm=task.get_process_address_space()) if elf_hdr.is_valid(): elf_hdr_size = elf_hdr.elf_obj.size() buf = "" try: buf = api.r_va(pgd_for_memory_read, base, elf_hdr_size) except: pp_warning("Could not read ELF header at address %x" % base) h = hashlib.sha256() h.update(buf) checksum = h.hexdigest() if (checksum, fullname) not in symbols: symbols[(checksum, fullname)] = {} syms = symbols[(checksum, fullname)] # Fetch symbols for sym in elf_hdr.symbols(): if sym.st_value == 0 or (sym.st_info & 0xf) != 2: continue sym_name = elf_hdr.symbol_name(sym) sym_offset = sym.st_value if sym_name in syms: if syms[sym_name] != sym_offset: # There are cases in which the same import is present twice, such as in this case: # nm /lib/x86_64-linux-gnu/libpthread-2.24.so | grep "pthread_getaffinity_np" # 00000000000113f0 T pthread_getaffinity_np@GLIBC_2.3.3 # 00000000000113a0 T # pthread_getaffinity_np@@GLIBC_2.3.4 sym_name = sym_name + "_" while sym_name in syms and syms[sym_name] != sym_offset: sym_name = sym_name + "_" if sym_name not in syms: syms[sym_name] = sym_offset else: syms[sym_name] = sym_offset mod.set_symbols(symbols[(checksum, fullname)]) return None