Exemple #1
0
        /// <summary>
        /// Get a defined type from the symbol API (e.g. _EPROCESS)
        /// After the first call this is all cached staticlly
        ///
        /// WARNING!!! This means you need to reload every memory dump you're looking at
        /// TODO: Make this instance specific per-vtero
        /// </summary>
        /// <param name="TypeName"></param>
        /// <param name="cv"></param>
        /// <returns></returns>
        public static dynamic GetType(string TypeName, CODEVIEW_HEADER cv = null)
        {
            if (_dyn_cache.TryGetValue(TypeName, out Tuple <String, ExpandoObject> cachedVersion))
            {
                return(cachedVersion.Item2.DeepCopy());
            }

            var json = TypeDef(TypeName, cv);
            var dyn  = JsonConvert.DeserializeObject <List <ExpandoObject> >(json.Result, converter).First();

            _dyn_cache.TryAdd(TypeName, Tuple.Create(json.Result, dyn));

            return(dyn.DeepCopy());
        }
Exemple #2
0
        public static CODEVIEW_HEADER Init(
            string name      = null,
            string pdb       = null,
            string symname   = null,
            string symaddr   = null,
            string typename  = null,
            string baseva    = null,
            string vsize     = null,
            string symrange  = null,
            string age       = null,
            string sig       = null,
            string timestamp = null,
            string guid      = null
            )
        {
            bool parsed = false;
            var  cv     = new CODEVIEW_HEADER();

            if (name.Contains(".."))
            {
                return(null);
            }
            if (pdb.Contains(".."))
            {
                return(null);
            }

            if (!string.IsNullOrWhiteSpace(pdb) && pdb.Any((x) => char.IsSurrogate(x) || char.IsSymbol(x) || char.IsControl(x) || x == Path.DirectorySeparatorChar || x == Path.AltDirectorySeparatorChar || x == Path.VolumeSeparatorChar || x == Path.PathSeparator))
            {
                return(null);
            }
            if (!string.IsNullOrWhiteSpace(name) && name.Any((x) => char.IsSurrogate(x) || char.IsSymbol(x) || char.IsControl(x) || x == Path.DirectorySeparatorChar || x == Path.AltDirectorySeparatorChar || x == Path.VolumeSeparatorChar || x == Path.PathSeparator))
            {
                return(null);
            }

            cv.Name          = name;
            cv.PdbName       = pdb;
            cv.Type          = typename;
            cv.SymName       = symname;
            cv.BaseVA        = ParseUlong(baseva, ref parsed);
            cv.SymAddr       = ParseUlong(symaddr, ref parsed);
            cv.VSize         = ParseUint(vsize, ref parsed);
            cv.SymRange      = ParseUint(symrange, ref parsed);
            cv.Age           = ParseUint(age, ref parsed);
            cv.Sig           = ParseUint(sig, ref parsed);
            cv.TimeDateStamp = ParseUint(timestamp, ref parsed);
            Guid.TryParse(guid, out cv.aGuid);
            return(cv);
        }
Exemple #3
0
        public static CODEVIEW_HEADER Init(
            string name      = null,
            string pdb       = null,
            string symaddr   = null,
            string typename  = null,
            string baseva    = null,
            string vsize     = null,
            string age       = null,
            string sig       = null,
            string timestamp = null,
            string guid      = null
            )
        {
            bool parsed = false;
            var  cv     = new CODEVIEW_HEADER();

            cv.Name    = name;
            cv.PdbName = pdb;
            cv.Type    = typename;

            if (!string.IsNullOrWhiteSpace(baseva))
            {
                cv.BaseVA = ParseUlong(baseva, ref parsed);
            }
            if (!string.IsNullOrWhiteSpace(symaddr))
            {
                cv.SymAddr = ParseUlong(symaddr, ref parsed);
            }
            if (!string.IsNullOrWhiteSpace(vsize))
            {
                cv.VSize = ParseUint(vsize, ref parsed);
            }
            if (!string.IsNullOrWhiteSpace(age))
            {
                cv.Age = ParseUint(age, ref parsed);
            }
            if (!string.IsNullOrWhiteSpace(sig))
            {
                cv.Sig = ParseUint(sig, ref parsed);
            }
            if (!string.IsNullOrWhiteSpace(timestamp))
            {
                cv.TimeDateStamp = ParseUint(timestamp, ref parsed);
            }
            if (!string.IsNullOrWhiteSpace(guid))
            {
                cv.aGuid = Guid.Parse(guid);
            }
            return(cv);
        }
Exemple #4
0
        public static SYMBOL_INFO SymFromName(string name, CODEVIEW_HEADER cvh)
        {
            SYMBOL_INFO rv = new SYMBOL_INFO();

            var json  = SymAPI.FromName(name, cvh);
            var names = JsonConvert.DeserializeObject <NameList>(json.Result);

            if (names == null)
            {
                return(rv);
            }

            var first = names.Names.First();

            rv.Address = first.Address;
            rv.Size    = (uint)first.Length;
            rv.Name    = first.Name;

            return(rv);
        }
Exemple #5
0
 public async static Task <string> FromAddress(string address, CODEVIEW_HEADER cvh) => await GET($"SymFromName/x?symaddr={address}&guid={cvh.aGuid:N}&age={cvh.Age:X1}&PDB={cvh.PdbName}&baseva={cvh.BaseVA}");
Exemple #6
0
 public async static Task <string> TypeDef(string name, CODEVIEW_HEADER cvh) => await GET($"typedef/x?type={name}&guid={cvh.aGuid:N}&age={cvh.Age:X1}&PDB={cvh.PdbName}&baseva={cvh.BaseVA}");
Exemple #7
0
        /// <summary>
        /// Origionally this tended to be a lot faster than dynamically parsing this out of expando's
        /// </summary>
        /// <param name="TypeName">_EPROCESS or something that is contained by the passed in CV or is cached</param>
        /// <param name="cv">required for first time for a given type</param>
        /// <returns>Dictionary that represents length and offset_of for all defined struct fields (except bitfields)</returns>
        public static Dictionary <string, Tuple <int, int> > GetTypeOffsets(string TypeName, CODEVIEW_HEADER cv = null)
        {
            Dictionary <string, Tuple <int, int> > rv = new Dictionary <string, Tuple <int, int> >();
            var str = GetTypeString(TypeName, cv);

            JsonTextReader reader = new JsonTextReader(new StringReader(str));
            String         Name = string.Empty;
            int            Length = 0, Pos = 0;

            // the first entry is a bit different format
            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    if (reader.Value.Equals("TypeName"))
                    {
                        Name = reader.ReadAsString();
                    }
                    reader.Read();
                    Length = reader.ReadAsInt32() ?? 0;
                    rv.Add(Name, Tuple.Create(0, Length));
                    break;
                }
            }

            // after the first entry we have a fairly consistant format of entries (tag is skipped between name & pos)
            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    if (reader.Value.Equals("MemberName"))
                    {
                        Name = reader.ReadAsString();
                        do
                        {
                            reader.Read();
                        } while (reader.TokenType != JsonToken.PropertyName);
                        do
                        {
                            reader.Read();
                        } while (reader.TokenType != JsonToken.PropertyName);
                        Pos = reader.ReadAsInt32() ?? 0;
                        do
                        {
                            reader.Read();
                        } while (reader.TokenType != JsonToken.PropertyName);
                        Length = reader.ReadAsInt32() ?? 0;
                        rv.Add(Name, Tuple.Create(Pos, Length));
                    }
                }
            }
            return(rv);
        }
Exemple #8
0
 // where the bindings all get originated
 public Dia3(CODEVIEW_HEADER cvh)
 {
     CV = cvh;
 }
Exemple #9
0
 public DiaSymbol(CODEVIEW_HEADER cv) : this()
 {
     CV = cv;
 }
Exemple #10
0
 public DiaSource(CODEVIEW_HEADER cv) : this()
 {
     CV = cv;
 }
Exemple #11
0
 public DiaSession(CODEVIEW_HEADER cv)
 {
     CV = cv;
 }
Exemple #12
0
        /// <summary>
        /// Perform full symbol walk scanning for a struct/member position and length
        ///
        /// TODO: make safe for type collisions in other pdb's
        /// </summary>
        /// <param name="PDBFile">d:\dev\symbols\ntkrnlmp.pdb\DD08DD42692B43F199A079D60E79D2171\ntkrnlmp.pdb</param>
        /// <param name="Struct">_EPROCESS</param>
        /// <param name="Member">Pcb.DirectoryTableBase</param>
        /// <returns>Tuple of Position & Length </returns>

        public static Tuple <int, int> StructMemberInfo(CODEVIEW_HEADER cv, string Struct, string Member)
        {
#if !NETSTANDARD2_0
            IDiaSession     Session;
            IDiaSymbol      Master         = null;
            IDiaEnumSymbols EnumSymbols    = null;
            uint            compileFetched = 0;

            var result = from symx in StructInfo
                         where symx.Key.EndsWith(Member)
                         select symx;

            if (result.Count() > 0)
            {
                return(result.First().Value);
            }
#endif

#if NETSTANDARD2_0
            IDictionary <string, dynamic> dInfo = null;
            dynamic memberInfo = null;
            var     cnt        = Member.Split('.').Length;

            var typeInfo = SymAPI.GetType(Struct, cv);

            dInfo = typeInfo as IDictionary <string, dynamic>;
            if (cnt == 1)
            {
                memberInfo = dInfo[Member];
            }
            else
            {
                for (int i = 0; i < cnt; i++)
                {
                    var path = Member.Split('.')[i];

                    dInfo      = typeInfo as IDictionary <string, dynamic>;
                    memberInfo = dInfo[path];

                    if (i < cnt)
                    {
                        typeInfo = memberInfo;
                    }
                }
            }

            dInfo = memberInfo as IDictionary <string, dynamic>;
            return(Tuple.Create((int)dInfo["OffsetPos"], (int)dInfo["Length"]));

            /* bah, screw this just return the object :\
             * var foo = new DiaSource(cv);
             * foo.loadDataFromPdb(cv.PDBFullPath);
             * foo.openSession(out Session);
             */
#else
            var foo = new DiaSource();
            foo.loadDataFromPdb(cv.PDBFullPath);
            foo.openSession(out Session);
            if (Session == null)
            {
                return(null);
            }
            Session.findChildren(Session.globalScope, (uint)DebugHelp.SymTagEnum.Null, Struct, 0, out EnumSymbols);
            do
            {
                EnumSymbols.Next(1, out Master, out compileFetched);
                if (Master == null)
                {
                    continue;
                }
#if DEBUGX
                Console.ForegroundColor = ConsoleColor.White;
                WriteLine($"Dumping Type [{Master.name}] Len [{Master.length}]");
#endif
                if (!StructInfo.ContainsKey(Master.name))
                {
                    StructInfo.Add(Master.name, Tuple.Create <int, int>(0, (int)Master.length));
                }

                DumpStructs(Master, Master.name, Struct, 0);
            } while (compileFetched == 1);

            var resultx = (from symx in StructInfo
                           where symx.Key.EndsWith(Member)
                           select symx).FirstOrDefault();

            return(resultx.Value);
#endif
        }
Exemple #13
0
        /// <summary>
        /// We use sympath environment variable
        /// </summary>
        /// <param name="cv_data"></param>
        /// <param name="BaseVA"></param>
        /// <param name="SymPath"></param>
        /// <returns></returns>
        public static bool TryLoadSymbols(long Handle, CODEVIEW_HEADER cv_data, ulong BaseVA, bool Verbose = false)
        {
#if NETSTANDARD2_0
            cv_data.PDBFullPath = $"NET_BINDING-{cv_data}";
            return(true);
#else
            var symStatus = false;
            if (string.IsNullOrWhiteSpace(cv_data.PdbName))
            {
                return(symStatus);
            }

            var sym = Sym.Initalize(Handle, null, DebugHelp.SymOptions.SYMOPT_UNDNAME);

            if (!sym && Verbose)
            {
                Sym.Errors.Enqueue($"Can not initialize symbols for ${Handle}, error:  {new Win32Exception(Marshal.GetLastWin32Error()).Message }");
            }


            StringBuilder sbx    = new StringBuilder(1024);
            StringBuilder sbName = new StringBuilder(cv_data.PdbName.Substring(0, cv_data.PdbName.IndexOf(".pdb") + 4));

            uint three = 0;
            var  flags = DebugHelp.SSRVOPT_GUIDPTR;
            symStatus = DebugHelp.SymFindFileInPathW(Handle, null, sbName, ref cv_data.aGuid, cv_data.Age, three, flags, sbx, IntPtr.Zero, IntPtr.Zero);
            //// try twice, just in case
            if (!symStatus)
            {
                symStatus = DebugHelp.SymFindFileInPathW(Handle, null, sbName, ref cv_data.aGuid, cv_data.Age, three, flags, sbx, IntPtr.Zero, IntPtr.Zero);
            }

            if (!symStatus)
            {
                if (Verbose)
                {
                    Sym.Errors.Enqueue($" Symbol locate returned {symStatus}: {new Win32Exception(Marshal.GetLastWin32Error()).Message }, attempting less precise request.");
                }

                flags = DebugHelp.SSRVOPT_DWORDPTR;
                var      refBytes    = BitConverter.GetBytes(cv_data.TimeDateStamp);
                GCHandle pinnedArray = GCHandle.Alloc(refBytes, GCHandleType.Pinned);
                IntPtr   pointer     = pinnedArray.AddrOfPinnedObject();

                symStatus = DebugHelp.SymFindFileInPathW(Handle, null, sbName, pointer, cv_data.VSize, three, flags, sbx, IntPtr.Zero, IntPtr.Zero);
                pinnedArray.Free();
                if (!symStatus && Verbose)
                {
                    Sym.Errors.Enqueue($" Find Symbols returned value: {symStatus}:[{sbx.ToString()}]");
                }
            }
            if (symStatus)
            {
                var symLoaded = DebugHelp.SymLoadModuleEx(Handle, IntPtr.Zero, sbx.ToString(), null, BaseVA, cv_data.VSize, IntPtr.Zero, 0);
                if (symLoaded == 0 && Verbose)
                {
                    Sym.Errors.Enqueue($"Symbols file located @ {sbx.ToString()} yet load Failed: [{new Win32Exception(Marshal.GetLastWin32Error()).Message }]");
                }

                cv_data.PDBFullPath = sbx.ToString();
            }

            return(symStatus);
#endif
        }