Beispiel #1
0
        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}]");
                }
            }
        }
Beispiel #2
0
        public dynamic xStructInfo(string Struct, long Address, int minLen = 4096, 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;
            }

            long[] memRead = null;
            if (Address != 0)
            {
                memRead = GetVirtualLongLen(Address, minLen);
            }

            var rv = sym.xStructInfo(pdb.DebugDetails.PDBFullPath, Struct, memRead, GetVirtualByte, GetVirtualLong);

            rv.SelfAddr = Address;

            return(rv);
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        /// <summary>
        ///  This guy names the section and establishes the codeview data needed for symbol handling
        /// </summary>
        /// <param name="sec"></param>
        /// <returns></returns>
        public CODEVIEW_HEADER ExtractCVDebug(MemSection sec)
        {
            uint SizeData = 0, RawData = 0, PointerToRawData = 0;

            Extract Ext = sec.Module;
            long    VA  = sec.VA.Address;

            var _va       = VA + Ext.DebugDirPos;
            var block     = VGetBlock(_va);
            var TimeDate2 = BitConverter.ToUInt32(block, ((int)Ext.DebugDirPos & 0xfff) + 4);

            if (TimeDate2 != Ext.TimeStamp & Vtero.VerboseOutput)
            {
                WriteColor(ConsoleColor.Yellow, "Unable to lock on to CV data.");
                return(null);
            }

            var max_offset = (int)(_va & 0xfff) + 28;

            if (max_offset > 0x1000)
            {
                return(null);
            }

            SizeData         = BitConverter.ToUInt32(block, (int)(_va & 0xfff) + 16);
            RawData          = BitConverter.ToUInt32(block, (int)(_va & 0xfff) + 20);
            PointerToRawData = BitConverter.ToUInt32(block, (int)(_va & 0xfff) + 24);

            _va = VA + RawData;

            var bytes = new byte[16];

            block = VGetBlock(_va);

            // first 4 bytes
            var sig = block[((int)_va & 0xfff)];

            Array.ConstrainedCopy(block, (((int)_va & 0xfff) + 4), bytes, 0, 16);
            var gid = new Guid(bytes);

            // after GUID
            var age = block[((int)_va & 0xfff) + 20];

            // char* at end
            var str = Encoding.Default.GetString(block, (((int)_va & 0xfff) + 24), 32).Trim();
            var cv  = new CODEVIEW_HEADER {
                VSize = (int)Ext.SizeOfImage, TimeDateStamp = TimeDate2, byteGuid = bytes, Age = age, aGuid = gid, Sig = sig, PdbName = str
            };

            sec.Name         = str.Substring(0, str.IndexOf('.')).ToLower();
            sec.DebugDetails = cv;

            return(cv);
        }
Beispiel #5
0
        /// <summary>
        ///  This guy names the section and establishes the codeview data needed for symbol handling
        /// </summary>
        /// <param name="sec"></param>
        /// <returns></returns>
        public CODEVIEW_HEADER ExtractCVDebug(MemSection sec)
        {
            uint SizeData = 0, RawData = 0, PointerToRawData = 0;

            Extract Ext = sec.Module;
            long    VA  = sec.VA.Address;

            var _va   = VA + Ext.DebugDirPos;
            var block = GetVirtualByte(_va);

            var TimeDate2 = BitConverter.ToUInt32(block, 4);

            if (TimeDate2 != Ext.TimeStamp & Vtero.VerboseOutput)
            {
                WriteColor(ConsoleColor.Yellow, "Unable to lock on to CV data.");
                return(null);
            }

            SizeData         = BitConverter.ToUInt32(block, 16);
            RawData          = BitConverter.ToUInt32(block, 20);
            PointerToRawData = BitConverter.ToUInt32(block, 24);

            // Advance to the debug section where we may find the code view info
            _va = VA + RawData;
            var b2     = GetVirtualByte(_va);
            var bytes2 = new byte[16];
            var s2     = b2[0];

            Array.ConstrainedCopy(b2, 4, bytes2, 0, 16);
            var gid2 = new Guid(bytes2);
            // after GUID
            var age2 = b2[20];

            // char* at end
            var str2 = Encoding.Default.GetString(b2, 24, 32).Trim();
            var cv2  = new CODEVIEW_HEADER {
                VSize = (int)Ext.SizeOfImage, TimeDateStamp = TimeDate2, byteGuid = bytes2, Age = age2, aGuid = gid2, Sig = s2, PdbName = str2
            };

            if (str2.Contains(".") && str2.Contains(".pdb"))
            {
                sec.Name = str2.Substring(0, str2.IndexOf(".pdb") + 4).ToLower();
            }
            else
            {
                sec.Name = str2.ToLower();
            }
            sec.DebugDetails = cv2;
            return(cv2);
        }
Beispiel #6
0
 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}]");
             }
         }
     }
 }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        // TODO: MOVE below to DetectedProc class

        public CODEVIEW_HEADER ExtractCVDebug(DetectedProc dp, MemSection sec)
        {
             uint SizeData=0, RawData=0, PointerToRawData=0;

            Extract Ext = sec.Module;
            long VA = sec.VA.Address;

            if (dp.MemAccess == null)
                dp.MemAccess = new Mem(MemAccess);

            var _va = VA + Ext.DebugDirPos;
            var block = dp.VGetBlock(_va);
            var TimeDate2 = BitConverter.ToUInt32(block, ((int) Ext.DebugDirPos & 0xfff) + 4);

            if(TimeDate2 != Ext.TimeStamp & Vtero.VerboseOutput)
            {
                WriteColor(ConsoleColor.Yellow, "Unable to lock on to CV data.");
                return null; 
            }

            if(Vtero.VerboseOutput)
                WriteColor(ConsoleColor.Green, $"Locked on to CV Debug info.  Time2 = {TimeDate2:X} Time1 = {Ext.TimeStamp:X}");

            var max_offset = (int)(_va & 0xfff) + 28;
            if (max_offset > 0x1000)
            {
                if (Vtero.VerboseOutput)
                    WriteColor(ConsoleColor.Yellow, "CV block seems too straddle into next block (too large)"); return null;
            }
            SizeData = BitConverter.ToUInt32(block, (int)(_va & 0xfff) + 16);
            RawData = BitConverter.ToUInt32(block, (int)(_va & 0xfff) + 20);
            PointerToRawData = BitConverter.ToUInt32(block, (int)(_va & 0xfff) + 24);

            _va = VA + RawData;

            var bytes = new byte[16];

            block = dp.VGetBlock(_va);

            // first 4 bytes
            var sig = block[((int)_va & 0xfff)];
            
            Array.ConstrainedCopy(block, (((int) _va & 0xfff) + 4), bytes, 0, 16);
            var gid = new Guid(bytes);

            // after GUID
            var age = block[((int)_va & 0xfff) + 20];

            // char* at end
            var str = Encoding.Default.GetString(block, (((int)_va & 0xfff) + 24), 32).Trim();

            if (Vtero.VerboseOutput)
            {
                WriteLine($"Size = {SizeData} \t Raw = {RawData} \t Pointer {PointerToRawData}");
                WriteLine($"Str {str} : GUID : {gid} : AGE {age}");
            }

            var cv = new CODEVIEW_HEADER { VSize = (int) Ext.SizeOfImage, TimeDateStamp = TimeDate2, byteGuid = bytes, Age = age, aGuid = gid, Sig = sig, PdbName = str };

            sec.DebugDetails = cv;

            return cv;
        }