public void PersistPfnMap(PfnDatabaseMap source, string fileName) { byte[] bytesToCompress = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(source)); using (FileStream fileToCompress = File.Create(fileName)) using (GZipStream compressionStream = new GZipStream(fileToCompress, CompressionMode.Compress)) { compressionStream.Write(bytesToCompress, 0, bytesToCompress.Length); } }
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"); } }