private void DetectSectionsRamType(MemoryDescriptor mcu = null) { sectionMemoryTable = new Dictionary <ElfSection, string>(); var allocSections = new List <ElfSection>(); //get alloc allocSections foreach (var section in DwarfData.File.Sections) { if ((section.Header.flags & Elf32SectionFlags.SHF_ALLOC) == 0) { sectionMemoryTable[section] = unknownMemoryName; } else { allocSections.Add(section); } } if (mcu == null) { DetectSectionsRamTypeAuto(allocSections); } else { DetectSectionsRamTypeByMcu(allocSections, mcu); } DetectMemoryTypesEx(); }
public bool IsSupportedFormat() { bool rv = false; if (!File.Exists(DumpFile)) { return(rv); } using (var dstream = File.OpenRead(DumpFile)) { using (var dbin = new BinaryReader(dstream)) { // start with a easy to handle format of DMP if (ASCIIEncoding.ASCII.GetString(dbin.ReadBytes(8)) != "PAGEDU64") { return(rv); } dbin.BaseStream.Position = 0x2020; var StartOfMem = dbin.ReadUInt32(); // Find the RUN info dbin.BaseStream.Position = 0x88; var MemRunDescriptor = new MemoryDescriptor(); MemRunDescriptor.StartOfMemmory = StartOfMem; MemRunDescriptor.NumberOfRuns = dbin.ReadInt64(); MemRunDescriptor.NumberOfPages = dbin.ReadInt64(); // this struct has to fit in the header which is only 0x2000 in total size if (MemRunDescriptor.NumberOfRuns > 32 || MemRunDescriptor.NumberOfRuns < 0) { // TODO: in this case we have to de-patchguard the KDDEBUGGER_DATA block } else { // in this case StartOfMem is 0x2000 MemRunDescriptor.StartOfMemmory = 0x2000; rv = true; // we have an embedded RUN in the DMP file that appears to conform to the rules we know for (int i = 0; i < MemRunDescriptor.NumberOfRuns; i++) { var basePage = dbin.ReadInt64(); var pageCount = dbin.ReadInt64(); MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = basePage, PageCount = pageCount }); } PhysMemDesc = MemRunDescriptor; } } } return(rv); }
public BasicRunDetector(string MemSourceFile) { MemFile = MemSourceFile; FileInfo fi = new FileInfo(MemFile); SupportedStatus = fi.Exists; PhysMemDesc = new MemoryDescriptor(fi.Length); }
private void _read() { _threadId = m_io.ReadU4le(); _suspendCount = m_io.ReadU4le(); _priorityClass = m_io.ReadU4le(); _priority = m_io.ReadU4le(); _teb = m_io.ReadU8le(); _stack = new MemoryDescriptor(m_io, this, m_root); _threadContext = new LocationDescriptor(m_io, this, m_root); }
public bool IsSupportedFormat() { bool rv = false; if (!File.Exists(DumpFile)) return rv; using(var dstream = File.OpenRead(DumpFile)) { using (var dbin = new BinaryReader(dstream)) { // start with a easy to handle format of DMP if (ASCIIEncoding.ASCII.GetString(dbin.ReadBytes(8)) != "PAGEDU64") return rv; dbin.BaseStream.Position = 0x2020; var StartOfMem = dbin.ReadUInt32(); // Find the RUN info dbin.BaseStream.Position = 0x88; var MemRunDescriptor = new MemoryDescriptor(); MemRunDescriptor.StartOfMemmory = StartOfMem; MemRunDescriptor.NumberOfRuns = dbin.ReadInt64(); MemRunDescriptor.NumberOfPages = dbin.ReadInt64(); // this struct has to fit in the header which is only 0x2000 in total size if (MemRunDescriptor.NumberOfRuns > 32 || MemRunDescriptor.NumberOfRuns < 0) { // TODO: in this case we have to de-patchguard the KDDEBUGGER_DATA block } else { // in this case StartOfMem is 0x2000 MemRunDescriptor.StartOfMemmory = 0x2000; rv = true; // we have an embedded RUN in the DMP file that appears to conform to the rules we know for (int i = 0; i < MemRunDescriptor.NumberOfRuns; i++) { var basePage = dbin.ReadInt64(); var pageCount = dbin.ReadInt64(); MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = basePage, PageCount = pageCount }); } PhysMemDesc = MemRunDescriptor; } } } return rv; }
public MemoryProfile(DwarfData dwData, MemoryDescriptor memoryDescriptor = null) { DwarfData = dwData; DetectSectionsRamType(memoryDescriptor); //build memory usage table memoryUsageTable = new Dictionary <string, MemoryUsage>(); var memories = GetMemoryNames(); if (memories != null) { foreach (var memory in memories) { var sections = GetSectionsByMemoryEx(memory); var mem = new MemoryUsage { Sections = sections }; if (sections != null && sections.Length != 0) { mem.BytesUsed = sections.Aggregate(0UL, (current, section) => current + section.Header.size); if (memoryDescriptor != null && memoryDescriptor.IsEntryExists(memory)) { var entry = memoryDescriptor.GetEntryByName(memory); mem.Base = (ulong)entry.Origin; mem.Length = (ulong)entry.Length; } else { } } memoryUsageTable[memory] = mem; } } }
IntPtr INativeMemoryProvider.AllocateBytes(long numberOfBytes) { var cashed = _free.Find(md => md.NumberOfBytes == numberOfBytes); if (cashed != null) { _free.Remove(cashed); _logger?.WriteStatus($"\t\t\t\tReUsing {numberOfBytes}"); return(cashed.Ptr); } var ptr = AllocateMemory(numberOfBytes); var descriptor = new MemoryDescriptor(ptr, numberOfBytes); _allocated.Add(descriptor); var stack = MemoryUtils.ParseStackTrace(); var gigaBytes = numberOfBytes / (1024.0 * 1024 * 1024); _logger?.WriteError($"Allocating {gigaBytes:######0.0000} GiB ({numberOfBytes} bytes), ptr:{ptr} at {stack[7]}"); return(ptr); }
/// <summary> /// This pulls info from the hypervisor areas regarding memory extents /// </summary> /// <param name="vtero"></param> /// <returns></returns> public override bool IsSupportedFormat(Vtero vtero) { long InfoCnt; long nr_vcpu, nr_pages = 0, page_size = 0, pfn_LAST, pfn_VAL; // use abstract implementation & scan for internal LogicalPhysMemDesc = ExtractMemDesc(vtero); if (Elf == null) return false; using (var dstream = File.OpenRead(vtero.MemFile)) { using (var ebin = new BinaryReader(dstream)) { ELFInfo = Elf.GetSection(".note.Xen"); // get note stuff and fill in da info if (ELFInfo != null) { ebin.BaseStream.Position = ELFInfo.Offset; InfoCnt = ebin.ReadInt64(); for (long l = 0; l < InfoCnt; l++) { var InfoType = ebin.ReadInt32(); ebin.BaseStream.Position += 12; switch (InfoType) { // header type case 0x2000001: nr_vcpu = ebin.ReadInt64(); nr_pages = ebin.ReadInt64(); page_size = ebin.ReadInt64(); break; // none type case 0x2: break; default: break; } } ELFPfn = Elf.GetSection(".xen_pfn"); ebin.BaseStream.Position = ELFPfn.Offset; // base page, length long CurrBasePage = 0; long CurrRunLen = 0; // parse the array pfn_LAST = ebin.ReadInt64(); for (long pfnx = 0; pfnx < nr_pages; pfnx++) { CurrRunLen++; pfn_VAL = ebin.ReadInt64(); if (pfn_LAST + 1 == pfn_VAL) { pfn_LAST = pfn_VAL; continue; } // add run DetectedRuns.Add(CurrBasePage, CurrRunLen); // reset counter // that is adjusted in the value pfn_LAST = CurrBasePage = pfn_VAL; CurrRunLen = 0; if (CurrBasePage >= nr_pages) break; } } } } ELFPages = Elf.GetSection(".xen_pages"); if (ELFPages != null) StartOfMem = ELFPages.Offset; PhysMemDesc = new MemoryDescriptor(nr_pages * page_size); PhysMemDesc.NumberOfRuns = DetectedRuns.Count; PhysMemDesc.NumberOfPages = nr_pages; PhysMemDesc.StartOfMemmory = StartOfMem; PhysMemDesc.Run = new List<MemoryRun>(); foreach (var kvp in DetectedRuns) PhysMemDesc.Run.Add(new MemoryRun() { BasePage = kvp.Key, PageCount = kvp.Value }); return SupportedStatus; }
/// <summary> /// OK need to double check later but even though there are 64 bits available in the field /// only 32bits are seemingly being used. Otherwise the values have to be interpreted as /// physical addresses and not page numbers. /// </summary> /// <returns></returns> public override bool IsSupportedFormat(Vtero vtero) { // use abstract implementation & scan for internal // were actually not going to use this in VMWare since were so good at vmss // this is sort of meaningless :( //LogicalPhysMemDesc = ExtractMemDesc(vtero); bool rv = false; if (!File.Exists(vDeviceFile) || !File.Exists(MemFile)) { return(rv); } // Let's seee how far we can get w/o being to aggressive here //using (var dstream = File.OpenRead(vDeviceFile)) //{ // using (var dbin = new BinaryReader(dstream)) // { // // D2BE is really easy to extract data from // if (dbin.ReadUInt32() != 0xBED2BED2) // return rv; // } //} rv = true; var MemRunDescriptor = new MemoryDescriptor(); // vmem files are contagious starting from 0 MemRunDescriptor.StartOfMemmory = 0; var inFile = File.OpenRead(vDeviceFile); // TODO: make this (parsing) more precise for additional versions var stateData = new byte[0x40000]; inFile.Read(stateData, 0, stateData.Length); var ToFind = ASCIIEncoding.ASCII.GetBytes("regionsCount"); var rpn = ASCIIEncoding.ASCII.GetBytes("regionPageNum"); var ppn = ASCIIEncoding.ASCII.GetBytes("regionPPN"); var rsiz = ASCIIEncoding.ASCII.GetBytes("regionSize"); int i; bool Found = false; for (i = 0; i < stateData.Length - ToFind.Length; i++) { int n = 0; do { if (stateData[i + n] != ToFind[n]) { break; } n++; if (n >= ToFind.Length) { Found = true; } } while (!Found); if (Found) { break; } } long TotalPages = 0; i += ToFind.Length; var Count = BitConverter.ToUInt32(stateData, i); MemRunDescriptor.NumberOfRuns = Count; i += 4; i += 2; // 2 bytes looks like a typeID or some sort of magic // below the >> 20 is/was what seemed to be an adjustment for 64-44 bits of // physical address range // however the additional >> 12 is physical address into physical pages // but it seemingly was supposed to be pages to begin with so who knows, but this works // maybe it is pages and I needed +4 on the index and then everything works with a .ToUInt32 // but that now seems short of the physical limits, anyhow, this works ;) for (int r = 0; r < Count; r++) { i += rpn.Length; var basePage = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; i += ppn.Length; var ppnVal = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; i += rsiz.Length; var regionSize = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; TotalPages += regionSize; MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = ppnVal, PageCount = regionSize, regionPPN = basePage }); } MemRunDescriptor.NumberOfPages = TotalPages; PhysMemDesc = MemRunDescriptor; // adjust start of memory to if (vDeviceFile == MemFile) { var x = (int)(Math.Ceiling((decimal)i / 0x10000) * 0x10000); StartOfMem = x; } if (TotalPages == 0) { MemRunDescriptor.NumberOfPages = new FileInfo(MemFile).Length >> MagicNumbers.PAGE_SHIFT; PhysMemDesc = MemRunDescriptor; LogicalPhysMemDesc = ExtractMemDesc(vtero); } return(rv); }
/// <summary> /// OK need to double check later but even though there are 64 bits available in the field /// only 32bits are seemingly being used. Otherwise the values have to be interpreted as /// physical addresses and not page numbers. /// </summary> /// <returns></returns> public override bool IsSupportedFormat(Vtero vtero) { // use abstract implementation & scan for internal // were actually not going to use this in VMWare since were so good at vmss // this is sort of meaningless :( //LogicalPhysMemDesc = ExtractMemDesc(vtero); bool rv = false; if (!File.Exists(vDeviceFile) || !File.Exists(MemFile)) return rv; using (var dstream = File.OpenRead(vDeviceFile)) { using (var dbin = new BinaryReader(dstream)) { // D2BE is really easy to extract data from if (dbin.ReadUInt32() != 0xBED2BED2) return rv; } } rv = true; var MemRunDescriptor = new MemoryDescriptor(); // vmem files are contagious starting from 0 MemRunDescriptor.StartOfMemmory = 0; var stateData = File.ReadAllBytes(vDeviceFile); var ToFind = ASCIIEncoding.ASCII.GetBytes("regionsCount"); var rpn = ASCIIEncoding.ASCII.GetBytes("regionPageNum"); var ppn = ASCIIEncoding.ASCII.GetBytes("regionPPN"); var rsiz = ASCIIEncoding.ASCII.GetBytes("regionSize"); int i; for(i=0; i < stateData.Length-ToFind.Length; i++) { int n = 0; bool Found = false; do { if (stateData[i + n] != ToFind[n]) break; n++; if (n >= ToFind.Length) Found = true; } while (!Found); if (Found) break; } long TotalPages = 0; i += ToFind.Length; var Count = BitConverter.ToUInt32(stateData, i); MemRunDescriptor.NumberOfRuns = Count; i += 4; i += 2; // 2 bytes looks like a typeID or some sort of magic // below the >> 20 is/was what seemed to be an adjustment for 64-44 bits of // physical address range // however the additional >> 12 is physical address into physical pages // but it seemingly was supposed to be pages to begin with so who knows, but this works // maybe it is pages and I needed +4 on the index and then everything works with a .ToUInt32 // but that now seems short of the physical limits, anyhow, this works ;) for (int r = 0; r < Count; r++) { i += rpn.Length; var basePage = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; i += ppn.Length; var ppnVal = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; i += rsiz.Length; var regionSize = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; TotalPages += regionSize; MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = ppnVal, PageCount = regionSize, regionPPN = basePage }); } MemRunDescriptor.NumberOfPages = TotalPages; PhysMemDesc = MemRunDescriptor; return rv; }
/// <summary> /// Extract memory extents info from the guest memory /// </summary> /// <param name="vtero"></param> /// <returns></returns> public MemoryDescriptor ExtractMemDesc(Vtero vtero) { MemoryDescriptor MemRunDescriptor = null; // rarely used pool tag var off = Scanner.BackwardsValueScan(vtero.MemFile, 0x6c4d6d4d); using (var dstream = File.OpenRead(vtero.MemFile)) { var MemSize = dstream.Length; long totPageCnt = 0; using (var dbin = new BinaryReader(dstream)) { foreach (var xoff in off) { //WriteLine($"Checking Memory Descriptor @{(xoff + 28):X}"); if (xoff > vtero.FileSize) { // WriteLine($"offset {xoff:X} > FileSize {vtero.FileSize:X}"); continue; } for (long doff = 4; doff <= 64; doff += 4) { dstream.Position = xoff + doff; MemRunDescriptor = new MemoryDescriptor(); MemRunDescriptor.NumberOfRuns = dbin.ReadInt64(); MemRunDescriptor.NumberOfPages = dbin.ReadInt64(); var RunCnt = MemRunDescriptor.NumberOfRuns; var PageCnt = MemRunDescriptor.NumberOfPages; //Console.WriteLine($"Runs: {RunCnt}, Pages: {MemRunDescriptor.NumberOfPages} "); long lastBasePage = 0; if (RunCnt > 0 && MemRunDescriptor.NumberOfRuns < 32) { MemRunDescriptor.Run = new List <MemoryRun>((int)RunCnt); for (int i = 0; i < RunCnt; i++) { var basePage = dbin.ReadInt64(); // error check range too high/low if (basePage < lastBasePage || basePage < 0) { break; } lastBasePage = basePage; var pageCount = dbin.ReadInt64(); if (pageCount > PageCnt || pageCount <= 0) { break; } totPageCnt += pageCount; MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = basePage, PageCount = pageCount }); } if (totPageCnt > (PageCnt + 1024) || totPageCnt <= 0) { continue; } // if we have counted more pages than we have in disk // or // if we have less than 1/2 the pages we need (this is fudge factor should be precise right!) if (totPageCnt > (((MemSize - StartOfMem) >> MagicNumbers.PAGE_SHIFT) & 0xffffffff) || totPageCnt < (((MemSize - StartOfMem) >> MagicNumbers.PAGE_SHIFT) & 0xffffffff) / 2 ) { //Console.WriteLine($"odd/bad memory run, skipping"); continue; } else { return(MemRunDescriptor); } } //WriteLine($"MemoryDescriptor {MemRunDescriptor}"); } } } } #if OLD_CODE long aSkipCount = 0; for (int i = 0; i < MemRunDescriptor.NumberOfRuns; i++) { var RunSkip = MemRunDescriptor.Run[i].BasePage - aSkipCount; MemRunDescriptor.Run[i].SkipCount = RunSkip; aSkipCount = MemRunDescriptor.Run[i].PageCount; } #endif //WriteLine("Finished VALUE scan."); return(MemRunDescriptor); }
/// <summary> /// Extract memory extents info from the guest memory /// </summary> /// <param name="vtero"></param> /// <returns></returns> public MemoryDescriptor ExtractMemDesc(Vtero vtero) { MemoryDescriptor MemRunDescriptor = null; // rarely used pool tag var off = Scanner.BackwardsValueScan(vtero.MemFile, 0x6c4d6d4d); using (var dstream = File.OpenRead(vtero.MemFile)) { var MemSize = dstream.Length; long totPageCnt = 0; using (var dbin = new BinaryReader(dstream)) { foreach (var xoff in off) { //WriteLine($"Checking Memory Descriptor @{(xoff + 28):X}"); if (xoff > vtero.FileSize) { // WriteLine($"offset {xoff:X} > FileSize {vtero.FileSize:X}"); continue; } for (long doff = 4; doff <= 64; doff += 4) { dstream.Position = xoff + doff; MemRunDescriptor = new MemoryDescriptor(); MemRunDescriptor.NumberOfRuns = dbin.ReadInt64(); MemRunDescriptor.NumberOfPages = dbin.ReadInt64(); var RunCnt = MemRunDescriptor.NumberOfRuns; var PageCnt = MemRunDescriptor.NumberOfPages; //Console.WriteLine($"Runs: {RunCnt}, Pages: {MemRunDescriptor.NumberOfPages} "); long lastBasePage = 0; if (RunCnt > 0 && MemRunDescriptor.NumberOfRuns < 32) { MemRunDescriptor.Run = new List<MemoryRun>((int)RunCnt); for (int i = 0; i < RunCnt; i++) { var basePage = dbin.ReadInt64(); // error check range too high/low if (basePage < lastBasePage || basePage < 0) break; lastBasePage = basePage; var pageCount = dbin.ReadInt64(); if (pageCount > PageCnt || pageCount <= 0) break; totPageCnt += pageCount; MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = basePage, PageCount = pageCount }); } if (totPageCnt > (PageCnt + 1024) || totPageCnt <= 0) continue; // if we have counted more pages than we have in disk // or // if we have less than 1/2 the pages we need (this is fudge factor should be precise right!) if (totPageCnt > (((MemSize - StartOfMem) >> MagicNumbers.PAGE_SHIFT) & 0xffffffff) || totPageCnt < (((MemSize - StartOfMem) >> MagicNumbers.PAGE_SHIFT) & 0xffffffff) / 2 ) { //Console.WriteLine($"odd/bad memory run, skipping"); continue; } else return MemRunDescriptor; } //WriteLine($"MemoryDescriptor {MemRunDescriptor}"); } } } } #if OLD_CODE long aSkipCount = 0; for (int i=0; i < MemRunDescriptor.NumberOfRuns; i++) { var RunSkip = MemRunDescriptor.Run[i].BasePage - aSkipCount; MemRunDescriptor.Run[i].SkipCount = RunSkip; aSkipCount = MemRunDescriptor.Run[i].PageCount; } #endif //WriteLine("Finished VALUE scan."); return MemRunDescriptor; }
static void Main(string[] args) { //string linkerScriptPath = @"C:/Users/Sergey/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32F4xxxx-HAL/LinkerScripts/STM32F439xI_flash.lds"; string elfFilePath = @"D:\MotionParallaxResearch\NMarker\V03\Software\ATmega328P\ATmega328P\ATmega328P\Debug\ATmega328P.elf"; MemoryDescriptor mem = null;// MemoryDescriptor.FromLinkerScript(linkerScriptPath); ElfFile elf = new ElfFile(File.ReadAllBytes(elfFilePath)); DwarfData dwData = new DwarfData(elf); MemoryProfile profile = new MemoryProfile(dwData, mem); var flashSections = profile.GetFlashSections(); var progSections = profile.GetProgramSections(); var memNames = profile.GetMemoryNames(); foreach (var name in memNames) { var sections = profile.GetSectionsByMemoryEx(name); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Memory: {0}", name); ulong totalSize = 0; foreach (var section in sections) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("\t{0} : {1}", section.Name, section.Header.size); totalSize += section.Header.size; //print symbols var fileGroups = section.Items.GroupBy(v => Path.GetFileName(v.FileStr)).ToArray(); foreach (var fileGroup in fileGroups) { Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("\t\t{0} : ", fileGroup.Key); Console.ResetColor(); foreach (var item in fileGroup) { var p1 = string.Format("\t\t\t{0}:", item.Name); if (p1.Length < 14) { p1 += "\t"; } if (p1.Length < 25) { p1 += "\t"; } Console.WriteLine(p1 + string.Format("\t{0}:\t0x{1:x}", item.Size, item.Pc)); } } } Console.WriteLine("\tTotal size: {0}", totalSize); } var flashSize = flashSections.Aggregate <ElfSection, ulong>(0, (current, item) => current + item.Header.size); var prgSize = progSections.Aggregate <ElfSection, ulong>(0, (current, item) => current + item.Header.size); Console.ReadLine(); }
private void DetectSectionsRamTypeByMcu(IEnumerable <ElfSection> allocSections, MemoryDescriptor mcu) { foreach (var section in allocSections) { sectionMemoryTable[section] = unknownMemoryName; foreach (var memoryEntry in mcu.Entries) { if ((section.Header.addr >= memoryEntry.Origin) && (section.Header.addr <= (memoryEntry.Origin + memoryEntry.Length))) { sectionMemoryTable[section] = memoryEntry.Name; break; } } } }
public override bool IsSupportedFormat(Vtero vtero) { bool rv = false; if (!File.Exists(DumpFile)) { return(rv); } // use abstract implementation & scan for internal LogicalPhysMemDesc = ExtractMemDesc(vtero); using (var dstream = File.OpenRead(DumpFile)) { MemSize = dstream.Length; using (var dbin = new BinaryReader(dstream)) { // start with a easy to handle format of DMP if (ASCIIEncoding.ASCII.GetString(dbin.ReadBytes(8)) != "PAGEDU64") { return(rv); } dbin.BaseStream.Position = 0x2020; StartOfMem = dbin.ReadUInt32(); // Find the RUN info dbin.BaseStream.Position = 0x88; var MemRunDescriptor = new MemoryDescriptor(); MemRunDescriptor.StartOfMemmory = StartOfMem; MemRunDescriptor.NumberOfRuns = dbin.ReadInt64(); MemRunDescriptor.NumberOfPages = dbin.ReadInt64(); // this struct has to fit in the header which is only 0x2000 in total size if (MemRunDescriptor.NumberOfRuns > 32 || MemRunDescriptor.NumberOfRuns < 0) { // TODO: in this case we have to de-patchguard the KDDEBUGGER_DATA block // before resulting to that... implemented a memory scanning mode to extract the runs out via struct detection PhysMemDesc = LogicalPhysMemDesc; PhysMemDesc.StartOfMemmory = StartOfMem; // physmem is preferred place to load from so if we have only 1 run move it to phys. LogicalPhysMemDesc = null; } else { // in this case StartOfMem is 0x2000 MemRunDescriptor.StartOfMemmory = 0x2000; // we have an embedded RUN in the DMP file that appears to conform to the rules we know for (int i = 0; i < MemRunDescriptor.NumberOfRuns; i++) { var basePage = dbin.ReadInt64(); var pageCount = dbin.ReadInt64(); MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = basePage, PageCount = pageCount }); } PhysMemDesc = MemRunDescriptor; } rv = true; } } #if OLD_CODE long aSkipCount = 0; for (int i = 0; i < PhysMemDesc.NumberOfRuns; i++) { var RunSkip = PhysMemDesc.Run[i].BasePage - aSkipCount; PhysMemDesc.Run[i].SkipCount = RunSkip; aSkipCount = PhysMemDesc.Run[i].BasePage + PhysMemDesc.Run[i].PageCount; } #endif return(rv); }
/// <summary> /// OK need to double check later but even though there are 64 bits available in the field /// only 32bits are seemingly being used. Otherwise the values have to be interpreted as /// physical addresses and not page numbers. /// </summary> /// <returns></returns> public bool IsSupportedFormat() { bool rv = false; if (!File.Exists(vDeviceFile) || !File.Exists(MemFile)) { return(rv); } using (var dstream = File.OpenRead(vDeviceFile)) { using (var dbin = new BinaryReader(dstream)) { // D2BE is really easy to extract data from if (dbin.ReadUInt32() != 0xBED2BED2) { return(rv); } } } rv = true; var MemRunDescriptor = new MemoryDescriptor(); // vmem files are contagious starting from 0 MemRunDescriptor.StartOfMemmory = 0; var stateData = File.ReadAllBytes(vDeviceFile); var ToFind = ASCIIEncoding.ASCII.GetBytes("regionsCount"); var rpn = ASCIIEncoding.ASCII.GetBytes("regionPageNum"); var ppn = ASCIIEncoding.ASCII.GetBytes("regionPPN"); var rsiz = ASCIIEncoding.ASCII.GetBytes("regionSize"); int i; for (i = 0; i < stateData.Length - ToFind.Length; i++) { int n = 0; bool Found = false; do { if (stateData[i + n] != ToFind[n]) { break; } n++; if (n >= ToFind.Length) { Found = true; } } while (!Found); if (Found) { Console.WriteLine($"Found it at 0x{i:X}"); break; } } long TotalPages = 0; i += ToFind.Length; var Count = BitConverter.ToUInt32(stateData, i); MemRunDescriptor.NumberOfRuns = Count; i += 4; i += 2; // 2 bytes looks like a typeID or some sort of magic // below the >> 20 is/was what seemed to be an adjustment for 64-44 bits of // physical address range // however the additional >> 12 is physical address into physical pages // but it seemingly was supposed to be pages to begin with so who knows, but this works // maybe it is pages and I needed +4 on the index and then everything works with a .ToUInt32 // but that now seems short of the physical limits, anyhow, this works ;) for (int r = 0; r < Count; r++) { i += rpn.Length; var basePage = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; i += ppn.Length; var ppnVal = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; i += rsiz.Length; var regionSize = BitConverter.ToInt64(stateData, i) >> 20 >> 12; i += 8; i += 2; TotalPages += (regionSize >> 12); MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = ppnVal, PageCount = regionSize, regionPPN = basePage }); } MemRunDescriptor.NumberOfPages = TotalPages; PhysMemDesc = MemRunDescriptor; return(rv); }
public void Reload(string elfFilePath, string linkerScrintFilePath) { _elfUri = new Uri(elfFilePath); try { File = new ElfFile(System.IO.File.ReadAllBytes(elfFilePath)); } catch (Exception ex) { Debug.WriteLine(ex.Message); return; } _dwarf = new DwarfData(_elfFile); _memoryDescriptor = System.IO.File.Exists(linkerScrintFilePath) ? MemoryDescriptor.FromLinkerScript(linkerScrintFilePath) : null; Profile = new MemoryProfile(_dwarf, _memoryDescriptor); Symbols.Clear(); foreach (var memoryName in Profile.MemoryNames) { var adapter = new MemoryTypeAdapter(Profile, memoryName); foreach (var section in adapter.Sections) { foreach (var symbol in section.Symbols) { if (symbol.Header.Info.SymbolType == Elf32SymbolType.STT_SECTION) { continue; } SymbolDescriptor desc = new SymbolDescriptor(); desc.Section = section; desc.Memory = adapter; desc.Symbol = symbol; desc.DwarfUnitItem = _dwarf.globalItems.FirstOrDefault(v => v.Name == symbol.Name); /*Uri address1 = new Uri("http://www.contoso.com/"); * * // Create a new Uri from a string. * Uri address2 = new Uri("http://www.contoso.com/index.htm?date=today"); * * // Determine the relative Uri. * Console.WriteLine("The difference is {0}", address1.MakeRelativeUri(address2));*/ if (!string.IsNullOrEmpty(desc.DwarfUnitItem?.FileStr)) { if (System.IO.File.Exists(desc.DwarfUnitItem.FileStr)) { Uri elfUri = new Uri(elfFilePath); Uri symbolUri = new Uri(desc.DwarfUnitItem.FileStr); Uri relativePath = elfUri.MakeRelativeUri(symbolUri); desc.DwarfUnitItem.FileStr = relativePath.ToString(); } } Symbols.Add(desc); } } } UpdateTitle(); }
/// <summary> /// This pulls info from the hypervisor areas regarding memory extents /// </summary> /// <param name="vtero"></param> /// <returns></returns> public override bool IsSupportedFormat(Vtero vtero) { long InfoCnt; long nr_vcpu, nr_pages = 0, page_size = 0, pfn_LAST, pfn_VAL; // use abstract implementation & scan for internal LogicalPhysMemDesc = ExtractMemDesc(vtero); if (Elf == null) { return(false); } using (var dstream = File.OpenRead(vtero.MemFile)) { using (var ebin = new BinaryReader(dstream)) { ELFInfo = Elf.GetSection(".note.Xen"); // get note stuff and fill in da info if (ELFInfo != null) { ebin.BaseStream.Position = ELFInfo.Offset; InfoCnt = ebin.ReadInt64(); for (long l = 0; l < InfoCnt; l++) { var InfoType = ebin.ReadInt32(); ebin.BaseStream.Position += 12; switch (InfoType) { // header type case 0x2000001: nr_vcpu = ebin.ReadInt64(); nr_pages = ebin.ReadInt64(); page_size = ebin.ReadInt64(); break; // none type case 0x2: break; default: break; } } ELFPfn = Elf.GetSection(".xen_pfn"); ebin.BaseStream.Position = ELFPfn.Offset; // base page, length long CurrBasePage = 0; long CurrRunLen = 0; // parse the array pfn_LAST = ebin.ReadInt64(); for (long pfnx = 0; pfnx < nr_pages; pfnx++) { CurrRunLen++; pfn_VAL = ebin.ReadInt64(); if (pfn_LAST + 1 == pfn_VAL) { pfn_LAST = pfn_VAL; continue; } // add run DetectedRuns.Add(CurrBasePage, CurrRunLen); // reset counter // that is adjusted in the value pfn_LAST = CurrBasePage = pfn_VAL; CurrRunLen = 0; if (CurrBasePage >= nr_pages) { break; } } } } } ELFPages = Elf.GetSection(".xen_pages"); if (ELFPages != null) { StartOfMem = ELFPages.Offset; } PhysMemDesc = new MemoryDescriptor(nr_pages * page_size); PhysMemDesc.NumberOfRuns = DetectedRuns.Count; PhysMemDesc.NumberOfPages = nr_pages; PhysMemDesc.StartOfMemmory = StartOfMem; PhysMemDesc.Run = new List <MemoryRun>(); foreach (var kvp in DetectedRuns) { PhysMemDesc.Run.Add(new MemoryRun() { BasePage = kvp.Key, PageCount = kvp.Value }); } return(SupportedStatus); }
public static Vtero Scanit(ConfigOptions co) { bool SkipVMCS = (co.VersionsToEnable & PTType.VMCS) != PTType.VMCS; var Filename = co.FileName; co.VersionsToEnable = co.VersionsToEnable & ~PTType.VMCS; // allocate now so that we can un-serialize or keep an instance Vtero vtero = new Vtero(); // this instance is temporally used for loading state // i.e. don't set properties or fields here if (!co.IgnoreSaveData) { vtero = vtero.CheckpointRestoreState(Filename); if (vtero == null) { vtero = new Vtero(); } else { vtero.OverRidePhase = true; } } if (vtero.Phase < 2) { if (!co.ForceSingleFlatMemRun) { vtero = new Vtero(Filename); } else { var siz = new FileInfo(co.FileName).Length; vtero.MRD = new BasicRunDetector(); vtero.MRD.MemFile = co.FileName; vtero.MRD.vDeviceFile = co.FileName; vtero.MRD.PhysMemDesc = new MemoryDescriptor(siz); vtero = new Vtero(Filename, vtero.MRD); } } if (!vtero.OverRidePhase) { Mem.InitMem(co.FileName, vtero.MRD); //ProgressBarz.BaseMessage = new ConsoleString("First pass, looking for processes"); ForegroundColor = ConsoleColor.Cyan; #if TESTING Timer = Stopwatch.StartNew(); if ((Version & PTType.VALUE) == PTType.VALUE) { var off = vtero.ScanValue(Is64Scan, valuL, 0); WriteLine(FormatRate(vtero.FileSize, Timer.Elapsed)); using (var dstream = File.OpenRead(vtero.MemFile)) { using (var dbin = new BinaryReader(dstream)) { foreach (var xoff in off) { WriteLine($"Checking Memory Descriptor @{(xoff + 28):X}"); if (xoff > vtero.FileSize) { WriteLine($"offset {xoff:X} > FileSize {vtero.FileSize:X}"); continue; } dstream.Position = xoff + 28; var MemRunDescriptor = new MemoryDescriptor(); MemRunDescriptor.NumberOfRuns = dbin.ReadInt64(); MemRunDescriptor.NumberOfPages = dbin.ReadInt64(); Console.WriteLine($"Runs: {MemRunDescriptor.NumberOfRuns}, Pages: {MemRunDescriptor.NumberOfPages} "); if (MemRunDescriptor.NumberOfRuns < 0 || MemRunDescriptor.NumberOfRuns > 32) { continue; } for (int i = 0; i < MemRunDescriptor.NumberOfRuns; i++) { var basePage = dbin.ReadInt64(); var pageCount = dbin.ReadInt64(); MemRunDescriptor.Run.Add(new MemoryRun() { BasePage = basePage, PageCount = pageCount }); } WriteLine($"MemoryDescriptor {MemRunDescriptor}"); } } } WriteLine("Finished VALUE scan."); return; } if ((Version & PTType.VALUE) == PTType.VALUE) { return; } #endif } // basic perf checking //QuickOptions.Timer = Stopwatch.StartNew(); var procCount = vtero.ProcDetectScan(co.VersionsToEnable); // second pass // with the page tables we acquired, locate candidate VMCS pages in the format // [31-bit revision id][abort indicator] // the page must also have at least 1 64bit value which is all set (-1) // Root-HOST CR3 will have uniform diff // unless an extent based dump image is input, some .DMP variations // TODO: Add support for extent based inputs // Guest VMCS will contain host CR3 & guest CR3 (hCR3 & gCR3) // sometimes CR3 will be found in multiple page tables, e.g. system process or SMP // if I have more than 1 CR3 from different file_offset, just trim them out for now // future may have a reason to isolate based on original locationAG if (SkipVMCS) { if (!vtero.OverRidePhase) { vtero.GroupAS(); } if (co.VerboseLevel > 1) { WriteColor(ConsoleColor.Yellow, "Skipping VMCS scan (as requested)."); } } else { //ProgressBarz.BaseMessage = new ConsoleString("Second pass, correlating for VMCS pages"); var VMCSCount = vtero.VMCSScan(); //Timer.Stop(); if (!vtero.OverRidePhase) { //WriteColor(ConsoleColor.Blue, ConsoleColor.Yellow, $"{VMCSCount} candidate VMCS pages. Time to process: {QuickOptions.Timer.Elapsed}, Data scanned: {vtero.FileSize:N}"); // second time //WriteColor(ConsoleColor.Blue, ConsoleColor.Yellow, $"Second pass done. {QuickOptions.FormatRate(vtero.FileSize * 2, QuickOptions.Timer.Elapsed)}"); // each of these depends on a VMCS scan/pass having been done at the moment WriteColor(ConsoleColor.Cyan, ConsoleColor.Black, "grouping and joining all memory"); } // After this point were fairly functional vtero.GroupAS(); } // sync-save state so restarting is faster if (!co.IgnoreSaveData) { if (Vtero.VerboseLevel > 0) { Write($"Saving checkpoint... "); } var saveStateFile = vtero.CheckpointSaveState(); WriteColor(ConsoleColor.White, saveStateFile); } Console.CursorVisible = true; return(vtero); }