def linux_insert_kernel_module(module, base, size, basename, fullname, update_symbols=False): from vmi import modules from vmi import symbols from vmi import Module # Create module, use 0 as checksum as it is irrelevant here mod = Module(base, size, 0, 0, 0, basename, fullname) # Add an entry in the module list, if necessary if (0, 0) not in modules: modules[(0, 0)] = {} # Add the module to the module list if base in modules[(0, 0)]: del modules[(0, 0)][base] modules[(0, 0)][base] = mod if update_symbols: # Use 0 as a checksum, here we should not have name collision checksum = 0 if (checksum, fullname) not in symbols: symbols[(checksum, fullname)] = {} syms = symbols[(checksum, fullname)] try: ''' pp_debug("Processing symbols for module %s\n" % basename) ''' for sym_name, sym_offset in module.get_symbols(): 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 except Exception as e: # Probably could not fetch the symbols for this module pp_error("%s" % str(e)) pass mod.set_symbols(symbols[(checksum, fullname)]) return None
def windows_insert_module_internal( p_pid, p_pgd, base, size, fullname, basename, checksum, nt_header, update_symbols): from utils import get_addr_space from vmi import modules from vmi import symbols from vmi import Module from vmi import PseudoLDRDATA mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname) if p_pgd != 0: addr_space = get_addr_space(p_pgd) else: addr_space = get_addr_space() # Getting symbols, from cache! if (checksum, fullname) in symbols: mod.set_symbols(symbols[(checksum, fullname)]) elif update_symbols: syms = [] export_dir = nt_header.OptionalHeader.DataDirectory[0] if export_dir: expdir = obj.Object( '_IMAGE_EXPORT_DIRECTORY', offset=base + export_dir.VirtualAddress, vm=addr_space, parent=PseudoLDRDATA( base, basename, export_dir)) if expdir.valid(nt_header): # Ordinal, Function RVA, and Name Object for o, f, n in expdir._exported_functions(): if not isinstance(o, obj.NoneObject) and \ not isinstance(f, obj.NoneObject) and \ not isinstance(n, obj.NoneObject): syms.append((o, f.v(), str(n))) symbols[(checksum, fullname)] = syms mod.set_symbols(syms) if base in modules[(p_pid, p_pgd)]: del modules[(p_pid, p_pgd)][base] modules[(p_pid, p_pgd)][base] = mod
def windows_insert_module_internal(p_pid, p_pgd, base, size, fullname, basename, checksum, nt_header, update_symbols): import volatility.conf as volconf import volatility.registry as registry import volatility.commands as commands import volatility.addrspace as addrspace import volatility.constants as constants import volatility.exceptions as exceptions import volatility.obj as obj import volatility.scan as scan import volatility.plugins.kdbgscan as kdbg import volatility.win32.tasks as tasks import volatility.utils as utils from utils import get_addr_space from vmi import modules from vmi import symbols from vmi import Module from vmi import PseudoLDRDATA mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname) if p_pgd != 0: addr_space = get_addr_space(p_pgd) else: addr_space = get_addr_space() #Getting symbols, from cache! if (checksum, fullname) in symbols: mod.set_symbols(symbols[(checksum, fullname)]) elif update_symbols: syms = [] export_dir = nt_header.OptionalHeader.DataDirectory[0] if export_dir: expdir = obj.Object('_IMAGE_EXPORT_DIRECTORY', offset=base + export_dir.VirtualAddress, vm=addr_space, parent=PseudoLDRDATA(base, basename, export_dir)) if expdir.valid(nt_header): # Ordinal, Function RVA, and Name Object for o, f, n in expdir._exported_functions(): if not type(o) is obj.NoneObject and \ not type(f) is obj.NoneObject and \ not type(n) is obj.NoneObject: syms.append((o, f.v(), str(n))) symbols[(checksum, fullname)] = syms mod.set_symbols(syms) if base in modules[(p_pid, p_pgd)]: del modules[(p_pid, p_pgd)][base] modules[(p_pid, p_pgd)][base] = mod
def windows_insert_module_internal(p_pid, p_pgd, base, size, fullname, basename, checksum, nt_header, update_symbols): from utils import get_addr_space from vmi import modules from vmi import symbols from vmi import Module from vmi import PseudoLDRDATA from api_internal import dispatch_module_load_callback from api_internal import dispatch_module_remove_callback mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname) if p_pgd != 0: addr_space = get_addr_space(p_pgd) else: addr_space = get_addr_space() # First, we try to get the symbols from the cache if (checksum, fullname) in symbols: mod.set_symbols(symbols[(checksum, fullname)]) # If we are updating symbols (a simple module retrieval would # not require symbol extraction), and, either we dont have any # symbols on the cache, or we have an empty list (symbols could # not be retrieved for some reason, such as a missing memory page, # we try symbol resolution if update_symbols and ((checksum, fullname) not in symbols or len(symbols[(checksum, fullname)]) == 0): syms = {} export_dir = nt_header.OptionalHeader.DataDirectory[0] if export_dir: expdir = obj.Object('_IMAGE_EXPORT_DIRECTORY', offset=base + export_dir.VirtualAddress, vm=addr_space, parent=PseudoLDRDATA(base, basename, export_dir)) if expdir.valid(nt_header): # Ordinal, Function RVA, and Name Object for o, f, n in expdir._exported_functions(): if not isinstance(o, obj.NoneObject) and \ not isinstance(f, obj.NoneObject) and \ not isinstance(n, obj.NoneObject): syms[str(n)] = f.v() # If we managed to parse export table, update symbols, # no matter if it is empty if (checksum, fullname) not in symbols or len(syms) > len( symbols[(checksum, fullname)]): symbols[(checksum, fullname)] = syms # Even if it is empty, the module symbols are set # to an empty list, and thus are 'resolved'. # Anyway, in future updates, they could be resolved, # as we allow this in the first condition. mod.set_symbols(symbols[(checksum, fullname)]) # Add module to mods_pending, or # Update modules that may we might not have been # able to resolve symbols in the past if len(syms) == 0: if (checksum, fullname) not in mods_pending: mods_pending[(checksum, fullname)] = [] mods_pending[(checksum, fullname)].append(mod) else: if (checksum, fullname) in mods_pending and len( mods_pending[(checksum, fullname)]) > 0: for mod in mods_pending[(checksum, fullname)]: mod.set_symbols(syms) del mods_pending[(checksum, fullname)] else: # Since there is no export dir, we assume that it does # not have any symbols if (checksum, fullname) not in symbols: symbols[(checksum, fullname)] = [] # Even if it is empty, the module symbols are set # to an empty list, and thus are 'resolved'. # Anyway, in future updates, they could be resolved, # as we allow this in the first condition. mod.set_symbols(symbols[(checksum, fullname)]) # Add module to mods_pending, or if (checksum, fullname) not in mods_pending: mods_pending[(checksum, fullname)] = [] mods_pending[(checksum, fullname)].append(mod) #Module load/del notification if base in modules[(p_pid, p_pgd)]: if modules[(p_pid, p_pgd)][base].get_size() != size or \ modules[(p_pid, p_pgd)][base].get_checksum() != checksum or \ modules[(p_pid, p_pgd)][base].get_name() != basename or \ modules[(p_pid, p_pgd)][base].get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback( p_pid, p_pgd, base, modules[(p_pid, p_pgd)][base].get_size(), modules[(p_pid, p_pgd)][base].get_name(), modules[(p_pid, p_pgd)][base].get_fullname()) del modules[(p_pid, p_pgd)][base] modules[(p_pid, p_pgd)][base] = mod dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) # If we updated the symbols and have a bigger list now, dont substitute the module # but update its symbols instead elif len(mod.get_symbols()) > len( modules[(p_pid, p_pgd)][base].get_symbols()): modules[(p_pid, p_pgd)][base].set_symbols(mod.get_symbols()) else: # Just notify of module load modules[(p_pid, p_pgd)][base] = mod dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) # Mark the module as present modules[(p_pid, p_pgd)][base].set_present()
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 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)] = {} # Add the module to the module list if base in modules[(pid, pgd)]: del modules[(pid, pgd)][base] modules[(pid, pgd)][base] = mod 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 = api.r_va(pgd_for_memory_read, base, elf_hdr_size) 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
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_kernel_module(module, base, size, basename, fullname, update_symbols=False): from vmi import add_module from vmi import has_module from vmi import get_module from vmi import has_symbols from vmi import get_symbols from vmi import add_symbols from vmi import Module from api_internal import dispatch_module_load_callback from api_internal import dispatch_module_remove_callback # Create module, use 0 as checksum as it is irrelevant here mod = Module(base, size, 0, 0, 0, basename, fullname) #Module load/del notification if has_module(0, 0, base): ex_mod = get_module(0, 0, 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(0, 0, base, ex_mod.get_size(), ex_mod.get_name(), ex_mod.get_fullname()) dispatch_module_load_callback(0, 0, base, size, basename, fullname) add_module(0, 0, base, mod) else: # Just notify of module load dispatch_module_load_callback(0, 0, base, size, basename, fullname) add_module(0, 0, base, mod) # Mark the module as present get_module(0, 0, base).set_present() if update_symbols: if not has_symbols(fullname): syms = {} try: ''' pp_debug("Processing symbols for module %s\n" % basename) ''' for sym_name, sym_offset in module.get_symbols(): 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) except Exception as e: # Probably could not fetch the symbols for this module pp_error("%s" % str(e)) pass mod.set_symbols(get_symbols(fullname)) return None
def linux_insert_kernel_module(module, base, size, basename, fullname, update_symbols=False): 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 # Create module, use 0 as checksum as it is irrelevant here mod = Module(base, size, 0, 0, 0, basename, fullname) # Add an entry in the module list, if necessary if (0, 0) not in modules: modules[(0, 0)] = {} #Module load/del notification if base in modules[(0, 0)]: if modules[(0, 0)][base].get_size() != size or \ modules[(0, 0)][base].get_checksum() != checksum or \ modules[(0, 0)][base].get_name() != basename or \ modules[(0, 0)][base].get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback( 0, 0, base, modules[(0, 0)][base].get_size(), modules[(0, 0)][base].get_name(), modules[(0, 0)][base].get_fullname()) del modules[(0, 0)][base] dispatch_module_load_callback(0, 0, base, size, basename, fullname) modules[(0, 0)][base] = mod else: # Just notify of module load dispatch_module_load_callback(0, 0, base, size, basename, fullname) modules[(0, 0)][base] = mod # Mark the module as present modules[(0, 0)][base].set_present() if update_symbols: # Use 0 as a checksum, here we should not have name collision checksum = 0 if (checksum, fullname) not in symbols: symbols[(checksum, fullname)] = {} syms = symbols[(checksum, fullname)] try: ''' pp_debug("Processing symbols for module %s\n" % basename) ''' for sym_name, sym_offset in module.get_symbols(): 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 except Exception as e: # Probably could not fetch the symbols for this module pp_error("%s" % str(e)) pass mod.set_symbols(symbols[(checksum, fullname)]) return None
def windows_insert_module_internal(p_pid, p_pgd, base, size, fullname, basename, checksum, nt_header, update_symbols): from utils import get_addr_space from vmi import modules from vmi import symbols from vmi import Module from vmi import PseudoLDRDATA from api_internal import dispatch_module_load_callback from api_internal import dispatch_module_remove_callback mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname) if p_pgd != 0: addr_space = get_addr_space(p_pgd) else: addr_space = get_addr_space() # Getting symbols, from cache! if (checksum, fullname) in symbols: mod.set_symbols(symbols[(checksum, fullname)]) elif update_symbols: syms = {} export_dir = nt_header.OptionalHeader.DataDirectory[0] if export_dir: expdir = obj.Object('_IMAGE_EXPORT_DIRECTORY', offset=base + export_dir.VirtualAddress, vm=addr_space, parent=PseudoLDRDATA(base, basename, export_dir)) if expdir.valid(nt_header): # Ordinal, Function RVA, and Name Object for o, f, n in expdir._exported_functions(): if not isinstance(o, obj.NoneObject) and \ not isinstance(f, obj.NoneObject) and \ not isinstance(n, obj.NoneObject): syms[str(n)] = f.v() if len(syms) > 0: symbols[(checksum, fullname)] = syms mod.set_symbols(syms) if (checksum, fullname) in mods_pending: for m in mods_pending[(checksum, fullname)]: m.set_symbols(syms) del mods_pending[(checksum, fullname)] else: if (checksum, fullname) in mods_pending: mods_pending[(checksum, fullname)].append(mod) else: mods_pending[(checksum, fullname)] = [mod] #Module load/del notification if base in modules[(p_pid, p_pgd)]: if modules[(p_pid, p_pgd)][base].get_size() != size or \ modules[(p_pid, p_pgd)][base].get_checksum() != checksum or \ modules[(p_pid, p_pgd)][base].get_name() != basename or \ modules[(p_pid, p_pgd)][base].get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback( p_pid, p_pgd, base, modules[(p_pid, p_pgd)][base].get_size(), modules[(p_pid, p_pgd)][base].get_name(), modules[(p_pid, p_pgd)][base].get_fullname()) del modules[(p_pid, p_pgd)][base] dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) modules[(p_pid, p_pgd)][base] = mod else: # Just notify of module load dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) modules[(p_pid, p_pgd)][base] = mod # Mark the module as present modules[(p_pid, p_pgd)][base].set_present()
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
def linux_insert_kernel_module(module, base, size, basename, fullname, update_symbols=False): 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 # Create module, use 0 as checksum as it is irrelevant here mod = Module(base, size, 0, 0, 0, basename, fullname) # Add an entry in the module list, if necessary if (0, 0) not in modules: modules[(0, 0)] = {} #Module load/del notification if base in modules[(0, 0)]: if modules[(0, 0)][base].get_size() != size or \ modules[(0, 0)][base].get_checksum() != checksum or \ modules[(0, 0)][base].get_name() != basename or \ modules[(0, 0)][base].get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback(0, 0, base, modules[(0, 0)][base].get_size(), modules[(0, 0)][base].get_name(), modules[(0, 0)][base].get_fullname()) del modules[(0, 0)][base] dispatch_module_load_callback(0, 0, base, size, basename, fullname) modules[(0, 0)][base] = mod else: # Just notify of module load dispatch_module_load_callback(0, 0, base, size, basename, fullname) modules[(0, 0)][base] = mod # Mark the module as present modules[(0, 0)][base].set_present() if update_symbols: # Use 0 as a checksum, here we should not have name collision checksum = 0 if (checksum, fullname) not in symbols: symbols[(checksum, fullname)] = {} syms = symbols[(checksum, fullname)] try: ''' pp_debug("Processing symbols for module %s\n" % basename) ''' for sym_name, sym_offset in module.get_symbols(): 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 except Exception as e: # Probably could not fetch the symbols for this module pp_error("%s" % str(e)) pass mod.set_symbols(symbols[(checksum, fullname)]) return None
def windows_insert_module_internal( p_pid, p_pgd, base, size, fullname, basename, checksum, update_symbols, do_stop = False): from utils import get_addr_space from vmi import add_symbols from vmi import get_symbols from vmi import has_symbols from vmi import Module from vmi import add_module from vmi import get_module from vmi import has_module from api_internal import dispatch_module_load_callback from api_internal import dispatch_module_remove_callback import pefile import api global filesystem global symbol_cache_must_be_saved if fullname.startswith("\\??\\"): fullname = fullname[4:] if fullname.upper().startswith("C:\\"): fullname = fullname[3:] if fullname.upper().startswith("\\SYSTEMROOT"): fullname = "\WINDOWS" + fullname[11:] fullname = fullname.replace("\\", "/") if fullname[-4:].upper() == ".SYS" and not "/" in fullname: fullname = "/WINDOWS/system32/DRIVERS/" + fullname fullname = fullname.lower() mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname) # First, we try to get the symbols from the cache if fullname != "" and has_symbols(fullname): mod.set_symbols(get_symbols(fullname)) # If we are updating symbols (a simple module retrieval would # not require symbol extraction), and we don't have any # symbols on the cache: elif fullname != "" and update_symbols: pp_debug("Symbols not found in cache, extracting from %s...\n" % fullname) unnamed_function_counter = 0 syms = {} # Here, fetch the file using the sleuthkit, and use # PE file to process it # First select the file system if not selected already if filesystem is None: for fs in api.get_filesystems(): file_list = api.open_guest_path(fs["index"], "") if isinstance(file_list, list) and len(file_list) > 0: if "windows" in [f.lower() for f in file_list]: filesystem = fs if filesystem is not None: # Try to read the file f = None try: f = api.open_guest_path(filesystem["index"], fullname) except Exception as e: pp_error("%s - %s\n" % (str(e), fullname)) if f is not None: data = f.read() pe = pefile.PE(data=data) if hasattr(pe, "DIRECTORY_ENTRY_EXPORT"): for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols: if exp.name is not None: syms[exp.name] = exp.address else: syms["unnamed_funcion_%d" % unnamed_function_counter] = exp.address unnamed_function_counter += 1 add_symbols(fullname, syms) mod.set_symbols(syms) # Even if it is empty, the module symbols are set # to an empty list, and thus are 'resolved'. # Anyway, in future updates, they could be resolved, # as we allow this in the first condition. symbol_cache_must_be_saved = True #Module load/del notification if has_module(p_pid, p_pgd, base): ex_mod = get_module(p_pid, p_pgd, base) # Module replacement, only if it is a different module, and also # take into consideration wow64 redirection. Never substitute the # wow64 version by the system32 version of the same dll if (ex_mod.get_fullname().lower() != fullname.lower()) and not ((ex_mod.get_name().lower() == basename.lower()) and ("windows/syswow64".lower() in ex_mod.get_fullname().lower()) and ("windows/system32" in fullname.lower())): # Notify of module deletion and module load dispatch_module_remove_callback(p_pid, p_pgd, base, ex_mod.get_size(), ex_mod.get_name(), ex_mod.get_fullname()) add_module(p_pid, p_pgd, base, mod) mod.set_present() dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) # If we updated the symbols and have a bigger list now, dont substitute the module # but update its symbols instead elif len(mod.get_symbols()) > len(ex_mod.get_symbols()): ex_mod.set_symbols(mod.get_symbols()) # In any case, mark as present ex_mod.set_present() else: # Just notify of module load add_module(p_pid, p_pgd, base, mod) # Mark the module as present mod.set_present() dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname)
def windows_insert_module_internal(p_pid, p_pgd, base, size, fullname, basename, checksum, update_symbols): from utils import get_addr_space 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 pefile import api global filesystem global symbol_cache_must_be_saved if fullname.startswith("\\??\\"): fullname = fullname[4:] if fullname.upper().startswith("C:\\"): fullname = fullname[3:] if fullname.upper().startswith("\\SYSTEMROOT"): fullname = "\WINDOWS" + fullname[11:] fullname = fullname.replace("\\", "/") if fullname[-4:].upper() == ".SYS" and not "/" in fullname: fullname = "/WINDOWS/system32/DRIVERS/" + fullname fullname = fullname.lower() mod = Module(base, size, p_pid, p_pgd, checksum, basename, fullname) # First, we try to get the symbols from the cache if fullname != "" and fullname in symbols.keys(): mod.set_symbols(symbols[fullname]) # If we are updating symbols (a simple module retrieval would # not require symbol extraction), and we don't have any # symbols on the cache: elif fullname != "" and update_symbols: unnamed_function_counter = 0 syms = {} # Here, fetch the file using the sleuthkit, and use # PE file to process it # First select the file system if not selected already if filesystem is None: for fs in api.get_filesystems(): file_list = api.open_guest_path(fs["index"], "") if isinstance(file_list, list) and len(file_list) > 0: if "windows" in [f.lower() for f in file_list]: filesystem = fs if filesystem is not None: # Try to read the file f = None try: f = api.open_guest_path(filesystem["index"], fullname) except Exception as e: pp_error("%s - %s\n" % (str(e), fullname)) if f is not None: data = f.read() pe = pefile.PE(data=data) if hasattr(pe, "DIRECTORY_ENTRY_EXPORT"): for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols: if exp.name is not None: syms[exp.name] = exp.address else: syms["unnamed_funcion_%d" % unnamed_function_counter] = exp.address unnamed_function_counter += 1 # If we managed to parse the export table, update the symbols # except if it is empty if fullname not in symbols.keys(): symbols[fullname] = syms # Even if it is empty, the module symbols are set # to an empty list, and thus are 'resolved'. # Anyway, in future updates, they could be resolved, # as we allow this in the first condition. mod.set_symbols(symbols[fullname]) symbol_cache_must_be_saved = True else: symbols[fullname] = {} mod.set_symbols(symbols[fullname]) #Module load/del notification if base in modules[(p_pid, p_pgd)]: if modules[(p_pid, p_pgd)][base].get_size() != size or \ modules[(p_pid, p_pgd)][base].get_checksum() != checksum or \ modules[(p_pid, p_pgd)][base].get_name() != basename or \ modules[(p_pid, p_pgd)][base].get_fullname() != fullname: # Notify of module deletion and module load dispatch_module_remove_callback( p_pid, p_pgd, base, modules[(p_pid, p_pgd)][base].get_size(), modules[(p_pid, p_pgd)][base].get_name(), modules[(p_pid, p_pgd)][base].get_fullname()) del modules[(p_pid, p_pgd)][base] modules[(p_pid, p_pgd)][base] = mod dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) # If we updated the symbols and have a bigger list now, dont substitute the module # but update its symbols instead elif len(mod.get_symbols()) > len( modules[(p_pid, p_pgd)][base].get_symbols()): modules[(p_pid, p_pgd)][base].set_symbols(mod.get_symbols()) else: # Just notify of module load modules[(p_pid, p_pgd)][base] = mod dispatch_module_load_callback(p_pid, p_pgd, base, size, basename, fullname) # Mark the module as present modules[(p_pid, p_pgd)][base].set_present()