public PfnDatabase(DataProviderBase dataProvider, Profile profile, ulong virtualAddress) : base(profile, dataProvider, virtualAddress) { _is64 = (_profile.Architecture == "AMD64"); // there's no point if the system is live if (_dataProvider.IsLive) { return; } // first let's see if it already exists FileInfo cachedFile = new FileInfo(_dataProvider.CacheFolder + "\\pfn_database_map.gz"); if (cachedFile.Exists && !dataProvider.IsLive) { PfnDatabaseMap dbm = RetrievePfnMap(cachedFile); if (dbm != null) { _pfnDatabaseList = dbm.PfnDatabaseRecords; return; } } int pageCount = (int)(_dataProvider.ImageLength / 0x1000); int blockTracker = 25600; // this is how many records are on 300 pages byte[] blockBuffer = null; for (int i = 0; i < pageCount; i++) { ulong startAddress = virtualAddress + (uint)(i * 0x30); // assuming pfn records are always 48 bytes long! if (blockTracker == 25600) { blockTracker = 0; blockBuffer = _dataProvider.ReadMemoryBlock(startAddress, 300 * 0x1000); if (blockBuffer == null) { break; } } MMPFN entry = new MMPFN(blockBuffer, blockTracker * 48); PfnRecord record = entry.PfnRecord; ulong containingPage = record.U4.PteFrame; record.PtePhysicalLocation = (containingPage << 12) | record.PteAddress & 0xfff; record.PhysicalAddress = (ulong)(i * 0x1000); blockTracker++; if (record.PteAddress == 0) { continue; } _pfnDatabaseList.Add(record); } PfnDatabaseMap map = new PfnDatabaseMap(); map.PfnDatabaseRecords = _pfnDatabaseList; if (!dataProvider.IsLive) { PersistPfnMap(map, _dataProvider.CacheFolder + "\\pfn_database_map.gz"); } }
public MMPFN(byte[] buffer, int offset) { GCHandle pinnedPacket = GCHandle.Alloc(buffer, GCHandleType.Pinned); _MMPFN pfnRecord = (_MMPFN)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset), typeof(_MMPFN)); _pfnRecord = new PfnRecord(); _pfnRecord.Lock = pfnRecord.Lock; _pfnRecord.PteAddress = pfnRecord.PteAddress & 0xffffffffffff; _pfnRecord.PteLong = pfnRecord.PteLong; _pfnRecord.VolatilePteAddress = pfnRecord.VolatilePteAddress; _pfnRecord.NodeBlinkLow = pfnRecord.NodeBlinkLow; _pfnRecord.VaType = pfnRecord.VaType; _pfnRecord.NodeFlinkLow = pfnRecord.NodeFlinkLow; _pfnRecord.ViewCount = pfnRecord.ViewCount; _pfnRecord.U1 = new u1(pfnRecord.u1); _pfnRecord.U2 = new u2(pfnRecord.u2); _pfnRecord.U3 = new u3(pfnRecord.u3); _pfnRecord.OriginalPte = pfnRecord.OriginalPte; _pfnRecord.U4 = new u4(pfnRecord.u4); _pfnRecord.E1 = pfnRecord.e1; _pfnRecord.E2 = pfnRecord.e2; pinnedPacket.Free(); }