Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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()
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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()
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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)
Esempio n. 13
0
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()