コード例 #1
0
ファイル: pte_mmap.c プロジェクト: dennisieur/rekall
// Edit the page tables to point a virtual address to a specific physical page.
//
// Args:
//  self: The this pointer to the object using this function.
//  target: The physical address to map to.
//
// Returns:
//  PTE_SUCCESS or PTE_ERROR
//
static PTE_STATUS pte_remap_rogue_page(PTE_MMAP_OBJ *self, PHYS_ADDR target) {
  // Can only remap pages, addresses must be page aligned.
  if (((!target) & PAGE_MASK) || self->rogue_page.offset) {
    WinDbgPrint("Failed to map %#016llx, "
                "only page aligned remapping is supported!",
                target);
    return PTE_ERROR;
  }

  WinDbgPrintDebug("Remapping pte at %p to %#016llx",
                   self->rogue_pte,
                   target);
  // Change the pte to point to the new offset.
  self->rogue_pte->page_frame = PAGE_TO_PFN(target);
  // Flush the old pte from the tlbs in the system.
  self->flush_tlbs_page_(self->rogue_page.pointer);

  return PTE_SUCCESS;
}
コード例 #2
0
ファイル: pte_mmap.c プロジェクト: google/rekall
// Call this before freeing the object or the rogue_page.
// Will reset the page table entry for the rogue page.
//
// Args:
//  self: Pointer to the allocated memory for this object.
//
void pte_mmap_cleanup(PTE_MMAP_OBJ *self) {
  WinDbgPrintDebug("Restoring pte to original mapping (%#016llx)",
                   self->original_addr);
  self->remap_page(self, self->original_addr);
  self->free_rogue_page_(self->rogue_page.pointer);
}
コード例 #3
0
ファイル: pte_mmap.c プロジェクト: google/rekall
// Traverses the page tables to find the pte for a given virtual address.
//
// Args:
//  self: The this pointer for the object calling this function.
//  vaddr: The virtual address to resolve the pte for
//  pte: A pointer to a pointer which will be set with the address of the pte,
//       if found.
//
// Returns:
//  PTE_SUCCESS or PTE_ERROR
//
static PTE_STATUS virt_find_pte(PTE_MMAP_OBJ *self, void *addr,
                                PTE **pte) {
  PTE_CR3 cr3;
  PML4E *pml4;
  PML4E *pml4e;
  PDPTE *pdpt;
  PDPTE *pdpte;
  PDE *pd;
  PDE *pde;
  PTE *pt;
  VIRT_ADDR vaddr;
  PTE_STATUS status = PTE_ERROR;

  vaddr.pointer = addr;

  WinDbgPrint("Resolving PTE for Address:%#016llx", vaddr);

  // Get contents of cr3 register to get to the PML4
  cr3 = self->get_cr3_();

  WinDbgPrint("Kernel CR3 is %p", cr3);
  WinDbgPrint("Kernel PML4 is at %p physical",
                   PFN_TO_PAGE(cr3.pml4_p));

  // Resolve the PML4
  pml4 = (PML4E *)self->phys_to_virt_(PFN_TO_PAGE(cr3.pml4_p));
  WinDbgPrint("kernel PML4 is at %p virtual", pml4);

  // Resolve the PDPT
  pml4e = (pml4 + vaddr.pml4_index);

  WinDbgPrint("PML4 entry %d is at %p", vaddr.pml4_index,
                   pml4e);

  if (!pml4e->present) {

    WinDbgPrint("Error, address %#016llx has no valid mapping in PML4:",
                vaddr.value);
    self->print_pte_(self, PTE_ERR, (PTE *)pml4e);
    goto error;
  }
  WinDbgPrint("PML4[%#010x]: %p)", vaddr.pml4_index, pml4e);


  pdpt = (PDPTE *)self->phys_to_virt_(PFN_TO_PAGE(pml4e->pdpt_p));
  WinDbgPrintDebug("Points to PDPT:   %p)", pdpt);

  // Resolve the PDT
  pdpte = (pdpt + vaddr.pdpt_index);
  if (!pdpte->present) {
    WinDbgPrint("Error, address %#016llx has no valid mapping in PDPT:",
                vaddr.value);
    self->print_pte_(self, PTE_ERR, (PTE *)pdpte);
    goto error;
  }
  if (pdpte->page_size) {
    WinDbgPrint("Error, address %#016llx belongs to a 1GB page:",
                vaddr.value);
    self->print_pte_(self, PTE_ERR, (PTE *)pdpte);
    goto error;
  }
  WinDbgPrint("PDPT[%#010x]: %p)", vaddr.pdpt_index, pdpte);
  pd = (PDE *)self->phys_to_virt_(PFN_TO_PAGE(pdpte->pd_p));
  WinDbgPrint("Points to PD:     %p)", pd);

  // Resolve the PT
  pde = (pd + vaddr.pd_index);
  if (!pde->present) {
    WinDbgPrint("Error, address %#016llx has no valid mapping in PD:",
                vaddr.value);
    self->print_pte_(self, PTE_ERR, (PTE *)pde);
    goto error;
  }
  if (pde->page_size) {
    WinDbgPrint("Error, address %#016llx belongs to a 2MB page:",
                vaddr.value);
    self->print_pte_(self, PTE_ERR, (PTE *)pde);
    goto error;
  }

  WinDbgPrint("PD  [%#010x]: %p)", vaddr.pd_index, pde);
  pt = (PTE *)self->phys_to_virt_(PFN_TO_PAGE(pde->pt_p));
  WinDbgPrint("Points to PT:     %p)", pt);

  // Get the PTE and Page Frame
  *pte = (pt + vaddr.pt_index);
  if (! (*pte)->present) {
    WinDbgPrint("Error, address %#016llx has no valid mapping in PT:",
                vaddr.value);
    self->print_pte_(self, PTE_ERR, (*pte));
    goto error;
  }
  WinDbgPrint("PT  [%#010x]: %p)", vaddr.pt_index, *pte);

  status = PTE_SUCCESS;
error:
  return status;
}