Beispiel #1
0
        public static dynamic xStructInfo(
            string PDBFile,
            string Struct,
            long vAddress  = 0,
            long[] memRead = null,
            Func <long, int, byte[]> GetMem            = null,
            Func <long, int, long[]> GetMemLong        = null,
            PropertyChangedEventHandler ExpandoChanged = null
            )
        {
            dynamic         Info        = null;
            IDiaSymbol      Master      = null;
            IDiaEnumSymbols EnumSymbols = null;
            IDiaSession     Session;
            uint            compileFetched = 0;

            var foo = new DiaSource();

            foo.loadDataFromPdb(PDBFile);
            foo.openSession(out Session);
            if (Session == null)
            {
                return(null);
            }

            Session.loadAddress = (ulong)vAddress;

            // 10 is regex
            Session.globalScope.findChildren(
                SymTagEnum.SymTagUDT
                ,
                Struct, 10, 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
                Info          = new ExpandoObject();
                Info.TypeName = Master.name;
                Info.Length   = Master.length;
                Info.vAddress = vAddress;

                //StructInfo.Add(Master.name, Info); // Tuple.Create<int, int>(0, (int)Master.length));
                xDumpStructs(Info, Master, Master.name, 0, vAddress, memRead, GetMem, GetMemLong, ExpandoChanged);

                if (ExpandoChanged != null)
                {
                    ((INotifyPropertyChanged)Info).PropertyChanged +=
                        new PropertyChangedEventHandler(ExpandoChanged);
                }
            } while (compileFetched == 1);

            return(Info);
        }
Beispiel #2
0
        void ClassCollectSym(IDiaSymbol Detail)
        {
            IDiaEnumSymbols EnumSymbols     = null;
            IDiaSymbol      Symbol          = null;
            List <string>   Args            = new List <string>();
            uint            childrenFetched = 0;

            ForegroundColor = ConsoleColor.Yellow;

            if (Detail == null || string.IsNullOrWhiteSpace(Detail.name))
            {
                return;
            }

            //WriteLine($"{Detail.undecoratedName} ({Detail.name}) Length: {Detail.length} RVA: {Detail.targetRelativeVirtualAddress} VA: {Detail.targetVirtualAddress}");

            Detail.findChildren(SymTagEnum.SymTagNull, null, 0, out EnumSymbols);
            do
            {
                EnumSymbols.Next(1, out Symbol, out childrenFetched);
                if (Symbol == null || string.IsNullOrEmpty(Symbol.name))
                {
                    continue;
                }

                if (Symbol.type != null)
                {
                    Args.Add(Symbol.type.name);
                }
                //  else
                //      WriteLine($"{Symbol.undecoratedName} ({Symbol.name}) @ {Symbol.virtualAddress:X} Length: {Symbol.length} ");
            } while (childrenFetched == 1);
        }
Beispiel #3
0
        private IEnumerable <Symbol> CreateChildrenImpl(SymTagEnum symbolTagType, string symbolName, NameSearchOptions searchOptions)
        {
            IDiaEnumSymbols enumSymbols = null;

            try
            {
                _sym.findChildren(symbolTagType, symbolName, (uint)searchOptions, out enumSymbols);
                if (enumSymbols == null)
                {
                    yield break;
                }

                while (true)
                {
                    uint       celt = 0;
                    IDiaSymbol symbol;
                    enumSymbols.Next(1, out symbol, out celt);
                    if (celt != 1)
                    {
                        break;            //No more symbols
                    }
                    yield return(Symbol.Create(symbol));
                }
            }
            finally
            {
                if (enumSymbols != null)
                {
                    Marshal.ReleaseComObject(enumSymbols);
                }
            }
        }
Beispiel #4
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 Tuple <int, int> StructMemberInfo(string PDBFile, string Struct, string Member)
        {
            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);
            }

            var foo = new DiaSource();

            foo.loadDataFromPdb(PDBFile);
            foo.openSession(out Session);
            if (Session == null)
            {
                return(null);
            }

            Session.findChildren(Session.globalScope, SymTagEnum.SymTagNull, 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);
        }
Beispiel #5
0
        public List <Tuple <String, ulong, ulong> > MatchSyms(String Match, String PDBFile, ulong LoadAddr = 0)
        {
            List <Tuple <String, ulong, ulong> > rv = new List <Tuple <string, ulong, ulong> >();
            IDiaSession     Session;
            IDiaEnumSymbols EnumSymbols    = null;
            IDiaSymbol      Master         = null;
            uint            compileFetched = 0;

            var foo = new DiaSource();

            foo.loadDataFromPdb(PDBFile);
            foo.openSession(out Session);
            if (Session == null)
            {
                return(rv);
            }
            // 10 is regex
            Session.globalScope.findChildren(SymTagEnum.SymTagNull, Match, 10, out EnumSymbols);

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

            Session.loadAddress = LoadAddr;

            var GlobalScope = Session.globalScope;

            var tot = EnumSymbols.count;

            do
            {
                EnumSymbols.Next(1, out Master, out compileFetched);
                if (Master == null)
                {
                    continue;
                }

                var len = Master.length;

                rv.Add(Tuple.Create <String, ulong, ulong>(Master.name, Master.virtualAddress, len));
#if DEBUGX
                ForegroundColor = ConsoleColor.White;
                WriteLine($"Name = [{Master.name}] VA = {Master.virtualAddress}");
#endif
            } while (compileFetched == 1);

            return(rv);
        }
Beispiel #6
0
        /// <summary>
        /// Converts <see cref="IDiaEnumSymbols"/> container to <see cref="IEnumerable{IDiaSymbol}"/>.
        /// </summary>
        /// <param name="container">The container.</param>
        public static IEnumerable <IDiaSymbol> Enum(this IDiaEnumSymbols container)
        {
            IDiaSymbol[] tempSymbols = new IDiaSymbol[1];
            container.Reset();
            while (true)
            {
                uint count;

                container.Next((uint)tempSymbols.Length, tempSymbols, out count);
                if (count == 0)
                {
                    break;
                }
                yield return(tempSymbols[0]);
            }
        }
Beispiel #7
0
    private DiaSymbol GetValidPublicSymbolEntry(String name)
    {
        IDiaEnumSymbols e = df.FindPublicSymbols(name);

        if (e.count != 1)
        {
            return(null);
        }
        else
        {
            IDiaSymbol s;
            UInt32     celt;

            e.Next(1, out s, out celt);
            return(new DiaSymbol(s));
        }
    }
Beispiel #8
0
        public dynamic xStructInfo(string PDBFile, string Struct, long[] memRead = null)
        {
            dynamic         Info        = null;
            IDiaSymbol      Master      = null;
            IDiaEnumSymbols EnumSymbols = null;
            IDiaSession     Session;
            uint            compileFetched = 0;

            var foo = new DiaSource();

            foo.loadDataFromPdb(PDBFile);
            foo.openSession(out Session);
            if (Session == null)
            {
                return(null);
            }
            // 10 is regex
            Session.globalScope.findChildren(SymTagEnum.SymTagNull, Struct, 10, 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
                Info          = new ExpandoObject();
                Info.TypeName = Master.name;
                Info.Length   = Master.length;
                //StructInfo.Add(Master.name, Info); // Tuple.Create<int, int>(0, (int)Master.length));

                xDumpStructs(Info, Master, Master.name, 0, memRead);
            } while (compileFetched == 1);

            return(Info);
        }
Beispiel #9
0
        void DumpStructs(IDiaSymbol Master, string preName, string Search, int CurrOffset)
        {
            IDiaSymbol      Sub            = null;
            IDiaEnumSymbols Enum2          = null;
            uint            compileFetched = 0;

            Master.findChildren(SymTagEnum.SymTagNull, null, 0, out Enum2);
            do
            {
                if (Enum2 == null)
                {
                    break;
                }

                Enum2.Next(1, out Sub, out compileFetched);
                if (Sub == null)
                {
                    continue;
                }

                var sType    = Sub.type;
                var typeName = sType.name;
                var currName = $"{preName}.{Sub.name}";
                int Pos      = CurrOffset + Sub.offset;

#if DEBUGX
                ForegroundColor = ConsoleColor.Cyan;
                WriteLine($"Pos = [{Pos}] Name = [{currName}] Len [{sType.length}], Type [{typeName}]");
#endif
                if (!StructInfo.ContainsKey(currName))
                {
                    StructInfo.Add(currName, Tuple.Create <int, int>(Pos, (int)sType.length));
                }
                DumpStructs(sType, currName, typeName, Pos);
            } while (compileFetched == 1);
        }
Beispiel #10
0
        /// <summary>
        /// Method for native type reflection into DLR
        /// TODO: Perf check + handle .Dictionary references
        /// </summary>
        /// <param name="Info"></param>
        /// <param name="Master"></param>
        /// <param name="preName"></param>
        /// <param name="CurrOffset"></param>
        /// <param name="memRead"></param>
        /// <returns></returns>
        dynamic xDumpStructs(dynamic Info, IDiaSymbol Master, string preName, int CurrOffset, long[] memRead = null, Func <long, byte[]> GetMem = null, Func <long, long[]> GetMemLong = null)
        {
            var IInfo    = (IDictionary <string, object>)Info;
            var InfoDict = new Dictionary <string, object>();

            Info.Dictionary = InfoDict;
            long lvalue = 0;


            IDiaSymbol      Sub            = null;
            IDiaEnumSymbols Enum2          = null;
            uint            compileFetched = 0;

            Master.findChildren(SymTagEnum.SymTagNull, null, 10, out Enum2);
            do
            {
                if (Enum2 == null)
                {
                    break;
                }

                Enum2.Next(1, out Sub, out compileFetched);
                if (Sub == null)
                {
                    continue;
                }

                dynamic zym        = new ExpandoObject();
                var     Izym       = (IDictionary <string, object>)zym;
                var     staticDict = new Dictionary <string, object>();
                zym.Dictionary = staticDict;

                var master   = zym.InstanceName = Master.name;
                var sType    = Sub.type;
                var typeName = zym.TypeName = sType.name;
                var currName = zym.MemberName = $"{preName}.{Sub.name}";
                int Pos      = CurrOffset + Sub.offset;

                zym.Tag       = (SymTagEnum)Sub.symTag;
                zym.Length    = sType.length;
                zym.OffsetPos = Pos;

                bool KeepRecur = true;

                if (memRead != null)
                {
                    var defName = "Value";
                    lvalue = memRead == null ? 0 : memRead[Pos / 8];

                    // TODO: Handles/OBJECT_FOO/_ETC...

                    if (String.Equals("_UNICODE_STRING", typeName) && GetMem != null)
                    {
                        // since we deref'd this struct manually don't follow
                        KeepRecur = false;
                        string strVal     = "";
                        var    DataOffset = (Pos + 8) / 8;
                        // get address from our offset
                        var StringAddr = memRead[DataOffset];
                        if (StringAddr != 0)
                        {
                            var strByteArr = GetMem(StringAddr);
                            var strLen     = (short)lvalue & 0xffff;
                            if (strLen > strByteArr.Length / 2 || strLen <= 0)
                            {
                                strLen = strByteArr.Length / 2;
                            }
                            strVal = Encoding.Unicode.GetString(strByteArr, 0, strLen);
                        }
                        Izym.Add(defName, strVal);
                        staticDict.Add(currName, lvalue);
                    }
                    else
                    {
                        // bittable types
                        // TODO: GUID
                        // 6 is a bitfield
                        if (Sub.locationType == 6)
                        {
                            zym.BitPosition = Sub.bitPosition;

                            var mask = 1U;
                            for (int x = (int)sType.length - 1; x > 0; x--)
                            {
                                mask  = mask << 1;
                                mask |= 1;
                            }
                            var new_mask = mask << (int)Sub.bitPosition;

                            lvalue &= new_mask;

                            // move lvalue to bitposition 0
                            // saves having todo this every time we evaluate Value
                            lvalue = lvalue >> (int)Sub.bitPosition;
                        }
                        else
                        {
                            switch (sType.length)
                            {
                            case 4:
                                lvalue = (int)lvalue & 0xffffffffff;
                                break;

                            case 2:
                                lvalue = (short)lvalue & 0xffffff;
                                break;

                            case 1:
                                lvalue = (byte)lvalue & 0xff;
                                break;

                            default:
                                break;
                            }
                        }
                        Izym.Add(defName, lvalue);
                        staticDict.Add(currName, lvalue);
                    }
                }

                // This is a pointer really, so type.type... of course!
                if (KeepRecur)
                {
                    var TypeType    = sType.type;
                    var TypeTypeTag = sType.symTag;
                    if ((SymTagEnum)TypeTypeTag == SymTagEnum.SymTagPointerType)
                    {
                        zym.IsPtr = true;
                        if (TypeType != null && !string.IsNullOrWhiteSpace(TypeType.name))
                        {
                            zym.PtrTypeName = TypeType.name;

                            // only recuse non-recursive ptr types
                            if (TypeType.name.Equals("_OBJECT_NAME_INFORMATION"))
                            {
                                // do second deref here
                                // the location to read is our offset pos data
                                var deRefArr = GetMemLong(lvalue);


                                xDumpStructs(zym, TypeType, currName, 0, deRefArr, GetMem, GetMemLong);
                            }
                        }
                    }
                    else
                    {
                        xDumpStructs(zym, sType, currName, Pos, memRead, GetMem, GetMemLong);
                    }
                }
#if DEBUGX
                ForegroundColor = ConsoleColor.Cyan;
                WriteLine($"Pos = [{Pos:X}] Name = [{currName}] Len [{sType.length}], Type [{typeName}], ThisStruct [{master}]");
#endif
                // Length comes up a lot in struct's and conflicts with the ExpandoObject
                // so remap it specially
                var AddedName = Sub.name;
                if (AddedName.ToLower().Equals("value"))
                {
                    AddedName = "ValueMember";
                }
                if (AddedName.ToLower().Equals("length"))
                {
                    AddedName = "LengthMember";
                }
                if (IInfo.ContainsKey(AddedName))
                {
                    continue;
                }
                IInfo.Add(AddedName, zym);
                InfoDict.Add(AddedName, lvalue);
            } while (compileFetched == 1);
            return(null);
        }
Beispiel #11
0
        private IDiaSymbol GetMethodSymbol(IDiaSymbol typeSymbol, string methodName)
        {
            ValidateArg.NotNull(typeSymbol, "typeSymbol");
            ValidateArg.NotNullOrEmpty(methodName, "methodName");

            IDiaEnumSymbols enumSymbols  = null;
            IDiaSymbol      methodSymbol = null;
            Dictionary <string, IDiaSymbol> methodSymbolsForType;

            try
            {
                if (this.methodSymbols.ContainsKey(typeSymbol.name))
                {
                    methodSymbolsForType = this.methodSymbols[typeSymbol.name];
                    if (methodSymbolsForType.ContainsKey(methodName))
                    {
                        return(methodSymbolsForType[methodName]);
                    }
                }
                else
                {
                    methodSymbolsForType = new Dictionary <string, IDiaSymbol>();
                    this.methodSymbols[typeSymbol.name] = methodSymbolsForType;
                }

                typeSymbol.findChildren(SymTagEnum.SymTagFunction, methodName, 0, out enumSymbols);

                uint celtFetched;
                enumSymbols.Next(1, out methodSymbol, out celtFetched);

#if DEBUG
                if (methodSymbol == null)
                {
                    IDiaEnumSymbols enumAllSymbols = null;
                    try
                    {
                        typeSymbol.findChildren(SymTagEnum.SymTagFunction, null, 0, out enumAllSymbols);
                        List <string> children = new List <string>();

                        IDiaSymbol childSymbol  = null;
                        uint       fetchedCount = 0;
                        while (true)
                        {
                            enumAllSymbols.Next(1, out childSymbol, out fetchedCount);
                            if (fetchedCount == 0 || childSymbol == null)
                            {
                                break;
                            }

                            children.Add(childSymbol.name);
                            ReleaseComObject(ref childSymbol);
                        }

                        Debug.Assert(children.Count > 0);
                    }
                    finally
                    {
                        ReleaseComObject(ref enumAllSymbols);
                    }
                }
#endif
            }
            finally
            {
                ReleaseComObject(ref enumSymbols);
            }

            if (null != methodSymbol)
            {
                methodSymbolsForType[methodName] = methodSymbol;
            }

            return(methodSymbol);
        }
Beispiel #12
0
        public int Enum(string arg)
        {
            IDiaEnumSymbols EnumSymbols    = null;
            IDiaSymbol      Master         = null;
            IDiaEnumTables  tables         = null;
            int             level          = 2;
            uint            compileFetched = 0;

            //DebugHelp.SymFindDebugInfoFile(hCurrentProcess, SymPath, arg, )

            var foo = new Dia2Lib.DiaSource();

            foo.loadDataForExe(arg, SymPath, null);
            //foo.loadDataFromPdb(arg);
            foo.openSession(out Session);

            if (Session == null)
            {
                return(-1);
            }

            Session.loadAddress = 0;
            uint rva = 0;

            //do
            //{
            //    try
            //    {
            //        Session.findChildren(Session.globalScope, SymTagEnum.SymTagNull, null, 0, out EnumSymbols);
            //        var tot1 = EnumSymbols.count;
            //        uint curr1 = 0;
            //        do
            //        {
            //            EnumSymbols.Next(1, out Master, out compileFetched);
            //            if (Master == null)
            //                continue;

            //            ForegroundColor = ConsoleColor.White;

            //            foreach (var pr in typeof(IDiaSymbol).LinqPublicProperties())
            //            {
            //                WriteLine($"{pr.Name} = {pr.GetValue(Master)}");
            //            }

            //            //foreach (var fn in typeof(IDiaSymbol).LinqPublicFunctions())
            //            //{
            //            //    //if (fn.Name.Contains("get"))
            //            //        WriteLine($"{fn.Name} = {fn.Invoke(Master, null)}");
            //            //}
            //            // DumpSymbol<IDiaSymbol>(Master, ref level);

            //        } while (curr1++ < tot1);



            //        //foreach (var pr in typeof(IDiaSymbol).LinqPublicProperties())
            //        //    WriteLine($"{pr.Name} = {pr.GetValue(Master)}");
            //    }
            //    catch { }
            //    finally
            //    {
            //        if (Master != null)
            //            rva += (uint)(Master.length == 0 ? 1 : Master.length);
            //    }

            //} while (Master != null);



            var GlobalScope = Session.globalScope;

            IDiaEnumDebugStreams DebugStreams;

            Session.getEnumDebugStreams(out DebugStreams);
            for (int i = 0; i < DebugStreams.count; i++)
            {
                var ds = DebugStreams.Item(i);
                foreach (var pr in typeof(IDiaEnumDebugStreamData).LinqPublicProperties())
                {
                    WriteLine($"{pr.Name} = {pr.GetValue(ds)}");
                }
            }

            Session.getEnumTables(out tables);
            for (int i = 0; i < tables.count; i++)
            {
                var ds = tables.Item(i);
                foreach (var pr in typeof(IDiaTable).LinqPublicProperties())
                {
                    WriteLine($"{pr.Name} = {pr.GetValue(ds)}");
                }
            }
            GlobalScope.findChildren(SymTagEnum.SymTagNull, null, 0, out EnumSymbols);
            var tot  = EnumSymbols.count;
            var curr = 0;

            do
            {
                EnumSymbols.Next(1, out Master, out compileFetched);
                if (Master == null)
                {
                    continue;
                }

                ForegroundColor = ConsoleColor.White;

                //foreach (var pr in typeof(IDiaSymbol).LinqPublicProperties())
                //WriteLine($"{pr.Name} = {pr.GetValue(Master)}");

                DumpSymbol <IDiaSymbol>(Master, level);
            } while (curr++ < tot);

            return(0);
        }
Beispiel #13
0
        private void PopulateCacheForTypeAndMethodSymbols()
        {
            IDiaEnumSymbols enumTypeSymbols = null;
            IDiaSymbol      global          = null;

            try
            {
                global = this.session.globalScope;
                global.findChildren(SymTagEnum.SymTagCompiland, null, 0, out enumTypeSymbols);
                uint       celtTypeSymbol;
                IDiaSymbol typeSymbol = null;

                // NOTE::
                // If foreach loop is used instead of Enumerator iterator, for some reason it leaves
                // the reference to pdb active, which prevents pdb from being rebuilt (in VS IDE scenario).
                enumTypeSymbols.Next(1, out typeSymbol, out celtTypeSymbol);
                while (celtTypeSymbol == 1 && null != typeSymbol)
                {
                    this.typeSymbols[typeSymbol.name] = typeSymbol;

                    IDiaEnumSymbols enumMethodSymbols = null;
                    try
                    {
                        Dictionary <string, IDiaSymbol> methodSymbolsForType = new Dictionary <string, IDiaSymbol>();
                        typeSymbol.findChildren(SymTagEnum.SymTagFunction, null, 0, out enumMethodSymbols);

                        uint       celtMethodSymbol;
                        IDiaSymbol methodSymbol = null;

                        enumMethodSymbols.Next(1, out methodSymbol, out celtMethodSymbol);
                        while (celtMethodSymbol == 1 && null != methodSymbol)
                        {
                            UpdateMethodSymbolCache(methodSymbol.name, methodSymbol, methodSymbolsForType);
                            enumMethodSymbols.Next(1, out methodSymbol, out celtMethodSymbol);
                        }

                        this.methodSymbols[typeSymbol.name] = methodSymbolsForType;
                    }
                    catch (Exception ex)
                    {
                        if (EqtTrace.IsErrorEnabled)
                        {
                            EqtTrace.Error(
                                "Ignoring the exception while iterating method symbols:{0} for type:{1}",
                                ex,
                                typeSymbol.name);
                        }
                    }
                    finally
                    {
                        ReleaseComObject(ref enumMethodSymbols);
                    }

                    enumTypeSymbols.Next(1, out typeSymbol, out celtTypeSymbol);
                }
            }
            catch (Exception ex)
            {
                if (EqtTrace.IsErrorEnabled)
                {
                    EqtTrace.Error("Ignoring the exception while iterating type symbols:{0}", ex);
                }
            }
            finally
            {
                ReleaseComObject(ref enumTypeSymbols);
                ReleaseComObject(ref global);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Method for native type reflection into DLR
        /// TODO: Perf check + handle .Dictionary references
        /// </summary>
        /// <param name="Info"></param>
        /// <param name="Master"></param>
        /// <param name="preName"></param>
        /// <param name="CurrOffset"></param>
        /// <param name="memRead"></param>
        /// <returns></returns>
        dynamic xDumpStructs(
            dynamic Info,
            IDiaSymbol Master,
            string preName,
            int CurrOffset,
            long vAddress  = 0,
            long[] memRead = null,
            Func <long, int, byte[]> GetMem            = null,
            Func <long, int, long[]> GetMemLong        = null,
            PropertyChangedEventHandler ExpandoChanged = null
            )
        {
            var IInfo    = (IDictionary <string, object>)Info;
            var InfoDict = new Dictionary <string, object>();

            Info.Dictionary = InfoDict;
            long   lvalue = 0;
            ulong  Length = 0, memberLen = 0;
            string memberName = string.Empty;

            IDiaSymbol      Sub   = null;
            IDiaEnumSymbols Enum2 = null;
            IDiaSymbol      TypeType;
            SymTagEnum      TypeTypeTag;

            uint compileFetched = 0;

            Master.findChildren(SymTagEnum.SymTagNull, null, 10, out Enum2);
            do
            {
                if (Enum2 == null)
                {
                    break;
                }

                Enum2.Next(1, out Sub, out compileFetched);
                if (Sub == null)
                {
                    continue;
                }

                dynamic zym        = new ExpandoObject();
                var     Izym       = (IDictionary <string, object>)zym;
                var     staticDict = new Dictionary <string, object>();
                zym.Dictionary = staticDict;

                var master   = zym.InstanceName = Master.name;
                var sType    = Sub.type;
                var typeName = sType.name;
                var currName = $"{preName}.{Sub.name}";

                // LocIsConstant
                if (Sub.locationType == 0xA)
                {
                    zym.ConstValue = Sub.value;
                }

                int Pos = CurrOffset + Sub.offset;

                zym.TypeName   = typeName;
                zym.MemberName = currName;

                zym.Tag    = (SymTagEnum)Sub.symTag;
                Length     = sType.length;
                zym.Length = Length;

                zym.OffsetPos = Pos;
                zym.vAddress  = vAddress;

                // bitfield
                if (Sub.locationType == 6)
                {
                    zym.BitPosition = Sub.bitPosition;
                    zym.BitCount    = Sub.length;
                }
                if (SymTagEnum.SymTagArrayType == (SymTagEnum)sType.symTag)
                {
                    TypeType = sType.type;

                    memberLen  = TypeType.length;
                    memberName = TypeType.name;

                    zym.ArrayCount      = Length / memberLen;
                    zym.ArrayMemberLen  = memberLen;
                    zym.ArrayMemberType = memberName;
                }

                bool KeepRecur = true;
                if (memRead != null)
                {
                    bool captured = false;
                    lvalue = memRead == null ? 0 : memRead[Pos / 8];

                    // TODO: Handles/OBJECT_FOO/_ETC...

                    if (String.Equals("_UNICODE_STRING", typeName) && GetMem != null)
                    {
                        // since we deref'd this struct manually don't follow
                        KeepRecur = false;
                        string strVal     = "";
                        var    DataOffset = (Pos + 8) / 8;
                        // get address from our offset
                        var StringAddr = memRead[DataOffset];
                        if (StringAddr != 0)
                        {
                            var strLen = (short)lvalue & 0xffff;

                            var strByteArr = GetMem(StringAddr, strLen + 2);

                            strVal = Encoding.Unicode.GetString(strByteArr, 0, strLen);
                        }
                        // update new address for double deref
                        zym.vAddress = StringAddr;
                        Izym.Add(defName, strVal);
                        staticDict.Add(currName, lvalue);
                    }
                    else
                    {
                        // bittable types
                        // TODO: GUID
                        // 6 is a bitfield
                        if (Sub.locationType == 6)
                        {
                            var mask    = 1U;
                            var BitsLen = Sub.length;
                            zym.BitCount = BitsLen;

                            var subOff = Sub.offset;

                            for (int x = (int)BitsLen - 1; x > 0; x--)
                            {
                                mask  = mask << 1;
                                mask |= 1;
                            }
                            var new_mask = mask << (int)Sub.bitPosition << (subOff * 8);

                            lvalue &= new_mask;

                            // move lvalue to bitposition 0
                            // saves having todo this every time we evaluate Value
                            lvalue   = lvalue >> (int)Sub.bitPosition >> (subOff * 8);
                            captured = true;
                        }
                        else
                        {
                            var shift = (Pos % 8 * 8);
                            switch (sType.length)
                            {
                            case 8:
                                captured = true;
                                break;

                            case 4:
                                lvalue   = (lvalue >> shift) & 0xffffffff;
                                captured = true;
                                break;

                            case 2:
                                lvalue   = (lvalue >> shift) & 0xffff;
                                captured = true;
                                break;

                            case 1:
                                lvalue   = (lvalue >> shift) & 0xff;
                                captured = true;
                                break;

                            default:
                                break;
                            }
                            // were dealing with some sort of array or weird sized type not nativly supported (yet, e.g. GUID)
                            // if we start with a _ we are going to be descending recursivly into this type so don't extract it here
                            // this is really for basic type array's or things' were not otherwise able to recursivly extract
                            if (!captured && (SymTagEnum.SymTagArrayType == (SymTagEnum)sType.symTag))
                            {
                                int BytesReadRoom = 0, len = 0;
                                if (memberLen == 1 || memberLen > 8)
                                {
                                    byte[] barr = new byte[sType.length];
                                    BytesReadRoom = (memRead.Length * 8) - Pos;
                                    len           = BytesReadRoom > barr.Length ? barr.Length : BytesReadRoom;
                                    Buffer.BlockCopy(memRead, Pos, barr, 0, len);

                                    Izym.Add(defName, barr);
                                    staticDict.Add(currName, barr);
                                }
                                else if (memberLen == 4)
                                {
                                    int   arrLen = (int)Length / (int)memberLen;
                                    int[] iarr   = new int[arrLen];
                                    BytesReadRoom = (memRead.Length * 8) - Pos;
                                    len           = BytesReadRoom > (int)Length ? (int)Length : BytesReadRoom;
                                    Buffer.BlockCopy(memRead, Pos, iarr, 0, len);

                                    Izym.Add(defName, iarr);
                                    staticDict.Add(currName, iarr);
                                }
                                else
                                {
                                    int    arrLen = (int)Length / (int)memberLen;
                                    long[] larr   = new long[arrLen];
                                    BytesReadRoom = (memRead.Length * 8) - Pos;
                                    len           = BytesReadRoom > (int)Length ? (int)Length : BytesReadRoom;
                                    Buffer.BlockCopy(memRead, Pos, larr, 0, len);

                                    Izym.Add(defName, larr);
                                    staticDict.Add(currName, larr);
                                }
                            }
                        }
                        if (captured)
                        {
                            Izym.Add(defName, lvalue);
                            staticDict.Add(currName, lvalue);
                        }
                    }
                }

                // This is a pointer really, so type.type... of course!
                if (KeepRecur)
                {
                    TypeType    = sType.type;
                    TypeTypeTag = (SymTagEnum)sType.symTag;
                    if (TypeTypeTag == SymTagEnum.SymTagPointerType)
                    {
                        zym.IsPtr = true;
                        if (TypeType != null && !string.IsNullOrWhiteSpace(TypeType.name))
                        {
                            zym.PtrTypeName = TypeType.name;

                            // only recuse non-recursive ptr types
                            if (TypeType.name.Equals("_OBJECT_NAME_INFORMATION"))
                            {
                                // do second deref here
                                // the location to read is our offset pos data
                                var deRefArr = GetMemLong(lvalue, 0x20);

                                xDumpStructs(zym, TypeType, currName, 0, vAddress, deRefArr, GetMem, GetMemLong, ExpandoChanged);
                            }
                        }
                    }
                    else
                    {
                        xDumpStructs(zym, sType, currName, Pos, vAddress, memRead, GetMem, GetMemLong, ExpandoChanged);
                    }
                }
#if DEBUGX
                ForegroundColor = ConsoleColor.Cyan;
                WriteLine($"Pos = [{Pos:X}] Name = [{currName}] Len [{sType.length}], Type [{typeName}], ThisStruct [{master}]");
#endif


                // Length comes up a lot in struct's and conflicts with the ExpandoObject
                // so remap it specially
                var AddedName = Sub.name;
                if (AddedName.ToLower().Equals("value"))
                {
                    AddedName = "ValueMember";
                }
                if (AddedName.ToLower().Equals("length"))
                {
                    AddedName = "LengthMember";
                }
                if (IInfo.ContainsKey(AddedName))
                {
                    continue;
                }


                IInfo.Add(AddedName, zym);
                InfoDict.Add(AddedName, lvalue);

                if (ExpandoChanged != null)
                {
                    ((INotifyPropertyChanged)zym).PropertyChanged += ExpandoChanged;
                }
            } while (compileFetched == 1);


            return(null);
        }
Beispiel #15
0
        dynamic xDumpStructs(dynamic Info, IDiaSymbol Master, string preName, int CurrOffset, long[] memRead = null)
        {
            var IInfo = (IDictionary <string, object>)Info;

            IDiaSymbol      Sub            = null;
            IDiaEnumSymbols Enum2          = null;
            uint            compileFetched = 0;

            Master.findChildren(SymTagEnum.SymTagNull, null, 10, out Enum2);
            do
            {
                if (Enum2 == null)
                {
                    break;
                }

                Enum2.Next(1, out Sub, out compileFetched);
                if (Sub == null)
                {
                    continue;
                }

                dynamic zym  = new ExpandoObject();
                var     Izym = (IDictionary <string, object>)zym;

                var master   = zym.InstanceName = Master.name;
                var sType    = Sub.type;
                var typeName = zym.TypeName = sType.name;
                var currName = zym.MemberName = $"{preName}.{Sub.name}";
                int Pos      = CurrOffset + Sub.offset;

                zym.Tag       = (SymTagEnum)Sub.symTag;
                zym.Length    = sType.length;
                zym.OffsetPos = Pos;

                if (memRead != null)
                {
                    var defName = "Value";
                    switch (sType.length)
                    {
                    case 4:
                        var ival = memRead == null ? 0 : (int)(memRead[Pos / 8] & 0xffffffffff);
                        Izym.Add(defName, ival);
                        break;

                    case 2:
                        var sval = memRead == null ? 0 : (short)(memRead[Pos / 8] & 0xffffff);
                        Izym.Add(defName, sval);
                        break;

                    case 1:
                        var bval = memRead == null ? 0 : (byte)(memRead[Pos / 8] & 0xff);
                        Izym.Add(defName, bval);
                        break;

                    default:
                        var lval = memRead == null ? 0 : memRead[Pos / 8];
                        Izym.Add(defName, lval);
                        break;
                    }
                }
                // This is a pointer really, so type.type... of course!
                var TypeType    = sType.type;
                var TypeTypeTag = sType.symTag;
                if ((SymTagEnum)TypeTypeTag == SymTagEnum.SymTagPointerType)
                {
                    zym.IsPtr = true;
                    if (TypeType != null && !string.IsNullOrWhiteSpace(TypeType.name))
                    {
                        zym.PtrTypeName = TypeType.name;
                    }
                }
                else
                {
                    xDumpStructs(zym, sType, currName, Pos, memRead);
                }
#if DEBUGX
                ForegroundColor = ConsoleColor.Cyan;
                WriteLine($"Pos = [{Pos:X}] Name = [{currName}] Len [{sType.length}], Type [{typeName}], ThisStruct [{master}]");
#endif

                if (IInfo.ContainsKey(Sub.name))
                {
                    continue;
                }

                IInfo.Add(Sub.name, zym);

                //Pos += (int)sType.length;
            } while (compileFetched == 1);
            return(null);
        }
Beispiel #16
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
        }
Beispiel #17
0
        private IDiaSymbol GetTypeSymbol(string typeName, SymTagEnum symTag)
        {
            ValidateArg.NotNullOrEmpty(typeName, "typeName");

            IDiaEnumSymbols enumSymbols = null;
            IDiaSymbol      typeSymbol  = null;
            IDiaSymbol      global      = null;

            uint celt;

            try
            {
                typeName = typeName.Replace('+', '.');
                if (this.typeSymbols.ContainsKey(typeName))
                {
                    return(this.typeSymbols[typeName]);
                }

                global = this.session.globalScope;
                global.findChildren(symTag, typeName, 0, out enumSymbols);

                enumSymbols.Next(1, out typeSymbol, out celt);

#if DEBUG
                if (typeSymbol == null)
                {
                    IDiaEnumSymbols enumAllSymbols = null;
                    try
                    {
                        global.findChildren(symTag, null, 0, out enumAllSymbols);
                        List <string> children = new List <string>();

                        IDiaSymbol childSymbol  = null;
                        uint       fetchedCount = 0;
                        while (true)
                        {
                            enumAllSymbols.Next(1, out childSymbol, out fetchedCount);
                            if (fetchedCount == 0 || childSymbol == null)
                            {
                                break;
                            }

                            children.Add(childSymbol.name);
                            ReleaseComObject(ref childSymbol);
                        }

                        Debug.Assert(children.Count > 0);
                    }
                    finally
                    {
                        ReleaseComObject(ref enumAllSymbols);
                    }
                }
#endif
            }
            finally
            {
                ReleaseComObject(ref enumSymbols);
                ReleaseComObject(ref global);
            }

            if (null != typeSymbol)
            {
                this.typeSymbols[typeName] = typeSymbol;
            }

            return(typeSymbol);
        }
Beispiel #18
0
        public List <MinSym> Enum(string arg)
        {
            IDiaEnumSymbols EnumSymbols    = null;
            IDiaSymbol      Master         = null;
            int             level          = 2;
            uint            compileFetched = 0;

            var rv = new List <MinSym>();

            var foo = new Dia2Lib.DiaSource();

            foo.loadDataForExe(arg, SymPath, null);
            foo.openSession(out Session);

            if (Session == null)
            {
                return(null);
            }

            Session.loadAddress = 0;

            var GlobalScope = Session.globalScope;



#if BLAH_FIX_SOMETIME
            // reflection & CCW not exactally match made in heaven?


            //do
            //{
            //    try
            //    {
            //        Session.findChildren(Session.globalScope, SymTagEnum.SymTagNull, null, 0, out EnumSymbols);
            //        var tot1 = EnumSymbols.count;
            //        uint curr1 = 0;
            //        do
            //        {
            //            EnumSymbols.Next(1, out Master, out compileFetched);
            //            if (Master == null)
            //                continue;
            //            ForegroundColor = ConsoleColor.White;
            //            foreach (var pr in typeof(IDiaSymbol).LinqPublicProperties())
            //            {
            //                WriteLine($"{pr.Name} = {pr.GetValue(Master)}");
            //            }
            //            //foreach (var fn in typeof(IDiaSymbol).LinqPublicFunctions())
            //            //{
            //            //    //if (fn.Name.Contains("get"))
            //            //        WriteLine($"{fn.Name} = {fn.Invoke(Master, null)}");
            //            //}
            //            // DumpSymbol<IDiaSymbol>(Master, ref level);
            //        } while (curr1++ < tot1);
            //        //foreach (var pr in typeof(IDiaSymbol).LinqPublicProperties())
            //        //    WriteLine($"{pr.Name} = {pr.GetValue(Master)}");
            //    }
            //    catch { }
            //    finally
            //    {
            //        if (Master != null)
            //            rva += (uint)(Master.length == 0 ? 1 : Master.length);
            //    }

            //} while (Master != null);


            IDiaEnumDebugStreams DebugStreams;

            /*
             * Session.getEnumDebugStreams(out DebugStreams);
             * for (int i = 0; i < DebugStreams.count; i++)
             * {
             *  var ds = DebugStreams.Item(i);
             * //    foreach (var pr in typeof(IDiaEnumDebugStreamData).LinqPublicProperties())
             * //        WriteLine($"{pr.Name} = {pr.GetValue(ds)}");
             * }
             *
             * Session.getEnumTables(out tables);
             * for (int i = 0; i < tables.count; i++)
             * {
             *  var ds = tables.Item(i);
             * //    foreach (var pr in typeof(IDiaTable).LinqPublicProperties())
             * //        WriteLine($"{pr.Name} = {pr.GetValue(ds)}");
             * }
             */
#endif

            GlobalScope.findChildren(SymTagEnum.SymTagNull, null, 0, out EnumSymbols);
            var tot = EnumSymbols.count;
            do
            {
                EnumSymbols.Next(1, out Master, out compileFetched);
                if (Master == null)
                {
                    continue;
                }

                ForegroundColor = ConsoleColor.White;

                foreach (var pr in typeof(IDiaSymbol).LinqPublicProperties())
                {
                    WriteLine($"{pr.Name} = {pr.GetValue(Master)}");
                }

                var subList = DumpSymbol <IDiaSymbol>(Master, level);
                rv.AddRange(subList);
            } while (compileFetched == 1);

            rv.Sort();

            return(rv);
        }