Example #1
0
    def generator(self, data):
        for task in data:
            pid = task.UniqueProcessId

            if task.Peb:
                for m in task.get_load_modules():
                    yield (0, [int(pid), Address(m.DllBase), Hex(m.SizeOfImage), Hex(m.LoadCount), str(m.FullDllName or '')])
            else:
                yield (0, [int(pid), Address(0), Hex(0), Hex(0), "Error reading PEB for pid"])
Example #2
0
 def generator(data):
     for object_type in data:
         yield (0, [
             Address(object_type.obj_offset),
             Hex(object_type.TotalNumberOfObjects),
             Hex(object_type.TotalNumberOfHandles),
             str(object_type.Key),
             str(object_type.Name or ''),
             str(object_type.TypeInfo.PoolType)
         ])
    def update_proc_vad_info(self, proc_peb_info):
        """Builds a dictionary of process executable information from VAD"""
        self.proc_vad_info = {}
        for pid in proc_peb_info:
            self.proc_vad_info[pid] = []
            proc = proc_peb_info[pid][0]

            if proc.Peb:
                # gets process information for the process executable from VAD and updates the dictionary
                for vad, addr_space in proc.get_vads(
                        vad_filter=proc._mapped_file_filter):
                    ext = ""
                    vad_found = False
                    if obj.Object("_IMAGE_DOS_HEADER",
                                  offset=vad.Start,
                                  vm=addr_space).e_magic != 0x5A4D:
                        continue

                    if str(vad.FileObject.FileName or ''):
                        ext = os.path.splitext(str(
                            vad.FileObject.FileName))[1].lower()

                    if (ext == ".exe") or (vad.Start
                                           == proc.Peb.ImageBaseAddress):
                        vad_filename = vad.FileObject.FileName
                        vad_baseaddr = vad.Start
                        vad_size = vad.End - vad.Start
                        vad_protection = vadinfo.PROTECT_FLAGS.get(
                            vad.VadFlags.Protection.v())
                        vad_tag = vad.Tag
                        self.proc_vad_info[pid].extend([
                            str(vad_filename or ''),
                            Address(vad_baseaddr),
                            Hex(vad_size),
                            str(vad_protection or ''),
                            str(vad_tag or '')
                        ])
                        vad_found = True
                        break

                if vad_found == False:
                    self.proc_vad_info[pid].extend(
                        ["NA", Address(0),
                         Hex(0), "NA", "NA"])

            else:
                self.proc_vad_info[pid].extend(
                    ["No VAD",
                     Address(0),
                     Hex(0), "No VAD", "No VAD"])
Example #4
0
    def generator(self, data):
        for process, module, hook in data:
            if not self._config.NO_WHITELIST:
                process_name = ""
                if process:
                    process_name = str(process.ImageFileName)

                if self.whitelist(hook.hook_mode | hook.hook_type,
                                    process_name, hook.VictimModule,
                                    hook.HookModule, hook.Function):
                    continue

            procname = "N/A"
            pid = -1
            if process:
                procname = str(process.ImageFileName)
                pid = int(process.UniqueProcessId)

            for n, info in enumerate(hook.disassembled_hops):
                (address, data) = info
                yield (0, [str(hook.Mode),
                    str(hook.Type),
                    procname,
                    pid,
                    str(module.BaseDllName or '') or ntpath.basename(str(module.FullDllName or '')),
                    Address(module.DllBase),
                    Hex(module.DllBase + module.SizeOfImage),
                    str(hook.Detail),
                    Address(hook.hook_address),
                    str(hook.HookModule),
                    Address(address),
                    Bytes(data)])
Example #5
0
    def generator(self, data):
        for atom_table in data:

            # This defeats the purpose of having a generator, but
            # its required if we want to be able to sort. We also
            # filter string atoms here.
            atoms = [a for a in atom_table.atoms() if a.is_string_atom()]

            if self._config.SORT_BY == "atom":
                attr = "Atom"
            elif self._config.SORT_BY == "refcount":
                attr = "ReferenceCount"
            else:
                attr = "obj_offset"

            for atom in sorted(atoms, key = lambda x: getattr(x, attr)):

                yield (0,
                    [Address(atom_table.obj_offset),
                    Address(atom.obj_offset),
                    Hex(atom.Atom),
                    int(atom.ReferenceCount),
                    int(atom.Pinned),
                    str(atom.Name or "")]
                    )
Example #6
0
 def generator(self, data):
     for memory_offset, file_offset, length in data.get_runs():
         yield (
             0,
             [Address(file_offset),
              Address(memory_offset),
              Hex(length)],
         )
Example #7
0
 def generator(data):
     for ldr_entry in data:
         yield (0,
                      [Address(ldr_entry.obj_offset),
                      str(ldr_entry.BaseDllName or ''),
                      Address(ldr_entry.DllBase),
                      Hex(ldr_entry.SizeOfImage),
                      str(ldr_entry.FullDllName or '')])
Example #8
0
    def generator(self, data):
        seen = []

        for window_station in data:
            for desktop in window_station.desktops():
                offset = desktop.PhysicalAddress
                if offset in seen:
                    continue
                seen.append(offset)
                name = "{0}\\{1}".format(desktop.WindowStation.Name,
                                         desktop.Name)

                for thrd in desktop.threads():
                    yield (0, [
                        Address(offset), name,
                        Hex(desktop.rpdeskNext.v()),
                        int(desktop.dwSessionId),
                        Hex(desktop.pDeskInfo.v()),
                        int(desktop.DeskInfo.fsHooks),
                        Hex(desktop.DeskInfo.spwnd),
                        int(len(list(desktop.windows(
                            desktop.DeskInfo.spwnd)))),
                        Hex(desktop.pheapDesktop.v()),
                        Hex(desktop.DeskInfo.pvDesktopLimit -
                            desktop.DeskInfo.pvDesktopBase),
                        Hex(desktop.DeskInfo.pvDesktopBase),
                        Hex(desktop.DeskInfo.pvDesktopLimit),
                        int(thrd.pEThread.Cid.UniqueThread),
                        str(thrd.ppi.Process.ImageFileName),
                        int(thrd.ppi.Process.UniqueProcessId),
                        int(thrd.ppi.Process.InheritedFromUniqueProcessId)
                    ])
Example #9
0
    def update_proc_peb_info(self, psdata):
        self.proc_peb_info = {}
        # Builds a dictionary of process executable information from PEB
        for proc in psdata:
            pid = int(proc.UniqueProcessId)
            self.proc_peb_info[pid] = [
                proc, pid, proc.ImageFileName,
                int(proc.InheritedFromUniqueProcessId),
                str(proc.CreateTime)
            ]
            if proc.Peb:
                # gets process information for the process executable from PEB and updates the dictionary
                mods = proc.get_load_modules()
                for mod in mods:
                    ext = os.path.splitext(str(mod.FullDllName))[1].lower()
                    if (ext == ".exe"):
                        proc_cmd_line = proc.Peb.ProcessParameters.CommandLine
                        proc_image_pathname = proc.Peb.ProcessParameters.ImagePathName
                        proc_image_baseaddr = proc.Peb.ImageBaseAddress
                        mod_baseaddr = mod.DllBase
                        mod_size = mod.SizeOfImage
                        mod_basename = mod.BaseDllName
                        mod_fullname = mod.FullDllName
                        break

                self.proc_peb_info[pid].extend([
                    str(proc_cmd_line),
                    str(proc_image_pathname),
                    Address(proc_image_baseaddr),
                    Address(mod_baseaddr),
                    Hex(mod_size),
                    str(mod_basename),
                    str(mod_fullname or "")
                ])

            else:
                self.proc_peb_info[pid].extend([
                    "NoPEB", "NoPEB",
                    Address(0),
                    Address(0),
                    Hex(0), "NoPEB", "NoPEB"
                ])
Example #10
0
    def generator(self, data):
        for n, entry, addr, module in data:
            if addr == 0:
                module_name = "NOT USED"
                sect_name = ""
            elif module:
                module_name = str(module.BaseDllName or "") 
                sect_name = self.get_section_name(module, addr)
            else:
                module_name = "UNKNOWN"
                sect_name = ""

            # The parent is IDT. The grand-parent is _KPCR. 
            cpu_number = entry.obj_parent.obj_parent.ProcessorBlock.Number

            yield (0, [Hex(cpu_number), Hex(n),
                          Address(entry.Selector),
                          Address(addr),
                          str(module_name),
                          str(sect_name)])
Example #11
0
 def generator(self, data):
     for module in data:
         if not self._config.PHYSICAL_OFFSET:
             offset = module.obj_offset
         else:
             offset = module.obj_vm.vtop(module.obj_offset)
         yield (0,
                [Address(offset),
                 str(module.BaseDllName or ''),
                 Address(module.DllBase),
                 Hex(module.SizeOfImage),
                 str(module.FullDllName or '')])
Example #12
0
    def generator(self, data):
        if self._config.OBJECT_TYPE:
            object_list = [s for s in self._config.OBJECT_TYPE.split(',')]
        else:
            object_list = []
        for pid, handle, object_type, name in data:
            if object_list and object_type not in object_list:
                continue
            if self._config.SILENT:
                if len(name.replace("'", "")) == 0:
                    continue
            if not self._config.PHYSICAL_OFFSET:
                offset = handle.Body.obj_offset
            else:
                offset = handle.obj_vm.vtop(handle.Body.obj_offset)

            yield (0, [
                Address(offset),
                int(pid),
                Hex(handle.HandleValue),
                Hex(handle.GrantedAccess),
                str(object_type),
                str(name)
            ])
Example #13
0
    def generator(self, data):
        for atom_table, window_station in data:
            for atom in atom_table.atoms():

                ## Filter string atoms
                if not atom.is_string_atom():
                    continue

                yield (0,
                    [Address(atom_table.PhysicalAddress),
                    int(window_station.dwSessionId),
                    str(window_station.Name or ''),
                    Hex(atom.Atom),
                    int(atom.ReferenceCount),
                    int(atom.HandleIndex),
                    int(atom.Pinned),
                    str(atom.Name or "")]
                    )
Example #14
0
    def generator(self, data):
        for session, wndsta, clip, handle in data:
            # If no tagCLIP is provided, we do not know the format
            if not clip:
                fmt = obj.NoneObject("Format unknown")
            else:
                # Try to get the format name, but failing that, print
                # the format number in hex instead.
                if clip.fmt.v() in consts.CLIPBOARD_FORMAT_ENUM:
                    fmt = str(clip.fmt)
                else:
                    fmt = hex(clip.fmt.v())

            # Try to get the handle from tagCLIP first, but
            # fall back to using _HANDLEENTRY.phead. Note: this can
            # be a value like DUMMY_TEXT_HANDLE (1) etc.
            if clip:
                handle_value = clip.hData
            else:
                handle_value = handle.phead.h

            clip_data = ""
            if handle:
                try:
                    clip_data = ''.join(
                        [chr(c) for c in handle.reference_object().abData])
                except AttributeError:
                    pass

            yield (
                0,
                [
                    int(session.SessionId),
                    str(wndsta.Name),
                    str(fmt),
                    Hex(handle_value),
                    Address(handle.phead.v()),
                    Bytes(clip_data),
                ],
            )
Example #15
0
    def generator(self, tasks):
        for task in tasks:
            wnf_process_context = task.WnfContext.dereference_as('_WNF_PROCESS_CONTEXT')
            for subscriber in wnf_process_context.SubscriptionListHead.list_of_type("_WNF_SUBSCRIPTION_CONTEXT", "SubscriptionContexts"):
                # case of subscriber head
                if subscriber.Header.NodeTypeCode != 0x905:
                    continue

                # sometimes reference a not in memory object (explorer.exe)
                # very strange...
                if subscriber.NameInstance.Header.NodeTypeCode != 0x903:
                    clear = subscriber.WnfId ^ 0x41C64E6DA3BC0074
                else:
                    clear = subscriber.NameInstance.WnfId ^ 0x41C64E6DA3BC0074

                if self._config.WNFID and int(self._config.wnfid, 16) != clear:
                    continue

                if self._config.Scope and int(self._config.scope, 16) != subscriber.NameInstance.ScopeInstance.v():
                    continue

                yield (0, [
                    Address(subscriber.v()),
                    task.UniqueProcessId.v(),
                    str(task.ImageFileName),
                    Address(subscriber.NameInstance),
                    Hex(clear),
                    int(clear & 0xf),
                    int(clear >> 4 & 0x3),
                    int(clear >> 6 & 0xf),
                    int(clear >> 0xa & 0x1),
                    Address(subscriber.NameInstance.ScopeInstance.get_scope_map_instance().v()),
                    Address(subscriber.NameInstance.ScopeInstance),
                    int(subscriber.NameInstance.ScopeInstance.Scope),
                    str(bool(subscriber.NameInstance.WnfData)),
                    int(subscriber.NameInstance.WnfData.DataSize)
                ])
Example #16
0
    def generator(self, data):
        # Determine which filters the user wants to see
        if self._config.FILTER:
            filters = set(self._config.FILTER.split(','))
        else:
            filters = set()

        for thread, addr_space, mods, mod_addrs, \
                     instances, hooked_tables, system_range, owner_name in data:
            # If the user didn't set filters, display all results. If
            # the user set one or more filters, only show threads
            # with matching results.
            tags = set([t for t, v in instances.items() if v.check()])

            if filters and not filters & tags:
                continue

            values = []

            values.append(Address(thread.obj_offset))
            values.append(int(thread.Cid.UniqueProcess))
            values.append(int(thread.Cid.UniqueThread))

            values.append(','.join(tags))
            values.append(str(thread.CreateTime))
            if thread.ExitTime > 0:
                values.append(str(thread.ExitTime))
            else:
                values.append('')

            values.append(str(thread.owning_process().ImageFileName))

            values.append(str(thread.attached_process().ImageFileName))

            # Lookup the thread's state
            state = str(thread.Tcb.State)

            # Find the wait reason
            if state == 'Waiting':
                state_reason = str(thread.Tcb.WaitReason)
            else:
                state_reason = ''

            values.append(state)
            values.append(state_reason)

            values.append(int(thread.Tcb.BasePriority))
            values.append(int(thread.Tcb.Priority))
            values.append(Address(thread.Tcb.Teb))

            values.append(Address(thread.StartAddress))
            values.append(owner_name)

            # Check the flag which indicates whether Win32StartAddress is valid
            if thread.SameThreadApcFlags & 1:
                values.append(Address(thread.Win32StartAddress))
            else:
                values.append(Address(-1))

            values.append(Address(thread.Tcb.Win32Thread))
            values.append(str(thread.CrossThreadFlags))

            # Disasemble the start address if possible
            dis = ''
            process_space = thread.owning_process().get_process_address_space()

            if process_space.is_valid_address(thread.StartAddress):
                buf = process_space.zread(thread.StartAddress, 24)

                mode = "32bit" if self.bits32 else "64bit"

                dis += "\n".join(["{0:#x} {1:<16} {2}".format(o, h, i)
                    for o, i, h in malfind.Disassemble(buf, thread.StartAddress.v(), mode)])

            if self.bits32:
                # Print the registers if possible
                trapframe = thread.Tcb.TrapFrame.dereference_as("_KTRAP_FRAME")

                if trapframe:
                    for r in trapframe.Eip, trapframe.Eax, trapframe.Ebx, \
                            trapframe.Ecx, trapframe.Edx, trapframe.Esi, \
                            trapframe.Edi, trapframe.HardwareEsp, \
                            trapframe.Ebp, trapframe.ErrCode, trapframe.SegCs, \
                            trapframe.HardwareSegSs, trapframe.SegDs, \
                            trapframe.SegEs, trapframe.SegGs, trapframe.SegFs, \
                            trapframe.EFlags, trapframe.Dr0, trapframe.Dr1, \
                            trapframe.Dr2, trapframe.Dr3, trapframe.Dr6, \
                            trapframe.Dr7 :
                        values.append(Hex(r))
                else:
                    values.extend( [Hex(-1)] * 23 )

                values.append(Address(thread.Tcb.ServiceTable))

                ssdt_obj = obj.Object("_SERVICE_DESCRIPTOR_TABLE",
                    offset = thread.Tcb.ServiceTable,
                    vm = addr_space
                    )

                if ssdt_obj != None:
                    for i, desc in enumerate(ssdt_obj.Descriptors):
                        if desc.is_valid():
                            service_table = Address(desc.KiServiceTable.v())
                        else:
                            service_table = Address(-1)
                        # Show exactly which functions are hooked
                        table = desc.KiServiceTable.v()
                        if table not in hooked_tables.keys():
                            yield (0, values + [i, service_table, -1, '',
                                                Address(-1), '', dis])
                            continue
                        yielded=False
                        for (j, func_name, func_addr, mod_name) in hooked_tables[table]:
                            yielded=True
                            yield(0, values + [i, service_table, j, func_name,
                                               Address(func_addr), mod_name, dis])
                        if not yielded:
                            yield (0, values + [i, service_table, -1, '',
                                                Address(-1), '', dis])
                else:
                    values.extend([ -1, Address(-1), -1, '', Address(-1), '', dis ])
                    yield (0, values)
            else:
                # registers
                values.extend( [Hex(-1)] * 23 )
                # ssdt
                values.extend([ Address(-1), -1, Address(-1), -1, '',
                                Address(-1), '', dis ])
                yield (0, values)
Example #17
0
 def create_ps_node(task):
     proc = {
         'pid': int(task.UniqueProcessId),
         'ppid': int(task.InheritedFromUniqueProcessId),
         'name': str(task.ImageFileName),
         'ctime': str(task.CreateTime),
         'proc': task,
         'children': []
     }
     peb = {
         'cmdline': None,
         'image_baseaddr': Address(0),
         'baseaddr': Address(0),
         'size': Hex(0),
         'basename': None,
         'fullname': None
     }
     vad = {
         'filename': '<No VAD>',
         'baseaddr': Address(0),
         'size': Hex(0),
         'protection': '<No VAD>',
         'tag': '<No VAD>'
     }
     if task.Peb:
         peb['cmdline'] = task.Peb.ProcessParameters.CommandLine
         mods = task.get_load_modules()
         for mod in mods:
             ext = os.path.splitext(str(mod.FullDllName))[1].lower()
             if ext == '.exe':
                 peb['image_baseaddr'] = Address(task.Peb.ImageBaseAddress)
                 peb['baseaddr'] = Address(mod.DllBase)
                 peb['size'] = Hex(0)
                 peb['basename'] = str(mod.BaseDllName)
                 peb['fullname'] = str(mod.FullDllName)
                 break
         vads = task.get_vads(vad_filter=task._mapped_file_filter)
         for entry, addr_space in vads:
             ext = ""
             vad_found = False
             if obj.Object("_IMAGE_DOS_HEADER",
                           offset=entry.Start,
                           vm=addr_space).e_magic != 0x5A4D:
                 continue
             if str(entry.FileObject.FileName or ''):
                 ext = os.path.splitext(str(entry.FileObject.FileName))[1]
                 ext = ext.lower()
             tmp_peb_iba = task.Peb.ImageBaseAddress
             if (ext == ".exe") or (entry.Start == tmp_peb_iba):
                 vad['filename'] = str(entry.FileObject.FileName)
                 vad['baseaddr'] = Address(entry.Start)
                 vad['size'] = Hex(entry.End - entry.Start)
                 tmp_vad_fp = entry.VadFlags.Protection.v()
                 tmp_vad_fp = vadinfo.PROTECT_FLAGS.get(tmp_vad_fp)
                 vad['protection'] = str(tmp_vad_fp or '')
                 vad['tag'] = str(entry.Tag or '')
                 vad_found = True
                 break
         if not vad_found:
             vad['filename'] = 'NA'
             vad['protection'] = 'NA'
             vad['tag'] = 'NA'
     proc['peb'] = peb
     proc['vad'] = vad
     return proc
Example #18
0
    def generator(self, data):
        if self._config.DISOFFSET:
            dis = self._config.DISOFFSET

        for offset, PARTITION_TABLE, boot_code in data:
            entry1 = PARTITION_TABLE.Entry1.dereference_as('PARTITION_ENTRY')
            entry2 = PARTITION_TABLE.Entry2.dereference_as('PARTITION_ENTRY')
            entry3 = PARTITION_TABLE.Entry3.dereference_as('PARTITION_ENTRY')
            entry4 = PARTITION_TABLE.Entry4.dereference_as('PARTITION_ENTRY')
            have_bootable = entry1.is_bootable_and_used(
            ) or entry2.is_bootable_and_used() or entry3.is_bootable_and_used(
            ) or entry4.is_bootable_and_used()
            if not self._config.NOCHECK and not have_bootable:
                # it doesn't really make sense to have a partition that is bootable, but empty or invalid
                # but we only skip MBRs with these types of partitions if we are checking
                continue

            distance = 0
            h = hashlib.md5()
            f = hashlib.md5()
            h.update(self.code_data)
            f.update(boot_code)
            if self._config.HASH:
                hash = "{0}".format(h.hexdigest())
                if hash.lower() != self._config.HASH.lower():
                    continue
            elif self._config.FULLHASH:
                hash = "{0}".format(f.hexdigest())
                if hash.lower() != self._config.FULLHASH.lower():
                    continue
            if self.disk_mbr:
                distance = self.levenshtein(
                    self._get_instructions(self.disk_mbr),
                    self._get_instructions(boot_code))
                if self._config.MAXDISTANCE != None and distance > self._config.MAXDISTANCE:
                    continue

            disksig = "{0:02x}-{1:02x}-{2:02x}-{3:02x}".format(
                PARTITION_TABLE.DiskSignature[0],
                PARTITION_TABLE.DiskSignature[1],
                PARTITION_TABLE.DiskSignature[2],
                PARTITION_TABLE.DiskSignature[3])

            yield (0, [
                Address(offset), disksig,
                str(h.hexdigest()),
                str(f.hexdigest()),
                int(distance), "{0:#x} {1}".format(
                    entry1.get_value(entry1.BootableFlag),
                    "(Bootable)" if entry1.is_bootable() else ""),
                "{0:#x} ({1})".format(entry1.get_value(entry1.PartitionType),
                                      entry1.get_type()),
                Hex(entry1.StartingLBA),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry1.StartingCylinder(), entry1.StartingCHS[0],
                    entry1.StartingSector()),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry1.EndingCylinder(), entry1.EndingCHS[0],
                    entry1.EndingSector()),
                Hex(entry1.SizeInSectors), "{0:#x} {1}".format(
                    entry2.get_value(entry2.BootableFlag),
                    "(Bootable)" if entry2.is_bootable() else ""),
                "{0:#x} ({1})".format(entry2.get_value(entry2.PartitionType),
                                      entry2.get_type()),
                Hex(entry2.StartingLBA),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry2.StartingCylinder(), entry2.StartingCHS[0],
                    entry2.StartingSector()),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry2.EndingCylinder(), entry2.EndingCHS[0],
                    entry2.EndingSector()),
                Hex(entry2.SizeInSectors), "{0:#x} {1}".format(
                    entry3.get_value(entry3.BootableFlag),
                    "(Bootable)" if entry3.is_bootable() else ""),
                "{0:#x} ({1})".format(entry3.get_value(entry3.PartitionType),
                                      entry3.get_type()),
                Hex(entry3.StartingLBA),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry3.StartingCylinder(), entry3.StartingCHS[0],
                    entry3.StartingSector()),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry3.EndingCylinder(), entry3.EndingCHS[0],
                    entry3.EndingSector()),
                Hex(entry3.SizeInSectors), "{0:#x} {1}".format(
                    entry4.get_value(entry4.BootableFlag),
                    "(Bootable)" if entry4.is_bootable() else ""),
                "{0:#x} ({1})".format(entry4.get_value(entry4.PartitionType),
                                      entry4.get_type()),
                Hex(entry4.StartingLBA),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry4.StartingCylinder(), entry4.StartingCHS[0],
                    entry4.StartingSector()),
                "Cylinder: {0} Head: {1} Sector: {2}".format(
                    entry4.EndingCylinder(), entry4.EndingCHS[0],
                    entry4.EndingSector()),
                Hex(entry4.SizeInSectors),
                Bytes(boot_code)
            ])