public void LoadModulesInRange(long VA, long length, string OnlyModule = null) { var KVS = new VirtualScanner(this, new Mem(MemAccess)); foreach (var artifact in KVS.Run(VA, VA + length)) { var ms = new MemSection() { IsExec = true, Module = artifact, VA = new VIRTUAL_ADDRESS(artifact.VA) }; var extracted = ExtractCVDebug(ms); if (extracted == null) { continue; } if (!string.IsNullOrWhiteSpace(OnlyModule) && OnlyModule != ms.Name) { continue; } if (!Sections.ContainsKey(artifact.VA)) { Sections.TryAdd(artifact.VA, ms); } // we can clobber this guy all the time I guess since everything is stateless in Sym and managed // entirely by the handle ID really which is local to our GUID so.... sym = Vtero.TryLoadSymbols(ID.GetHashCode(), ms.DebugDetails, ms.VA.Address); if (Vtero.VerboseOutput) { WriteColor(ConsoleColor.Green, $"symbol loaded [{sym != null}] from file [{ms.DebugDetails.PDBFullPath}]"); } } }
public dynamic xStructInfo(string Struct, long[] memRead = null, string Module = "ntkrnlmp") { MemSection pdb = null; if (Module == "ntkrnlmp" && KernelSection != null) { pdb = KernelSection; } else { var pdbPaths = from files in Sections.Values where files.DebugDetails != null && !string.IsNullOrWhiteSpace(files.DebugDetails.PDBFullPath) && files.DebugDetails.PDBFullPath.ToLower().Contains(Module.ToLower()) select files; pdb = pdbPaths.FirstOrDefault(); KernelSection = pdb; } if (sym == null) { sym = Vtero.TryLoadSymbols(ID.GetHashCode(), pdb.DebugDetails, pdb.VA.Address); } return(sym.xStructInfo(pdb.DebugDetails.PDBFullPath, Struct, memRead, GetVirtualByte, GetVirtualLong)); }
public static void DumpDetected(Vtero vtero, DetectedProc p, long VAStart = 0, long VAEnd = 0xffffffff0000) { var mods = vtero.ModuleScan(p, VAStart, VAEnd); // BUGBUG: TODO: Refactor the threadlocal stuff seems were re-entrant unsafe :( //Parallel.ForEach(mods, (detected) => //{ foreach (var detected in mods) { var cv_data = vtero.ExtractCVDebug(p, detected.Value, detected.Key); if (cv_data != null) { var sympath = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH"); if (string.IsNullOrWhiteSpace(sympath)) { sympath = "SRV*http://msdl.microsoft.com/download/symbols"; } if (vtero.TryLoadSymbols(p, detected.Value, cv_data, detected.Key, sympath)) { vtero.GetKernelDebuggerData(p, detected.Value, cv_data, sympath); } } } //}); }
public void LoadSymbols(MemSection OnlyMS = null) { foreach (var ms in Sections) { if (OnlyMS == null || (OnlyMS != null && OnlyMS.VA.Address == ms.Key)) { sym = Vtero.TryLoadSymbols(ID.GetHashCode(), ms.Value.DebugDetails, ms.Value.VA.Address); if (Vtero.VerboseOutput) { WriteColor(ConsoleColor.Green, $"symbol loaded [{sym != null}] from file [{ms.Value.DebugDetails.PDBFullPath}]"); } } } }
public static void DumpDetected(Vtero vtero, DetectedProc p, long VAStart = 0, long VAEnd = 0xffffffff0000) { var mods = vtero.ModuleScan(p, VAStart, VAEnd); //Parallel.ForEach(mods, (detected) => //{ foreach (var detected in p.Sections) { var cv_data = vtero.ExtractCVDebug(p, detected); if (cv_data != null) { var sympath = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH"); if (string.IsNullOrWhiteSpace(sympath)) sympath = "SRV*http://msdl.microsoft.com/download/symbols"; if(vtero.TryLoadSymbols(cv_data, detected.VA.Address, sympath)) vtero.KernelProc = p; } } //}); }
/// <summary> /// Currently we scan hard for only kernel regions (2MB pages + ExEC) /// If there are kernel modules named the OnlyModule it may cause us to ignore the real one in that case /// you can still scan for * by passing null or empty string /// </summary> /// <param name="OnlyModule">Stop when the first module named this is found</param> public VirtualScanner ScanAndLoadModules(string OnlyModule = "ntkrnlmp.pdb", bool OnlyLarge = true, bool IncludeKernelSpace = true, bool OnlyValid = true, bool IncludeData = false, bool DoExtraHeaderScan = true) { const int LARGE_PAGE_SIZE = 1024 * 1024 * 2; var curr = 0; PageTable.AddProcess(this, new Mem(MemAccess)); //var cnt = PT.FillPageQueue(OnlyLarge, IncludeKernelSpace); var KVS = new VirtualScanner(this, new Mem(MemAccess), DoExtraHeaderScan); // single threaded worked best so far //Parallel.For(0, cnt, (i, loopState) => x foreach (var range in PT.FillPageQueue(OnlyLarge, IncludeKernelSpace, OnlyValid, IncludeData)) //for (int i = 0; i < cnt; i++) { curr++; bool stop = false; if (Vtero.VerboseLevel > 1) { //var curr = cnt - PT.PageQueue.Count; //var done = Convert.ToDouble(curr) / Convert.ToDouble(cnt) * 100.0; Console.CursorLeft = 0; Console.Write($"{curr} scanned"); } if (range.PTE.Valid && !range.PTE.NoExecute) { foreach (var artifact in KVS.Run(range.VA.Address, range.VA.Address + (range.PTE.LargePage ? LARGE_PAGE_SIZE : MagicNumbers.PAGE_SIZE), range)) { var ms = new MemSection() { IsExec = true, Module = artifact, VA = new VIRTUAL_ADDRESS(artifact.VA), Source = range }; var extracted = ExtractCVDebug(ms); if (extracted == null) { if (Vtero.VerboseLevel > 1) { WriteColor(ConsoleColor.Yellow, $"failed debug info for PE @address {range.VA.Address:X}, extracted headers: {artifact}"); } continue; } if (!string.IsNullOrWhiteSpace(OnlyModule) && OnlyModule != ms.Name) { continue; } if (!Sections.ContainsKey(artifact.VA)) { Sections.TryAdd(artifact.VA, ms); } // we can clobber this guy all the time I guess since everything is stateless in Sym and managed // entirely by the handle ID really which is local to our GUID so.... sym = Vtero.TryLoadSymbols(ID.GetHashCode(), ms.DebugDetails, ms.VA.Address); if (Vtero.VerboseOutput) { WriteColor((sym != null) ? ConsoleColor.Green : ConsoleColor.Yellow, $" symbol loaded = [{sym != null}] PDB [{ms.DebugDetails.PDBFullPath}] @ {range.VA.Address:X}, {ms.Name}"); if (Vtero.VerboseLevel > 1) { WriteColor((sym != null) ? ConsoleColor.Green : ConsoleColor.Yellow, $"headers: { artifact} "); } } if (!string.IsNullOrWhiteSpace(OnlyModule)) { if (!string.IsNullOrWhiteSpace(ms.Name) && ms.Name == OnlyModule) { stop = true; //loopState.Stop(); break; } } //if (loopState.IsStopped) //return; if (stop) { break; } } } //if (loopState.IsStopped) // return;e //}); if (stop) { break; } } return(KVS); }
/// <summary> /// Currently we scan hard for only kernel regions (2MB pages + ExEC) /// If there are kernel modules named the OnlyModule it may cause us to ignore the real one in that case /// you can still scan for * by passing null or empty string /// </summary> /// <param name="OnlyModule">Stop when the first module named this is found</param> public VirtualScanner ScanAndLoadModules(string OnlyModule = "ntkrnlmp") { PageTable.AddProcess(this, new Mem(MemAccess)); var cnt = PT.FillPageQueue(true); var KVS = new VirtualScanner(this, new Mem(MemAccess)); KVS.ScanMode = VAScanType.PE_FAST; Parallel.For(0, cnt, (i, loopState) => { PFN range; var curr = cnt - PT.PageQueue.Count; var done = (int)(Convert.ToDouble(curr) / Convert.ToDouble(cnt) * 100.0) + 0.5; if (PT.PageQueue.TryDequeue(out range) && range.PTE.Valid) { var found = KVS.Run(range.VA.Address, range.VA.Address + (range.PTE.LargePage ? (1024 * 1024 * 2) : 0x1000), loopState); // Attempt load foreach (var artifact in found) { var ms = new MemSection() { IsExec = true, Module = artifact.Value, VA = new VIRTUAL_ADDRESS(artifact.Key) }; var extracted = ExtractCVDebug(ms); if (extracted == null) { continue; } if (!string.IsNullOrWhiteSpace(OnlyModule) && OnlyModule != ms.Name) { continue; } if (!Sections.ContainsKey(artifact.Key)) { Sections.TryAdd(artifact.Key, ms); } // we can clobber this guy all the time I guess since everything is stateless in Sym and managed // entirely by the handle ID really which is local to our GUID so.... sym = Vtero.TryLoadSymbols(ID.GetHashCode(), ms.DebugDetails, ms.VA.Address); if (Vtero.VerboseOutput) { WriteColor(ConsoleColor.Green, $"symbol loaded [{sym != null}] from file [{ms.DebugDetails.PDBFullPath}]"); } if (!string.IsNullOrWhiteSpace(OnlyModule)) { if (!string.IsNullOrWhiteSpace(ms.Name) && ms.Name == OnlyModule) { loopState.Stop(); return; } } if (loopState.IsStopped) { return; } } } if (loopState.IsStopped) { return; } }); return(KVS); }
public static void DumpIt(Vtero vtero, ConfigOptions co, DumpOptions dmpo) { var Version = vtero.Version; Mem.InitMem(co.FileName, vtero.MRD); // Extract Address Spaces verifies the linkages between // process<->CR3<->EPTP(if there is one) // and that they are functional var vetted = vtero.ExtrtactAddressSpaces(null, null, Version); // leaving this in as an example maybe? ;) //WriteLine("enter a group ID: "); //input = ReadLine(); //int Grp = int.Parse(input); //WriteLine("enter a process ID: "); //input = ReadLine(); //long procID = long.Parse(input, NumberStyles.HexNumber); //var proc = (from procz in vtero.ASGroups[Grp] // where procz.CR3Value == procID // select procz).First(); //int i = 1; //DetectedProc dp = proc; //while(dp == null) // dp = vtero.GetKernelRangeFromGroup(i++); // Scan for kernel // NT kernel may be in 0xFFFFF80000000 to 0xFFFFF8800000 range long KernVAStart = 0xF80000000000; long KernVAEnd = KernVAStart + (0x8000000000 - 0x1000); string input = string.Empty; var Detections = new Dictionary <long, Extract>(); DetectedProc LikelyKernel = null; bool Decoded = false; // were doing this in nested loops to brute force our way past any errors // but only need the first set of detections per group foreach (var grpz in vtero.ASGroups) { foreach (var vm in vtero.VMCSs.Values) { WriteColor(ConsoleColor.White, $"Group ID: {grpz.Key}"); foreach (var p in grpz.Value) { WriteLine($"Proc: {p.CR3Value:X}"); Detections = Detections.Concat( vtero.ModuleScan(p, KernVAStart, KernVAEnd).Where(x => !Detections.ContainsKey(x.Key))) .ToDictionary(x => x.Key, x => x.Value); if (Detections.Count() > 0) { LikelyKernel = p; if (vm.EPTP == 0) { p.vmcs = null; } else { p.vmcs = vm; } // scan for kernel foreach (var detected in Detections) { WriteColor(ConsoleColor.Green, $"Attempting to parse detected PE module loaded @ {detected.Key:X}"); WriteColor(ConsoleColor.Cyan, detected.Value.ToString()); if (detected.Value.ToString().Contains("POOLCODE")) { WriteColor(ConsoleColor.White, "Likely Kernel analyzing for CV data"); var cv_data = vtero.ExtractCVDebug(LikelyKernel, detected.Value, detected.Key); if (cv_data != null) { var sympath = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH"); if (string.IsNullOrWhiteSpace(sympath)) { sympath = "SRV*http://msdl.microsoft.com/download/symbols"; } if (vtero.TryLoadSymbols(LikelyKernel, detected.Value, cv_data, detected.Key, sympath)) { Decoded = vtero.GetKernelDebuggerData(LikelyKernel, detected.Value, cv_data, sympath); } } } } } if (Decoded) { break; } } if (Decoded) { break; } } if (Decoded) { break; } } ForegroundColor = ConsoleColor.Green; WriteLine($"{Environment.NewLine}Final analysis completed, address spaces extracted. {QuickOptions.Timer.Elapsed} {QuickOptions.FormatRate(vtero.FileSize * 3, QuickOptions.Timer.Elapsed)}"); // do a test dump // extract & dump could be done at the same time if (!dmpo.ListOnly) { vtero.DumpASToFile(); } //if (Vtero.VerboseOutput) //vtero.DumpFailList(); return; }