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); }
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); }
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); } } }
/// <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); }
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); }
/// <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]); } }
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)); } }
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); }
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); }
/// <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); }
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); }
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); }
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); } }
/// <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); }
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); }
/// <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 }
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); }
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); }