Example #1
0
    def _get_task_parents(self):
        if self.addr_space.profile.obj_has_member("task_struct", "real_parent"): 
            ret = [x.real_parent.v() for x in linux_pslist.linux_pslist(self._config).calculate()] 
        else:
            ret = [x.parent.v() for x in linux_pslist.linux_pslist(self._config).calculate()]

        return ret
Example #2
0
    def _get_task_parents(self):
        if self.addr_space.profile.obj_has_member("task_struct",
                                                  "real_parent"):
            ret = [
                self.addr_space.vtop(x.real_parent.v())
                for x in linux_pslist.linux_pslist(self._config).calculate()
            ]
        else:
            ret = [
                self.addr_space.vtop(x.parent.v())
                for x in linux_pslist.linux_pslist(self._config).calculate()
            ]

        return ret
    def filter_tasks(self):
        tasks = pslist.linux_pslist(self._config).calculate()
        if self._config.PID is not None:
            try:
                pidlist = [int(p) for p in self._config.PID.split(",")]
            except ValueError:
                debug.error("Invalid PID {0}".format(self._config.PID))

            pids = [t for t in tasks if t.pid in pidlist]
            if len(pids) == 0:
                debug.error(
                    "Cannot find PID {0}. If its terminated or unlinked, use psscan and then supply --offset=OFFSET".format(
                        self._config.PID
                    )
                )
            return pids

        if self._config.NAME is not None:
            try:
                name_re = re.compile(self._config.NAME, re.I)
            except re.error:
                debug.error("Invalid name {0}".format(self._config.NAME))

            names = [t for t in tasks if name_re.search(str(t.comm))]
            if len(names) == 0:
                debug.error(
                    "Cannot find name {0}. If its terminated or unlinked, use psscan and then supply --offset=OFFSET".format(
                        self._config.NAME
                    )
                )
            return names

        return tasks
    def calculate(self):
        linux_common.set_plugin_members(self)
        phys_addr_space = utils.load_as(self._config, astype='physical')

        pl = linux_pslist.linux_pslist(self._config).calculate()
        ps = linux_psscan.linux_psscan(self._config).calculate()

        pids = []

        for process in pl:
            pids.append(int(process.pid))

        for process in ps:
            if int(process.pid) not in pids:
                start_time = process.get_task_start_time()
                if start_time == None:
                    start_time = ""

                if process.mm.pgd == None:
                    dtb = process.mm.pgd
                else:
                    dtb = self.addr_space.vtop(
                        process.mm.pgd) or process.mm.pgd

                yield process, start_time, dtb
    def calculate(self):

        # if no gDvm object offset was specified, use this one
        if not self._config.GDVM_OFFSET:
            self._config.GDVM_OFFSET = str(0x41b0)

        # use linux_pslist plugin to find process address space and ID if not specified
        proc_as = None
        tasks = linux_pslist.linux_pslist(self._config).calculate()
        for task in tasks:
            if str(task.comm) == "keystore":
                proc_as = task.get_process_address_space()
                self._config.PID = str(task.pid)
                break

        # find stack
        for task, vma in dalvik.get_data_section_stack(self._config):
            # read length and password, they seem to have constant offset
            length = obj.Object('int',
                                offset=vma.vm_start + 0x1982c,
                                vm=proc_as)
            password = obj.Object('String',
                                  offset=vma.vm_start + 0x19830,
                                  vm=proc_as,
                                  length=length)
            yield password
     def calculate(self):
          # if no gDvm object offset was specified, use this one
          if not self._config.GDVM_OFFSET:
               self._config.GDVM_OFFSET = str(hex(0x41b0))

          # use linux_pslist plugin to find process address space and ID if not specified
          proc_as = None
          tasks = linux_pslist.linux_pslist(self._config).calculate()
          for task in tasks:
               if str(task.comm) == "ndroid.contacts":
                    proc_as = task.get_process_address_space()
                    if not self._config.PID:
                         self._config.PID = str(task.pid)
                    break

          # use dalvik_loaded_classes plugin to find class offset if not specified
          if not self._config.CLASS_OFFSET:
              classes = dalvik_loaded_classes.dalvik_loaded_classes(self._config).calculate()
              for task, clazz in classes:
                   if (dalvik.getString(clazz.sourceFile)+"" == "PhoneCallDetails.java"):
                        self._config.CLASS_OFFSET = str(hex(clazz.obj_offset))
                        break

          # use dalvik_find_class_instance plugin to find a list of possible class instances
          instances = dalvik_find_class_instance.dalvik_find_class_instance(self._config).calculate()
          for sysClass, inst in instances:
               callDetailsObj = obj.Object('PhoneCallDetails', offset = inst, vm = proc_as)
               # access type ID field for sanity check
               typeID = int(callDetailsObj.callTypes.contents0)
               # valid type ID must be 1,2 or 3
               if (typeID == 1 or typeID == 2 or typeID == 3):
                    yield callDetailsObj
Example #7
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        fs_types = self._get_filesystem_types()

        # newer kernels
        if self.profile.has_type("mount"):
            mnttype = "mount"

            cache = linux_slabinfo(self._config).get_kmem_cache(mnttype, self._config.UNALLOCATED)

            for task in linux_pslist.linux_pslist(self._config).calculate():
                if task.pid == 1:
                    ns = task.nsproxy.mnt_ns
                    break
        else:
            cache = linux_slabinfo(self._config).get_kmem_cache(
                "mnt_cache", self._config.UNALLOCATED, struct_name="vfsmount"
            )
            ns = None

        for mnt in cache:
            ret = self._parse_mnt(mnt, ns, fs_types)

            if ret:
                (mnt_sb, dev_name, path, fstype, rr, mnt_string) = ret

                if not (dev_name == "devtmpfs" and path == "/"):
                    yield (mnt_sb, dev_name, path, fstype, rr, mnt_string)
Example #8
0
    def calculate(self):

        ## we need this module imported
        if not has_yara:
            debug.error(
                "Please install Yara from code.google.com/p/yara-project")

        ## leveraged from the windows yarascan plugin
        rules = self._compile_rules()

        ## set the linux plugin address spaces
        linux_common.set_plugin_members(self)

        if self._config.KERNEL:
            ## the start of kernel memory taken from VolatilityLinuxIntelValidAS
            if self.addr_space.profile.metadata.get('memory_model',
                                                    '32bit') == "32bit":
                kernel_start = 0xc0000000
            else:
                kernel_start = 0xffffffff80000000

            scanner = malfind.DiscontigYaraScanner(
                rules=rules, address_space=self.addr_space)

            for hit, address in scanner.scan(start_offset=kernel_start):
                yield (None, address, hit,
                       scanner.address_space.zread(address, 64))
        else:
            for task in pslist.linux_pslist(self._config).calculate():
                scanner = VmaYaraScanner(task=task, rules=rules)
                for hit, address in scanner.scan():
                    yield (task, address, hit,
                           scanner.address_space.zread(address, 64))
Example #9
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        fs_types = self._get_filesystem_types()

        # newer kernels
        if self.profile.has_type("mount"):
            mnttype = "mount"

            cache = linux_slabinfo(self._config).get_kmem_cache(
                mnttype, self._config.UNALLOCATED)

            for task in linux_pslist.linux_pslist(self._config).calculate():
                if task.pid == 1:
                    ns = task.nsproxy.mnt_ns
                    break
        else:
            cache = linux_slabinfo(self._config).get_kmem_cache(
                "mnt_cache", self._config.UNALLOCATED, struct_name="vfsmount")
            ns = None

        for mnt in cache:
            ret = self._parse_mnt(mnt, ns, fs_types)

            if ret:
                (mnt_sb, dev_name, path, fstype, rr, mnt_string) = ret

                if not (dev_name == "devtmpfs" and path == "/"):
                    yield (mnt_sb, dev_name, path, fstype, rr, mnt_string)
Example #10
0
 def _fill_cache(self):
     for task in linux_pslist.linux_pslist(self._config).calculate():
         for filp, fd in task.lsof():
             filepath = linux_common.get_path(task, filp)
             if type(filepath) == str and filepath.find("socket:[") != -1:
                 to_add = filp.dentry.d_inode.i_ino
                 self.fd_cache[to_add] = [task, filp, fd, filepath]
Example #11
0
 def _fill_cache(self):
     for task in linux_pslist.linux_pslist(self._config).calculate():
         for filp, fd in task.lsof():
             filepath = linux_common.get_path(task, filp)
             if type(filepath) == str and filepath.find("socket:[") != -1:
                 to_add = filp.dentry.d_inode.i_ino.v()
                 self.fd_cache[to_add] = [task, filp, fd, filepath]
Example #12
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        mntptr = obj.Object(
            "Pointer",
            offset=self.addr_space.profile.get_symbol("mount_hashtable"),
            vm=self.addr_space)

        mnt_list = obj.Object(theType="Array",
                              offset=mntptr.v(),
                              vm=self.addr_space,
                              targetType="list_head",
                              count=512)

        if self.profile.has_type("mount"):
            mnttype = "mount"

            for task in linux_pslist.linux_pslist(self._config).calculate():
                if task.pid == 1:
                    ns = task.nsproxy.mnt_ns
                    break

        else:
            mnttype = "vfsmount"
            ns = None

        # get each list_head out of the array
        for outerlist in mnt_list:

            for mnt in outerlist.list_of_type(mnttype, "mnt_hash"):
                yield (mnt, ns)
Example #13
0
    def filter_tasks(self):
        tasks = pslist.linux_pslist(self._config).calculate()
        if self._config.PID is not None:
            try:
                pidlist = [int(p) for p in self._config.PID.split(',')]
            except ValueError:
                debug.error("Invalid PID {0}".format(self._config.PID))

            pids = [t for t in tasks if t.pid in pidlist]
            if len(pids) == 0:
                debug.error(
                    "Cannot find PID {0}. If its terminated or unlinked, use psscan and then supply --offset=OFFSET"
                    .format(self._config.PID))
            return pids

        if self._config.NAME is not None:
            try:
                name_re = re.compile(self._config.NAME, re.I)
            except re.error:
                debug.error("Invalid name {0}".format(self._config.NAME))

            names = [t for t in tasks if name_re.search(str(t.comm))]
            if len(names) == 0:
                debug.error(
                    "Cannot find name {0}. If its terminated or unlinked, use psscan and then supply --offset=OFFSET"
                    .format(self._config.NAME))
            return names

        return tasks
Example #14
0
 def calculate(self):
 
     ## we need this module imported
     if not has_yara:
         debug.error("Please install Yara from code.google.com/p/yara-project")
         
     ## leveraged from the windows yarascan plugin
     rules = self._compile_rules()
         
     ## set the linux plugin address spaces 
     linux_common.set_plugin_members(self)
 
     if self._config.KERNEL:
         ## the start of kernel memory taken from VolatilityLinuxIntelValidAS
         if self.addr_space.profile.metadata.get('memory_model', '32bit') == "32bit":
             kernel_start = 0xc0000000
         else:
             kernel_start = 0xffffffff80000000
         
         scanner = malfind.DiscontigYaraScanner(rules = rules,
                                                address_space = self.addr_space)
                                                
         for hit, address in scanner.scan(start_offset = kernel_start):
             yield (None, address, hit, 
                     scanner.address_space.zread(address, 64))
     else:
         for task in pslist.linux_pslist(self._config).calculate():
             scanner = VmaYaraScanner(task = task, rules = rules)
             for hit, address in scanner.scan():
                 yield (task, address, hit, 
                             scanner.address_space.zread(address, 64))
Example #15
0
    def calculate(self):
        # Should contain the options for one e-mail
        out = []

        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            if not task.mm:
                continue
            # Get the dump for the process
            content = task.get_elf(task.mm.start_code)

            #print all elements that have at least 4 characters
            string_contents = self.binaryToString(content)
            emails = self.emailSearch(string_contents)

            # If dump directory is specified, we should dump all the tasks to the directory
            if self._config.DUMP_DIR:
                linux_common.write_elf_file(self._config.DUMP_DIR, task,
                                            task.mm.start_code)

            #proc_contents = task.get_elf(task.get_process_address_space())
            out.append({"task": task, "emails": emails})

        #Returns a tuple of (task, content)
        return out
Example #16
0
 def check_open_files_fop(self, f_op_members, modules):
     # get all the members in file_operations, they are all function pointers
     tasks = linux_pslist.linux_pslist(self._config).calculate()
     for task in tasks:
         for filp, i in task.lsof():
             for (hooked_member, hook_address) in self.verify_ops(filp.f_op, f_op_members, modules):
                 name = "{0:s} {1:d} {2:s}".format(task.comm, i, linux_common.get_path(task, filp))
                 yield (name, hooked_member, hook_address)
Example #17
0
    def _compare_filps(self):
        dcache = self._gather_dcache()

        tasks = linux_pslist.linux_pslist(self._config).calculate()
        for task in tasks:
            for filp, i in task.lsof():
                val = filp.dentry.v()
                if not val in dcache:
                    yield val

        procs = linux_pslist.linux_pslist(self._config).calculate()
        for proc in procs:
            for vma in proc.get_proc_maps():
                if vma.vm_file:
                    val = vma.vm_file.dentry.v()
                    if not val in dcache:
                        yield val
    def _compare_filps(self):
        dcache = self._gather_dcache()

        tasks = linux_pslist.linux_pslist(self._config).calculate()
        for task in tasks:
            for filp, i in task.lsof():
                val = filp.dentry.v()
                if not val in dcache:
                    yield val

        procs = linux_pslist.linux_pslist(self._config).calculate()
        for proc in procs:
            for vma in proc.get_proc_maps():
                if vma.vm_file:
                    val = vma.vm_file.dentry.v()
                    if not val in dcache:
                        yield val
Example #19
0
 def check_open_files_fop(self, f_op_members, modules):
     # get all the members in file_operations, they are all function pointers
     tasks = linux_pslist.linux_pslist(self._config).calculate()
     for task in tasks:
         for filp, i in task.lsof():
             for (hooked_member, hook_address) in self.verify_ops(filp.f_op, f_op_members, modules):
                 name = "{0:s} {1:d} {2:s}".format(task.comm, i, linux_common.get_path(task, filp))
                 yield (name, hooked_member, hook_address)
Example #20
0
    def calculate(self):
        if (not self._config.OUT_DIR
                or not os.path.isdir(self._config.OUT_DIR)):
            debug.error("Please specify an existing output dir (--out-dir)")

        if (not os.path.isfile("./loader")):
            debug.error(
                "Cannot find 'loader' inside current working directory, compile it or `cd` in the right directory"
            )

        # Extract mappings, kind of ugly but i did not find another way to call the modules..
        for p in linux_pslist.linux_pslist(self._config).calculate():
            pname = str(p.comm)
            if pname == 'X' or pname == 'Xorg':
                break

        tmp_dir = tempfile.mkdtemp()
        self._config.add_option("PID")
        self._config.add_option("DUMP_DIR")
        self._config.PID = str(p.pid)
        self._config.DUMP_DIR = tmp_dir
        out = StringIO.StringIO()
        data = linux_proc_maps.linux_proc_maps(self._config).calculate()
        print("[+] Dumping Xorg memory mappings in %s" % tmp_dir)
        linux_dump_map.linux_dump_map(self._config).render_text(out, data)

        # Extract screenshots
        xw = linux_xwindows.linux_xwindows(self._config)
        for msg, screen_windows, screen_info in xw.calculate():
            for screen_id, win in screen_windows:
                # print('{} on Screen {}\n'.format(str(win), screen_id))
                if win.drawable.type == 0 and win.drawable.width > 150 and win.drawable.height > 150:
                    out = StringIO.StringIO()
                    xw.visit_property(
                        win.optional.dereference().userProps.dereference(),
                        out)

                    loader = [
                        "./loader",
                        str(win.drawable),
                        str(win.drawable.pScreen.visuals),
                        str(win.borderWidth),
                        str(screen_info.imageByteOrder),
                        str(screen_info.bitmapScanlineUnit),
                        str(screen_info.bitmapScanlinePad),
                        str(screen_info.bitmapBitOrder),
                        str(win.drawable.pScreen.GetImage),
                        str(tmp_dir),
                        str(self._config.OUT_DIR)
                    ]
                    print("[+] Calling %s" % ' '.join(loader))
                    subprocess.check_call(loader)
    def filter_tasks(self):
        tasks = linux_pslist(self._config).calculate()
        tasks_filt = []
        for task in tasks:
            for c_plug, c_param1, c_param2 in LINUX_RAKOS_A_FILTER: 
                if c_plug == 'netstat':
                    for ents in task.netstat():
                        if ents[0] == socket.AF_INET:
                            (_, proto, saddr, sport, daddr, dport, state) = ents[1]
                            if (str(saddr) == c_param1) and (str(sport) == c_param2):
                                tasks_filt.append(task)
                                print("Suspected PID: {0:8s} {1:<16}:{2:>5} {3:<16}:{4:>5} {5:<15s} {6:>17s}/{7:<5d}\n".format(proto, saddr, sport, daddr, dport, state, task.comm, task.pid))

        return tasks_filt
Example #22
0
    def filter_tasks(self):
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        if self._config.PID is not None:
            try:
                pidlist = [int(p) for p in self._config.PID.split(',')]
            except ValueError:
                debug.error("Invalid PID {0}".format(self._config.PID))

            pids = [t for t in tasks if t.pid in pidlist]
            if len(pids) == 0:
                debug.error("Cannot find PID {0}. If its terminated or unlinked, use psscan and then supply --offset=OFFSET".format(self._config.PID))
            return pids

        return tasks
Example #23
0
    def set_context(self, offset=None, pid=None, name=None, physical=False):
        if physical and offset != None:
            offset = pslist.linux_pslist(
                self._config).virtual_process_from_physical_offset(
                    offset).obj_offset
        elif pid is not None:
            offsets = []
            for p in self.getpidlist():
                if p.pid.v() == pid:
                    offsets.append(p)
            if not offsets:
                print "Unable to find process matching pid {0}".format(pid)
                return
            elif len(offsets) > 1:
                print "Multiple processes match {0}, please specify by offset".format(
                    pid)
                print "Matching processes:"
                self.ps(offsets)
                return
            else:
                offset = offsets[0].v()
        elif name is not None:
            offsets = []
            for p in self.getpidlist():
                if p.comm.find(name) >= 0:
                    offsets.append(p)
            if not offsets:
                print "Unable to find process matching name {0}".format(name)
                return
            elif len(offsets) > 1:
                print "Multiple processes match name {0}, please specify by PID or offset".format(
                    name)
                print "Matching processes:"
                self.ps(offsets)
                return
            else:
                offset = offsets[0].v()
        elif offset is None:
            print "Must provide one of: offset, name, or pid as a argument."
            return

        self._proc = obj.Object("task_struct",
                                offset=offset,
                                vm=self._addrspace)

        self.context_display()
Example #24
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            proc_as = task.get_process_address_space()

            # In cases when mm is an invalid pointer
            if not proc_as:
                continue

            if not self._config.HISTORY_LIST:
                # Do we scan everything or just /bin/bash instances?
                if not (self._config.SCAN_ALL or str(task.comm) == "bash"):
                    continue

                for hist in task.bash_history_entries():
                    yield task, hist

            else:
                the_history_addr = the_history_addr = self._config.HISTORY_LIST
                the_history = obj.Object(
                    "Pointer", vm=proc_as, offset=the_history_addr
                )
                max_ents = 2001
                the_history = obj.Object(
                    theType='Array',
                    offset=the_history,
                    vm=proc_as,
                    targetType='Pointer',
                    count=max_ents,
                )

                for ptr in the_history:
                    if not ptr:
                        if self._config.PRINTUNALLOC:
                            continue
                        else:
                            break

                    hist = ptr.dereference_as("_hist_entry")

                    if hist.is_valid():
                        yield task, hist
Example #25
0
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            proc_as = task.get_process_address_space()
            
            # In cases when mm is an invalid pointer 
            if not proc_as:
                continue

            # Do we scan everything or just /bin/bash instances?
            if not (self._config.SCAN_ALL or str(task.comm) == "bash"):
                continue

            for ent in task.bash_hash_entries():
                yield task, ent
Example #26
0
    def get_processes(self, addr_space):
        """Enumerate processes based on user options.

        :param      addr_space | <addrspace.AbstractVirtualAddressSpace>

        :returns    <list> 
        """
       
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        try:
            if self._config.PID is not None:
                pidlist = [int(p) for p in self._config.PID.split(',')]
                tasks = [t for t in tasks if int(t.pid) in pidlist]
        except (ValueError, TypeError):
            debug.error("Invalid PID {0}".format(self._config.PID))

        return tasks
Example #27
0
    def get_processes(self, addr_space):
        """Enumerate processes based on user options.

        :param      addr_space | <addrspace.AbstractVirtualAddressSpace>

        :returns    <list> 
        """

        tasks = linux_pslist.linux_pslist(self._config).calculate()

        try:
            if self._config.PID is not None:
                pidlist = [int(p) for p in self._config.PID.split(',')]
                tasks = [t for t in tasks if int(t.pid) in pidlist]
        except (ValueError, TypeError):
            debug.error("Invalid PID {0}".format(self._config.PID))

        return tasks
Example #28
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        tasks = linux_pslist.linux_pslist(self._config).calculate()

        if not self._config.HISTORY_LIST:
            debug.error("History list address not specified.")

        the_history_addr = self._config.HISTORY_LIST

        for task in tasks:
            proc_as = task.get_process_address_space()

            # In cases when mm is an invalid pointer
            if not proc_as:
                continue

            the_history = obj.Object("Pointer",
                                     vm=proc_as,
                                     offset=the_history_addr)

            max_ents = 2001

            the_history = obj.Object(theType='Array',
                                     offset=the_history,
                                     vm=proc_as,
                                     targetType='Pointer',
                                     count=max_ents)

            for ptr in the_history:
                if not ptr:
                    if self._config.PRINTUNALLOC:
                        continue
                    else:
                        break

                hist = obj.Object("_hist_entry", offset=ptr, vm=proc_as)

                cmd = hist.line.dereference()
                cmdtime = hist.timestamp.dereference()

                if cmd and len(cmd) and cmdtime and len(cmdtime):
                    yield (cmd, cmdtime)
Example #29
0
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        # newer kernels
        if self.profile.has_type("mount"):
            mnttype = "mount"
        
            cache = linux_slabinfo(self._config).get_kmem_cache(mnttype, self._config.UNALLOCATED)

            for task in linux_pslist.linux_pslist(self._config).calculate():
                if task.pid == 1:
                    ns = task.nsproxy.mnt_ns
                    break
        else:
            cache = linux_slabinfo(self._config).get_kmem_cache("mnt_cache", self._config.UNALLOCATED, struct_name = "vfsmount")
            ns = None

        for mnt in cache:
            yield (mnt, ns)
Example #30
0
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        # newer kernels
        if self.profile.has_type("mount"):
            mnttype = "mount"
        
            cache = linux_slabinfo(self._config).get_kmem_cache(mnttype, self._config.UNALLOCATED)

            for task in linux_pslist.linux_pslist(self._config).calculate():
                if task.pid == 1:
                    ns = task.nsproxy.mnt_ns
                    break
        else:
            cache = linux_slabinfo(self._config).get_kmem_cache("mnt_cache", self._config.UNALLOCATED, struct_name = "vfsmount")
            ns = None

        for mnt in cache:
            yield (mnt, ns)
Example #31
0
    def calculate(self):
        common.set_plugin_members(self)

        if self.profile.metadata["arch"] not in ["x64", "x86"]:
            debug.error("This plugin is only supported on Intel-based memory captures")

        self.bits = self.profile.metadata.get("memory_model", "32bit")
        self.reg_size = reg_size[self.bits]
        self.offsets = offsets[self.bits]
        self.fmt = fmt[self.bits]

        for proc in linux_pslist.linux_pslist(self._config).calculate():
            name = proc.get_commandline()
            thread_registers = []
            for thread_task in proc.threads():
                thread_name = thread_task.comm
                regs = self.parse_kernel_stack(thread_task)
                thread_registers.append((thread_name, regs))
            yield proc, name, thread_registers
Example #32
0
    def calculate(self):
        common.set_plugin_members(self)

        if self.profile.metadata['arch'] not in ["x64", "x86"]:
            debug.error(
                "This plugin is only supported on Intel-based memory captures")

        self.bits = self.profile.metadata.get('memory_model', '32bit')
        self.reg_size = reg_size[self.bits]
        self.offsets = offsets[self.bits]
        self.fmt = fmt[self.bits]

        for proc in linux_pslist.linux_pslist(self._config).calculate():
            name = proc.get_commandline()
            thread_registers = []
            for thread_task in proc.threads():
                thread_name = thread_task.comm
                regs = self.parse_kernel_stack(thread_task)
                thread_registers.append((thread_name, regs))
            yield proc, name, thread_registers
Example #33
0
    def set_context(self, offset = None, pid = None, name = None, physical = False):
        if physical and offset != None:
            offset = pslist.linux_pslist(self._config).virtual_process_from_physical_offset(offset).obj_offset  
        elif pid is not None:
            offsets = []
            for p in self.getpidlist():
                if p.pid.v() == pid:
                    offsets.append(p)
            if not offsets:
                print "Unable to find process matching pid {0}".format(pid)
                return
            elif len(offsets) > 1:
                print "Multiple processes match {0}, please specify by offset".format(pid)
                print "Matching processes:"
                self.ps(offsets)
                return
            else:
                offset = offsets[0].v()
        elif name is not None:
            offsets = []
            for p in self.getpidlist():
                if p.comm.find(name) >= 0:
                    offsets.append(p)
            if not offsets:
                print "Unable to find process matching name {0}".format(name)
                return
            elif len(offsets) > 1:
                print "Multiple processes match name {0}, please specify by PID or offset".format(name)
                print "Matching processes:"
                self.ps(offsets)
                return
            else:
                offset = offsets[0].v()
        elif offset is None:
            print "Must provide one of: offset, name, or pid as a argument."
            return

        self._proc = obj.Object("task_struct", offset = offset, vm = self._addrspace)

        self.context_display()
     def calculate(self):

          # if no gDvm object offset was specified, use this one
          if not self._config.GDVM_OFFSET:
               self._config.GDVM_OFFSET = str(0x41b0)

          # use linux_pslist plugin to find process address space and ID if not specified
          proc_as = None     
          tasks = linux_pslist.linux_pslist(self._config).calculate()
          for task in tasks:
               if str(task.comm) == "keystore":                    
                    proc_as = task.get_process_address_space()
                    self._config.PID = str(task.pid)
                    break

          # find stack
          for task, vma in dalvik.get_data_section_stack(self._config):
               # read length and password, they seem to have constant offset
               length = obj.Object('int', offset = vma.vm_start + 0x1982c, vm = proc_as)
               password = obj.Object('String', offset = vma.vm_start + 0x19830,
                              vm = proc_as, length = length)
               yield password
Example #35
0
     def calculate(self):

          # if no gDvm object offset was specified, use this one
          if not self._config.GDVM_OFFSET:
               self._config.GDVM_OFFSET = str(0x41b0)

          # use linux_pslist plugin to find process address space and ID if not specified
          proc_as = None     
          tasks = linux_pslist.linux_pslist(self._config).calculate()
          for task in tasks:
               if str(task.comm) == "putmethod.latin":                    
                    proc_as = task.get_process_address_space()
                    self._config.PID = str(task.pid)
                    break

          # use dalvik_loaded_classes plugin to find class offset if not specified
          if not self._config.CLASS_OFFSET:
              classes = dalvik_loaded_classes.dalvik_loaded_classes(self._config).calculate()
              for task, clazz in classes:
                   if (dalvik.getString(clazz.sourceFile)+"" == "RichInputConnection.java"):
                        self._config.CLASS_OFFSET = str(hex(clazz.obj_offset))
                        break

          # use dalvik_find_class_instance plugin to find a list of possible class instances
          instance = dalvik_find_class_instance.dalvik_find_class_instance(self._config).calculate()
          for sysClass, inst in instance:
               # get stringBuilder object
               stringBuilder = inst.clazz.getJValuebyName(inst, "mCommittedTextBeforeComposingText").Object.dereference_as('Object')
               # get superclass object
               abstractStringBuilder = stringBuilder.clazz.super.dereference_as('ClassObject')
               
               # array object of super class
               charArray = abstractStringBuilder.getJValuebyName(stringBuilder, "value").Object.dereference_as('ArrayObject')
               # get length of array object
               count = charArray.length
               # create string object with content of the array object
               text = obj.Object('String', offset = charArray.contents0.obj_offset,
               vm = abstractStringBuilder.obj_vm, length = count*2, encoding = "utf16")
               yield inst, text
Example #36
0
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            proc_as = task.get_process_address_space()
            
            # In cases when mm is an invalid pointer 
            if not proc_as:
                continue

            if not self._config.HISTORY_LIST:
                # Do we scan everything or just /bin/bash instances?
                if not (self._config.SCAN_ALL or str(task.comm) == "bash"):
                    continue

                for hist in task.bash_history_entries():
                    yield task, hist     

            else:    
                the_history_addr = the_history_addr = self._config.HISTORY_LIST
                the_history = obj.Object("Pointer", vm = proc_as, offset = the_history_addr)
                max_ents = 2001
                the_history = obj.Object(theType = 'Array', offset = the_history, 
                                         vm = proc_as, targetType = 'Pointer', 
                                         count = max_ents)

                for ptr in the_history:
                    if not ptr:
                        if self._config.PRINTUNALLOC:
                            continue
                        else:
                            break

                    hist = ptr.dereference_as("_hist_entry")      

                    if hist.is_valid():
                        yield task, hist
Example #37
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        mntptr = obj.Object("Pointer", offset = self.addr_space.profile.get_symbol("mount_hashtable"), vm = self.addr_space)

        mnt_list = obj.Object(theType = "Array", offset = mntptr.v(), vm = self.addr_space, targetType = "list_head", count = 512)

        if self.profile.has_type("mount"):
            mnttype = "mount"

            for task in linux_pslist.linux_pslist(self._config).calculate():
                if task.pid == 1:
                    ns = task.nsproxy.mnt_ns
                    break

        else:
            mnttype = "vfsmount"
            ns = None

        # get each list_head out of the array
        for outerlist in mnt_list:

            for mnt in outerlist.list_of_type(mnttype, "mnt_hash"):
                yield (mnt, ns)
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        if not self._config.HISTORY_LIST:
            debug.error("History list address not specified.")
        
        the_history_addr = self._config.HISTORY_LIST

        for task in tasks:
            proc_as = task.get_process_address_space()
            
            # In cases when mm is an invalid pointer 
            if not proc_as:
                continue

            the_history = obj.Object("Pointer", vm = proc_as, offset = the_history_addr)

            max_ents = 2001

            the_history = obj.Object(theType = 'Array', offset = the_history, vm = proc_as, targetType = 'Pointer', count = max_ents)

            for ptr in the_history:
                if not ptr:
                    if self._config.PRINTUNALLOC:
                        continue
                    else:
                        break

                hist = obj.Object("_hist_entry", offset = ptr, vm = proc_as)       
    
                cmd = hist.line.dereference()
                cmdtime = hist.timestamp.dereference()

                if cmd and len(cmd) and cmdtime and len(cmdtime):
                    yield (cmd, cmdtime)
Example #39
0
    def calculate(self):
        # if no gDvm object offset was specified, use this one
        if not self._config.GDVM_OFFSET:
            self._config.GDVM_OFFSET = str(hex(0x41b0))

        # use linux_pslist plugin to find process address space and ID if not specified
        proc_as = None
        tasks = linux_pslist.linux_pslist(self._config).calculate()
        for task in tasks:
            if str(task.comm) == "ndroid.contacts":
                proc_as = task.get_process_address_space()
                if not self._config.PID:
                    self._config.PID = str(task.pid)
                break

        # use dalvik_loaded_classes plugin to find class offset if not specified
        if not self._config.CLASS_OFFSET:
            classes = dalvik_loaded_classes.dalvik_loaded_classes(
                self._config).calculate()
            for task, clazz in classes:
                if (dalvik.getString(clazz.sourceFile) +
                        "" == "PhoneCallDetails.java"):
                    self._config.CLASS_OFFSET = str(hex(clazz.obj_offset))
                    break

        # use dalvik_find_class_instance plugin to find a list of possible class instances
        instances = dalvik_find_class_instance.dalvik_find_class_instance(
            self._config).calculate()
        for sysClass, inst in instances:
            callDetailsObj = obj.Object('PhoneCallDetails',
                                        offset=inst,
                                        vm=proc_as)
            # access type ID field for sanity check
            typeID = int(callDetailsObj.callTypes.contents0)
            # valid type ID must be 1,2 or 3
            if (typeID == 1 or typeID == 2 or typeID == 3):
                yield callDetailsObj
Example #40
0
 def get_pid_from_name(self, name):
     for proc in linux_pslist.linux_pslist(self._config).calculate():
         if proc.comm == name:
             return proc.pid
     else:
         raise (Exception("Bad Process name: {}".format(name)))
Example #41
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            if self.init_for_task(task):

                if self.profile.metadata.get('memory_model') == '64bit':
                    self.profile.vtypes.update(ZshProfile64().zshprofile)

                else:
                    # default/fallback profile
                    self.profile.vtypes.update(ZshProfile32().zshprofile)

                self.profile.compile()

                chunks_dict = dict()
                chunk_data_pointers = list()
                chunk_size = self.get_aligned_size(
                    self.profile.get_obj_size('histent'))
                data_offset = self.profile.get_obj_offset("malloc_chunk", "fd")

                for chunk in self.get_all_allocated_chunks():
                    chunks_dict[chunk.v() + data_offset] = chunk
                    chunk_data_pointers.append(chunk.v() + data_offset)

                commands_dict = dict()

                valid_histentry = None

                # we first try to find a chunk that most probably contains a
                # histent struct
                for chunk in self.get_all_allocated_chunks():

                    if not chunk.chunksize() == chunk_size:
                        continue

                    histent = obj.Object('histent',
                                         offset=chunk.v() + data_offset,
                                         vm=self.process_as)

                    # we test if the current histent struct seems to be valid
                    # first test: do we know the chunks where relevant
                    # pointers point to
                    pointers = [
                        histent.node.nam.v(),
                        histent.down.v(),
                        histent.up.v()
                    ]
                    if not len(set(pointers) & set(chunk_data_pointers)) \
                            == len(pointers):
                        continue

                    # second test: points the previous/next histent entry to
                    # this histent entry?
                    if not histent.up.down == histent or not histent.down.up \
                            == histent:
                        continue

                    # we hopefully found one
                    valid_histentry = histent
                    break

                if valid_histentry:
                    debug.debug(
                        "We probably found a valid histent chunk and now "
                        "start walking.")

                    # entries are linked circular so walking in one direction
                    # should be sufficient
                    for histent in heap_analysis.iterate_through_linked_list(
                            valid_histentry, lambda x: x.down):

                        command = ''

                        try:
                            command = chunks_dict[histent.node.nam.v()]
                            command = command.to_string()
                            command = command[:command.index("\x00")]

                        except KeyError:
                            debug.warning(
                                "Unexpected error: chunk for given "
                                "command-reference does not seem to exist.")

                        except ValueError:
                            pass

                        if histent.stim == histent.ftim == 0 and command == '':
                            histent_vma = heap_analysis.get_vma_for_offset(
                                self.vmas, histent.v())

                            if histent_vma not in self.heap_vmas:
                                # we most probably found the "curline" histent
                                # struct located in zsh's .bss section. as it
                                # doesn't contain an actual executed command,
                                # we are skipping it
                                continue

                        command_number = histent.histnum
                        start = obj.Object('UnixTimeStamp',
                                           offset=histent.stim.obj_offset,
                                           vm=self.process_as)
                        end = obj.Object('UnixTimeStamp',
                                         offset=histent.stim.obj_offset,
                                         vm=self.process_as)

                        commands_dict[command_number] = [
                            start, end, repr(command)
                        ]

                for key, value in sorted(commands_dict.items()):
                    yield (task.pid, key, value[0], value[1], value[2])
Example #42
0
 def getpidlist(self):
     return pslist.linux_pslist(self._config).allprocs()
     def calculate(self):

          # if no gDvm object offset was specified, use this one
          if not self._config.GDVM_OFFSET:
               self._config.GDVM_OFFSET = str(0x41b0)

          # use linux_pslist plugin to find process address space and ID if not specified
          proc_as = None     
          tasks = linux_pslist.linux_pslist(self._config).calculate()
          for task in tasks:
               if str(task.comm) == "droid.gallery3d":                    
                    proc_as = task.get_process_address_space()
                    self._config.PID = str(task.pid)
                    break

          # use dalvik_loaded_classes plugin to find class offset if not specified
          if not self._config.CLASS_OFFSET:
              classes = dalvik_loaded_classes.dalvik_loaded_classes(self._config).calculate()
              for task, clazz in classes:
                   if (dalvik.getString(clazz.sourceFile)+"" == "LocalAlbum.java"):
                        self._config.CLASS_OFFSET = str(hex(clazz.obj_offset))
                        break

          # use dalvik_find_class_instance plugin to find a list of possible class instances
          instance = dalvik_find_class_instance.dalvik_find_class_instance(self._config).calculate()
          for sysClass, inst in instance:
               # boolean value, 1 for images, 0 for videos
               isImage = inst.clazz.getJValuebyName(inst, "mIsImage").int
               # sanity check
               if isImage != True:
                    continue
               # number of pictures, initilized with -1
               count = inst.clazz.getJValuebyName(inst, "mCachedCount").int
               # sanity check
               if count == -1:
                    continue
               # get album name
               album_name = inst.clazz.getJValuebyName(inst, "mName").Object.dereference_as('Object')
               
               # get pictures of album
               album_path = inst.clazz.getJValuebyName(inst, "mItemPath").Object.dereference_as('Object')
               iCache = album_path.clazz.getJValuebyName(album_path, "mChildren").Object.dereference_as('Object')
               hashmap = iCache.clazz.getJValuebyName(iCache, "mWeakMap").Object.dereference_as('Object')
               # in this table there is a reference to every single picture
               map_table = hashmap.clazz.getJValuebyName(hashmap, "table").Object.dereference_as('ArrayObject')
               # parse the table
               map_entries = dalvik.parseArrayObject(map_table)

               # for every reference of the table
               for field in map_entries:
                    entry = field.clazz.getJValuebyName(field, "value").Object.dereference_as('Object')
                    weak_reference_clazz = entry.clazz.super.dereference_as('ClassObject')
                    reference_clazz = weak_reference_clazz.super.dereference_as('ClassObject')
                    image_path = reference_clazz.getJValuebyName(entry, "referent").Object.dereference_as('Object')
                    image_weak_reference = image_path.clazz.getJValuebyName(image_path, "mObject").Object.dereference_as('Object')

                    # finally this is the instance of one picture class
                    local_image = reference_clazz.getJValuebyName(image_weak_reference, "referent").Object.dereference_as('Object')
                    # the interesting information is found in the superclass
                    local_media_item = local_image.clazz.super.dereference_as('ClassObject')

                    # get picture information
                    image_name = local_media_item.getJValuebyName(local_image, "caption").Object.dereference_as('Object')                    
                    image_size = local_media_item.getJValuebyName(local_image, "fileSize").int
                    image_lat = local_media_item.getJValuebyName(local_image, "latitude").longlong
                    image_long = local_media_item.getJValuebyName(local_image, "longitude").longlong
                    image_date_taken = local_media_item.getJValuebyName(local_image, "dateTakenInMs").ulonglong
                    image_filepath = local_media_item.getJValuebyName(local_image, "filePath").Object.dereference_as('Object')
                    image_width = local_media_item.getJValuebyName(local_image, "width").int
                    image_heigth = local_media_item.getJValuebyName(local_image, "height").int
                    
                    yield inst, image_name, album_name, image_size, image_lat, image_long, image_date_taken, image_width, image_heigth
Example #44
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            if self.init_for_task(task):

                if self.profile.metadata.get('memory_model') == '64bit':
                    self.profile.vtypes.update(ZshProfile64().zshprofile)

                else:
                    # default/fallback profile
                    self.profile.vtypes.update(ZshProfile32().zshprofile)

                self.profile.compile()

                chunks_dict = dict()
                chunk_data_pointers = list()
                chunk_size = self.get_aligned_size(
                    self.profile.get_obj_size('histent'))
                data_offset = self.profile.get_obj_offset("malloc_chunk", "fd")

                for chunk in self.get_all_allocated_chunks():
                    chunks_dict[chunk.v() + data_offset] = chunk
                    chunk_data_pointers.append(chunk.v() + data_offset)

                commands_dict = dict()

                valid_histentry = None

                # we first try to find a chunk that most probably contains a
                # histent struct
                for chunk in self.get_all_allocated_chunks():

                    if not chunk.chunksize() == chunk_size:
                        continue

                    histent = obj.Object('histent',
                                         offset=chunk.v()+data_offset,
                                         vm=self.process_as)

                    # we test if the current histent struct seems to be valid
                    # first test: do we know the chunks where relevant
                    # pointers point to
                    pointers = [histent.node.nam.v(),
                                histent.down.v(),
                                histent.up.v()]
                    if not len(set(pointers) & set(chunk_data_pointers)) \
                            == len(pointers):
                        continue

                    # second test: points the previous/next histent entry to
                    # this histent entry?
                    if not histent.up.down == histent or not histent.down.up \
                            == histent:
                        continue

                    # we hopefully found one
                    valid_histentry = histent
                    break

                if valid_histentry:
                    debug.debug(
                        "We probably found a valid histent chunk and now "
                        "start walking.")

                    # entries are linked circular so walking in one direction
                    # should be sufficient
                    for histent in heap_analysis.iterate_through_linked_list(
                            valid_histentry, lambda x: x.down):

                        command = ''

                        try:
                            command = chunks_dict[histent.node.nam.v()]
                            command = command.to_string()
                            command = command[:command.index("\x00")]

                        except KeyError:
                            debug.warning(
                                "Unexpected error: chunk for given "
                                "command-reference does not seem to exist.")

                        except ValueError:
                            pass

                        if histent.stim == histent.ftim == 0 and command == '':
                            histent_vma = heap_analysis.get_vma_for_offset(
                                self.vmas, histent.v())

                            if histent_vma not in self.heap_vmas:
                                # we most probably found the "curline" histent
                                # struct located in zsh's .bss section. as it
                                # doesn't contain an actual executed command,
                                # we are skipping it
                                continue

                        command_number = histent.histnum
                        start = obj.Object('UnixTimeStamp',
                                           offset=histent.stim.obj_offset,
                                           vm=self.process_as)
                        end = obj.Object('UnixTimeStamp',
                                         offset=histent.stim.obj_offset,
                                         vm=self.process_as)

                        commands_dict[command_number] = [start,
                                                         end,
                                                         repr(command)]


                for key, value in sorted(commands_dict.items()):
                    yield (task.pid, key, value[0], value[1], value[2])
Example #45
0
 def _get_task_parents(self):
     return [x.real_parent.v() for x in linux_pslist.linux_pslist(self._config).calculate()]
Example #46
0
 def _get_pslist(self):
     return [
         x.obj_offset
         for x in linux_pslist.linux_pslist(self._config).calculate()
     ]
Example #47
0
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        tasks = linux_pslist.linux_pslist(self._config).calculate()
        
        # Are we dealing with 32 or 64-bit pointers
        if self.addr_space.profile.metadata.get('memory_model', '32bit') == '32bit':
            pack_format = "<I"
            addr_sz = 4
        else:
            pack_format = "<Q"
            addr_sz = 8
            
        for task in tasks:
            proc_as = task.get_process_address_space()
            
            # In cases when mm is an invalid pointer 
            if not proc_as:
                continue

            procvars = []
            for vma in task.get_proc_maps():
                if not (vma.vm_file and str(vma.vm_flags) == "rw-" and linux_common.get_path(task, vma.vm_file).find("bash") != -1):
                    continue

                env_start = 0
                for off in range(vma.vm_start, vma.vm_end):
                    # check the first index
                    addrstr = proc_as.read(off, addr_sz)
                    if not addrstr or len(addrstr) != addr_sz:
                        continue
                    addr = struct.unpack(pack_format, addrstr)[0]
                    # check first idx...
                    if addr:
                        firstaddrstr = proc_as.read(addr, addr_sz)
                        if not firstaddrstr or len(firstaddrstr) != addr_sz:
                            continue
                        firstaddr = struct.unpack(pack_format, firstaddrstr)[0]
                        buf = proc_as.read(firstaddr, 64)
                        if not buf:
                            continue
                        eqidx = buf.find("=")
                        if eqidx > 0:
                            nullidx = buf.find("\x00")
                            # single char name, =
                            if nullidx >= eqidx:
                                env_start = addr

                if env_start == 0:
                    continue

                envars = obj.Object(theType="Array", targetType="Pointer", vm=proc_as, offset=env_start, count=256)
                for var in envars:
                    if var:
                        varstr = proc_as.read(var, 1600)
                        eqidx = varstr.find("=")
                        idx = varstr.find("\x00")

                        if idx == -1 or eqidx == -1 or idx < eqidx:
                            break

                        varstr = varstr[:idx]

                        procvars.append(varstr) 

                yield task, " ".join(procvars)

                break
Example #48
0
    def calculate(self):
        linux_common.set_plugin_members(self)
    
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            proc_as = task.get_process_address_space()
            
            # In cases when mm is an invalid pointer 
            if not proc_as:
                continue

            if not self._config.HISTORY_LIST:
                # Do we scan everything or just /bin/bash instances?
                if not (self._config.SCAN_ALL or str(task.comm) == "bash"):
                    continue

                # Keep a bucket of history objects so we can order them
                history_entries = []

                # Brute force the history list of an address isn't provided 
                ts_offset = proc_as.profile.get_obj_offset("_hist_entry", "timestamp") 

                # Are we dealing with 32 or 64-bit pointers
                if proc_as.profile.metadata.get('memory_model', '32bit') == '32bit':
                    pack_format = "I"
                else:
                    pack_format = "Q"

                # Look for strings that begin with pound/hash on the process heap 
                for ptr_hash in task.search_process_memory(["#"], heap_only = True):
                    
                    # Find pointers to this strings address, also on the heap 
                    addr = struct.pack(pack_format, ptr_hash)

                    for ptr_string in task.search_process_memory([addr], heap_only = True):
                        
                        # Check if we found a valid history entry object 
                        hist = obj.Object("_hist_entry", 
                                          offset = ptr_string - ts_offset, 
                                          vm = proc_as)

                        if hist.is_valid():
                            history_entries.append(hist)
                            # We can terminate this inner loop now 
                            break
                
                # Report everything we found in order
                for hist in sorted(history_entries, key = attrgetter('time_as_integer')):
                    yield task, hist              
            else:    
                the_history_addr = the_history_addr = self._config.HISTORY_LIST
                the_history = obj.Object("Pointer", vm = proc_as, offset = the_history_addr)
                max_ents = 2001
                the_history = obj.Object(theType = 'Array', offset = the_history, 
                                         vm = proc_as, targetType = 'Pointer', 
                                         count = max_ents)

                for ptr in the_history:
                    if not ptr:
                        if self._config.PRINTUNALLOC:
                            continue
                        else:
                            break

                    hist = ptr.dereference_as("_hist_entry")      
    
                    if hist.is_valid():
                        yield task, hist
Example #49
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            proc_as = task.get_process_address_space()

            # In cases when mm is an invalid pointer
            if not proc_as:
                continue

            if not self._config.HISTORY_LIST:
                # Do we scan everything or just /bin/bash instances?
                if not (self._config.SCAN_ALL or str(task.comm) == "bash"):
                    continue

                # Keep a bucket of history objects so we can order them
                history_entries = []

                # Brute force the history list of an address isn't provided
                ts_offset = proc_as.profile.get_obj_offset(
                    "_hist_entry", "timestamp")

                # Are we dealing with 32 or 64-bit pointers
                if proc_as.profile.metadata.get('memory_model',
                                                '32bit') == '32bit':
                    pack_format = "I"
                else:
                    pack_format = "Q"

                # Look for strings that begin with pound/hash on the process heap
                for ptr_hash in task.search_process_memory(["#"],
                                                           heap_only=True):

                    # Find pointers to this strings address, also on the heap
                    addr = struct.pack(pack_format, ptr_hash)

                    for ptr_string in task.search_process_memory(
                        [addr], heap_only=True):

                        # Check if we found a valid history entry object
                        hist = obj.Object("_hist_entry",
                                          offset=ptr_string - ts_offset,
                                          vm=proc_as)

                        if hist.is_valid():
                            history_entries.append(hist)
                            # We can terminate this inner loop now
                            break

                # Report everything we found in order
                for hist in sorted(history_entries,
                                   key=attrgetter('time_as_integer')):
                    yield task, hist
            else:
                the_history_addr = the_history_addr = self._config.HISTORY_LIST
                the_history = obj.Object("Pointer",
                                         vm=proc_as,
                                         offset=the_history_addr)
                max_ents = 2001
                the_history = obj.Object(theType='Array',
                                         offset=the_history,
                                         vm=proc_as,
                                         targetType='Pointer',
                                         count=max_ents)

                for ptr in the_history:
                    if not ptr:
                        if self._config.PRINTUNALLOC:
                            continue
                        else:
                            break

                    hist = ptr.dereference_as("_hist_entry")

                    if hist.is_valid():
                        yield task, hist
Example #50
0
 def _get_task_parents(self):
     return [
         x.real_parent.v()
         for x in linux_pslist.linux_pslist(self._config).calculate()
     ]
Example #51
0
 def _get_pslist(self):
     return [self.addr_space.vtop(x.obj_offset) for x in linux_pslist.linux_pslist(self._config).calculate()]
Example #52
0
 def getpidlist(self):
     return pslist.linux_pslist(self._config).calculate()
Example #53
0
 def getpidlist(self):
     return pslist.linux_pslist(self._config).calculate()
Example #54
0
 def _get_pslist(self):
     return [x.obj_offset for x in linux_pslist.linux_pslist(self._config).calculate()]
Example #55
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        tasks = linux_pslist.linux_pslist(self._config).calculate()

        for task in tasks:
            if self.init_for_task(task):

                chunks_dict = dict()

                data_offset = self.profile.get_obj_offset("malloc_chunk", "fd")

                for chunk in self.get_all_allocated_chunks():
                    chunks_dict[chunk.v() + data_offset] = chunk

                if self.profile.metadata.get('memory_model') == '64bit':
                    string_offset = 26
                    relevant_chunk_size = 192
                    pointer_offsets = [16, 24, 32, 64]

                else:
                    string_offset = 18
                    relevant_chunk_size = 96
                    pointer_offsets = [12, 16, 20, 36]

                entry_number = 1

                for chunk in chunks_dict.values():

                    try:
                        # chunks containing refs to password entries typically
                        # have a size of 96 in the tested 32 bit environment
                        if not chunk.chunksize() == relevant_chunk_size:
                            continue

                        p_entry_data = chunk.to_string()

                        field_strings = []

                        # the pointers to title, username and so on are at
                        # these offsets
                        for i in pointer_offsets:
                            if self.profile.metadata.get('memory_model') == '32bit':
                                pointer = struct.unpack('I',
                                                        p_entry_data[i:i+4])[0]
                            else:
                                pointer = struct.unpack('Q',
                                                        p_entry_data[i:i+8])[0]

                            # if there is no chunk for the given pointer, we
                            # most probably have a wrong chunk. this will
                            # throw a KeyError exception and we proceed with
                            # the next chunk
                            curr_chunk_data = chunks_dict[pointer].to_string()

                            string_size = struct.unpack(
                                'I', curr_chunk_data[8:12])[0]

                            string_size *= 2

                            curr_string = curr_chunk_data[
                                string_offset:string_offset+string_size]

                            curr_string = curr_string.decode('utf-16-le')

                            field_strings.append(repr(curr_string))


                        yield (task.pid,
                               entry_number,
                               field_strings[0],
                               field_strings[1],
                               field_strings[2],
                               field_strings[3])

                        entry_number += 1

                    except (KeyError, UnicodeDecodeError):
                        # a password entry struct not containing a pointer to
                        # a chunk => out of scope
                        pass