Exemplo n.º 1
0
 def testLegacyDataMigration(self):
     res = rdf_memory.YaraProcessDumpResponse(dumped_processes=[
         rdf_memory.YaraProcessDumpInformation(dump_files=[
             rdf_paths.PathSpec(path="C:\\Foo\\Bar\\%s_%d_%x_%x.tmp" %
                                ("my_proc", 123, 111, 222),
                                pathtype="TMPFILE"),
             rdf_paths.PathSpec(path="/foo/bar/%s_%d_%x_%x.tmp" %
                                ("my_proc", 123, 456, 789),
                                pathtype="TMPFILE")
         ])
     ])
     memory._MigrateLegacyDumpFilesToMemoryAreas(res)
     self.assertEqual(
         res,
         rdf_memory.YaraProcessDumpResponse(dumped_processes=[
             rdf_memory.YaraProcessDumpInformation(memory_regions=[
                 rdf_memory.ProcessMemoryRegion(
                     start=111,
                     size=111,
                     file=rdf_paths.PathSpec(
                         path="/C:/Foo/Bar/%s_%d_%x_%x.tmp" %
                         ("my_proc", 123, 111, 222),
                         pathtype="TMPFILE")),
                 rdf_memory.ProcessMemoryRegion(
                     start=456,
                     size=333,
                     file=rdf_paths.PathSpec(
                         path="/foo/bar/%s_%d_%x_%x.tmp" %
                         ("my_proc", 123, 456, 789),
                         pathtype="TMPFILE"))
             ])
         ]))
Exemplo n.º 2
0
    def testPathSpecCasingIsCorrected(self):
        flow = memory.DumpProcessMemory(rdf_flow_objects.Flow())
        flow.SendReply = mock.Mock(spec=flow.SendReply)

        request = rdf_flow_objects.FlowRequest(
            request_data={
                "YaraProcessDumpResponse":
                rdf_memory.YaraProcessDumpResponse(dumped_processes=[
                    rdf_memory.YaraProcessDumpInformation(memory_regions=[
                        rdf_memory.ProcessMemoryRegion(
                            start=1,
                            size=1,
                            file=rdf_paths.PathSpec.Temp(
                                path="/C:/grr/x_1_0_1.tmp")),
                        rdf_memory.ProcessMemoryRegion(
                            start=1,
                            size=1,
                            file=rdf_paths.PathSpec.Temp(
                                path="/C:/GRR/x_1_1_2.tmp"))
                    ])
                ])
            })
        pathspecs = [
            rdf_paths.PathSpec.Temp(path="/C:/Grr/x_1_0_1.tmp"),
            rdf_paths.PathSpec.Temp(path="/C:/Grr/x_1_1_2.tmp")
        ]
        responses = flow_responses.Responses.FromResponses(
            request, [
                rdf_flow_objects.FlowResponse(payload=rdf_client_fs.StatEntry(
                    pathspec=pathspec)) for pathspec in pathspecs
            ])

        flow.ProcessMemoryRegions(responses)
        flow.SendReply.assert_any_call(
            rdf_memory.YaraProcessDumpResponse(dumped_processes=[
                rdf_memory.YaraProcessDumpInformation(memory_regions=[
                    rdf_memory.ProcessMemoryRegion(
                        start=1,
                        size=1,
                        file=rdf_paths.PathSpec.Temp(
                            path="/C:/Grr/x_1_0_1.tmp")),
                    rdf_memory.ProcessMemoryRegion(
                        start=1,
                        size=1,
                        file=rdf_paths.PathSpec.Temp(
                            path="/C:/Grr/x_1_1_2.tmp"))
                ])
            ]))
Exemplo n.º 3
0
    def Regions(self,
                skip_mapped_files=False,
                skip_shared_regions=False,
                skip_executable_regions=False,
                skip_readonly_regions=False):
        del skip_mapped_files
        del skip_shared_regions
        del skip_executable_regions
        del skip_readonly_regions

        for region in self.regions:
            yield rdf_memory.ProcessMemoryRegion(
                start=region.start,
                size=region.size,
                is_executable=region.is_executable,
                is_writable=region.is_writable,
                is_readable=region.is_readable)
Exemplo n.º 4
0
def _MigrateLegacyDumpFilesToMemoryAreas(response):
    """Migrates a YPDR from dump_files to memory_regions inplace."""
    for info in response.dumped_processes:
        for dump_file in info.dump_files:
            # filename = "%s_%d_%x_%x.tmp" % (process.name, pid, start, end)
            # process.name can contain underscores. Split exactly 3 _ from the right.
            path_without_ext, _ = dump_file.Basename().rsplit(".", 1)
            _, _, start, end = path_without_ext.rsplit("_", 3)
            start = int(start, 16)
            end = int(end, 16)

            info.memory_regions.Append(
                rdf_memory.ProcessMemoryRegion(
                    file=_CanonicalizeLegacyWindowsPathSpec(dump_file),
                    start=start,
                    size=end - start,
                ))
        # Remove dump_files, since new clients do not set it anymore.
        info.dump_files = None
Exemplo n.º 5
0
    def Regions(self,
                skip_mapped_files=False,
                skip_shared_regions=False,
                skip_executable_regions=False,
                skip_readonly_regions=False):
        """Returns an iterator over the readable regions for this process."""
        try:
            maps_file = open("/proc/" + str(self.pid) + "/maps", "r")
        except OSError as e:
            raise process_error.ProcessError(e)

        with maps_file:
            for line in maps_file:
                m = self.maps_re.match(line)
                if not m:
                    continue
                start = int(m.group(1), 16)
                end = int(m.group(2), 16)
                region_protec = m.group(3)
                inode = int(m.group(6))

                is_writable = "w" in region_protec
                is_executable = "x" in region_protec

                if "r" in region_protec:
                    if skip_mapped_files and inode != 0:
                        continue
                    if skip_shared_regions and "s" in region_protec:
                        continue
                    if skip_executable_regions and is_executable:
                        continue
                    if skip_readonly_regions and not is_writable:
                        continue

                    yield rdf_memory.ProcessMemoryRegion(
                        start=start,
                        size=end - start,
                        is_readable=True,
                        is_writable=is_writable,
                        is_executable=is_executable)
Exemplo n.º 6
0
  def Regions(self,
              skip_special_regions=False,
              skip_executable_regions=False,
              skip_readonly_regions=False):
    """Returns an iterator over the readable regions for this process."""
    offset = self.min_addr

    while True:
      if offset >= self.max_addr:
        break
      mbi = self.VirtualQueryEx(offset)
      offset = mbi.BaseAddress
      chunk = mbi.RegionSize
      protect = mbi.Protect
      state = mbi.State

      region = rdf_memory.ProcessMemoryRegion(
          start=offset,
          size=mbi.RegionSize,
          is_readable=True,
          is_writable=bool(protect
                           & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE
                              | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY)),
          is_executable=bool(protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ
                                        | PAGE_EXECUTE_READWRITE
                                        | PAGE_EXECUTE_WRITECOPY)))
      is_special = (
          protect & PAGE_NOCACHE or protect & PAGE_WRITECOMBINE or
          protect & PAGE_GUARD)

      offset += chunk

      if (state & MEM_FREE or state & MEM_RESERVE or
          (skip_special_regions and is_special) or
          (skip_executable_regions and region.is_executable) or
          (skip_readonly_regions and not region.is_writable)):
        continue

      yield region
Exemplo n.º 7
0
def R(start, size):
  """Returns a new ProcessMemoryRegion with the given start and size."""
  return rdf_memory.ProcessMemoryRegion(start=start, size=size)
Exemplo n.º 8
0
    def Regions(self,
                skip_executable_regions=False,
                skip_shared_regions=False,
                skip_readonly_regions=False):
        """Iterates over the readable regions for this process.

    We use mach_vm_region_recurse here to get a fine grained view of
    the process' memory space. The algorithm is that for some regions,
    the function returns is_submap=True which means that there are
    actually subregions that we need to examine by increasing the
    depth and calling the function again. For example, there are two
    regions, addresses 1000-2000 and 2000-3000 where 1000-2000 has two
    subregions, 1100-1200 and 1300-1400. In that case we would call:

    mvrr(address=0, depth=0)       -> (1000-2000, is_submap=True)
    mvrr(address=0, depth=1)       -> (1100-1200, is_submap=False)
    mvrr(address=1200, depth=1)    -> (1300-1400, is_submap=False)
    mvrr(address=1400, depth=1)    -> (2000-3000, is_submap=False)

    At this point, we know we went out of the original submap which
    ends at 2000. We need to recheck the region at 2000, it could be
    submap = True at depth 0 so we call

    mvrr(address=1400, depth=0)    -> (2000-3000, is_submap=False)

    Args:
      skip_executable_regions: Skips executable sections.
      skip_shared_regions: Skips shared sections. Includes mapped files.
      skip_readonly_regions: Skips readonly sections.

    Yields:
      Pairs (address, length) for each identified region.
    """

        address = ctypes.c_ulong(0)
        mapsize = ctypes.c_ulong(0)
        count = ctypes.c_uint32(submap_info_size)
        sub_info = vm_region_submap_short_info_data_64()
        depth = 0
        depth_end_addresses = {}

        while True:
            c_depth = ctypes.c_uint32(depth)

            r = libc.mach_vm_region_recurse(self.task, ctypes.pointer(address),
                                            ctypes.pointer(mapsize),
                                            ctypes.pointer(c_depth),
                                            ctypes.pointer(sub_info),
                                            ctypes.pointer(count))

            # If we get told "invalid address", we have crossed into kernel land...
            if r == 1:
                break

            if r != 0:
                raise process_error.ProcessError(
                    "Error in mach_vm_region, ret=%s" % r)

            if depth > 0 and address.value >= depth_end_addresses[depth]:
                del depth_end_addresses[depth]
                depth -= 1
                continue

            p = sub_info.protection
            is_executable = p & VM_PROT_EXECUTE
            if skip_executable_regions and is_executable:
                address.value += mapsize.value
                continue

            if skip_shared_regions and sub_info.share_mode in [
                    SM_COW, SM_SHARED, SM_TRUESHARED
            ]:
                address.value += mapsize.value
                continue

            if not p & VM_PROT_READ:
                address.value += mapsize.value
                continue

            is_writable = p & VM_PROT_WRITE
            if skip_readonly_regions and not is_writable:
                address.value += mapsize.value
                continue

            if sub_info.is_submap:
                depth += 1
                depth_end_addresses[depth] = address.value + mapsize.value
            else:
                yield rdf_memory.ProcessMemoryRegion(
                    start=address.value,
                    size=mapsize.value,
                    is_readable=True,
                    is_executable=is_executable,
                    is_writable=is_writable)
                address.value += mapsize.value