public abstract GetVTableRVA ( String symbolName, String keyBaseName ) : |
||
symbolName | String | |
keyBaseName | String | |
Résultat |
private static void ScanDacFile(String file, SymbolProvider sf, List <UInt32> rvaArray, out UInt32 numGlobals) { StreamReader strm = new StreamReader(file, System.Text.Encoding.ASCII); String line; Hashtable vtables = new Hashtable(); // hashtable to guarantee uniqueness of entries // // Scan through the data access header file looking // for the globals structure. // for (;;) { line = strm.ReadLine(); if (line == null) { throw new InvalidOperationException("Invalid dac header format"); } else if (line == "typedef struct _DacGlobals") { break; } } if (strm.ReadLine() != "{") { throw new InvalidOperationException("Invalid dac header format"); } // // All the globals come first so pick up each line that // begins with ULONG. // bool fFoundVptrs = false; numGlobals = 0; for (;;) { line = strm.ReadLine().Trim(); if (line.Equals("union {") || line.Equals("struct {") || line.Equals("};") || line.StartsWith("#line ") || line.StartsWith("# ")) { // Ignore. } else if (line.StartsWith("ULONG ")) { UInt32 rva = 0; line = line.Remove(0, 6); line = line.TrimEnd(";".ToCharArray()); string vptrSuffixSingle = "__vtAddr"; string vptrSuffixMulti = "__mvtAddr"; string vptrSuffix = null; if (line.EndsWith(vptrSuffixSingle)) { vptrSuffix = vptrSuffixSingle; } else if (line.EndsWith(vptrSuffixMulti)) { vptrSuffix = vptrSuffixMulti; } if (vptrSuffix != null) { if (!fFoundVptrs) { numGlobals = (UInt32)rvaArray.Count; fFoundVptrs = true; } line = line.Remove(line.Length - vptrSuffix.Length, vptrSuffix.Length); string keyBaseName = null; string descTail = null; if (vptrSuffix == vptrSuffixMulti) { // line now has the form <class>__<base>, so // split off the base. int basePrefix = line.LastIndexOf("__"); if (basePrefix < 0) { throw new InvalidOperationException("VPTR_MULTI_CLASS has no keyBase."); } keyBaseName = line.Substring(basePrefix + 2); line = line.Remove(basePrefix); descTail = " for " + keyBaseName; } rva = sf.GetVTableRVA(line, keyBaseName); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid vtable " + line + descTail); } else { String existing = (String)vtables[rva]; if (existing != null) { throw new InvalidOperationException(existing + " and " + line + " are at the same offsets." + " Add VPTR_UNIQUE(<a random unique number here>) to the offending classes to make their vtables unique."); } vtables[rva] = line; Console.WriteLine(" " + ToHexNB(rva) + ", // vtable " + line + descTail); } } else { SymbolProvider.SymType symType; if (fFoundVptrs) { throw new InvalidOperationException("Invalid dac header format. Vtable pointers must be last."); } if (line.StartsWith("dac__")) { // Global variables, use the prefix. line = line.Remove(0, 5); symType = SymbolProvider.SymType.GlobalData; } else if (line.StartsWith("fn__")) { // Global or static functions, use the prefix. line = line.Remove(0, 4); line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalFunction; } else { // Static member variable, use the full name with // namespace replacement. line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalData; } if (0 == rva) { rva = sf.GetGlobalRVA(line, symType); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid symbol " + line); } else { Console.WriteLine(" " + ToHexNB(rva) + ", // " + line); } } } rvaArray.Add(rva); } else if (line == "") { // Skip blanks. } else { // We hit a non-global so we're done. if (!line.Equals("} DacGlobals;")) { throw new InvalidOperationException("Invalid dac header format at \"" + line + "\""); } break; } } if (!fFoundVptrs) { throw new InvalidOperationException("Invalid dac header format. Vtable pointers not found."); } }
private static void ScanDacFile(String file, SymbolProvider sf, List<UInt32> rvaArray, out UInt32 numGlobals) { StreamReader strm = new StreamReader(file, System.Text.Encoding.ASCII); String line; Hashtable vtables = new Hashtable(); // hashtable to guarantee uniqueness of entries // // Scan through the data access header file looking // for the globals structure. // for (;;) { line = strm.ReadLine(); if (line == null) { throw new InvalidOperationException("Invalid dac header format"); } else if (line == "typedef struct _DacGlobals") { break; } } if (strm.ReadLine() != "{") { throw new InvalidOperationException("Invalid dac header format"); } // // All the globals come first so pick up each line that // begins with ULONG. // bool fFoundVptrs = false; numGlobals = 0; for (;;) { line = strm.ReadLine().Trim(); if ( line.Equals("union {") || line.Equals("struct {") || line.Equals("};") || line.StartsWith("#line ") || line.StartsWith("# ")) { // Ignore. } else if (line.StartsWith("ULONG ")) { UInt32 rva = 0; line = line.Remove(0, 6); line = line.TrimEnd(";".ToCharArray()); string vptrSuffixSingle = "__vtAddr"; string vptrSuffixMulti = "__mvtAddr"; string vptrSuffix = null; if (line.EndsWith(vptrSuffixSingle)) { vptrSuffix = vptrSuffixSingle; } else if (line.EndsWith(vptrSuffixMulti)) { vptrSuffix = vptrSuffixMulti; } if (vptrSuffix != null) { if (!fFoundVptrs) { numGlobals = (UInt32)rvaArray.Count; fFoundVptrs = true; } line = line.Remove(line.Length - vptrSuffix.Length, vptrSuffix.Length); string keyBaseName = null; string descTail = null; if (vptrSuffix == vptrSuffixMulti) { // line now has the form <class>__<base>, so // split off the base. int basePrefix = line.LastIndexOf("__"); if (basePrefix < 0) { throw new InvalidOperationException("VPTR_MULTI_CLASS has no keyBase."); } keyBaseName = line.Substring(basePrefix + 2); line = line.Remove(basePrefix); descTail = " for " + keyBaseName; } rva = sf.GetVTableRVA(line, keyBaseName); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid vtable " + line + descTail); } else { String existing = (String)vtables[rva]; if (existing != null) { throw new InvalidOperationException(existing + " and " + line + " are at the same offsets." + " Add VPTR_UNIQUE(<a random unique number here>) to the offending classes to make their vtables unique."); } vtables[rva] = line; Console.WriteLine(" " + ToHexNB(rva) + ", // vtable " + line + descTail); } } else { SymbolProvider.SymType symType; if (fFoundVptrs) throw new InvalidOperationException("Invalid dac header format. Vtable pointers must be last."); if (line.StartsWith("dac__")) { // Global variables, use the prefix. line = line.Remove(0, 5); symType = SymbolProvider.SymType.GlobalData; } else if (line.StartsWith("fn__")) { // Global or static functions, use the prefix. line = line.Remove(0, 4); line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalFunction; } else { // Static member variable, use the full name with // namespace replacement. line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalData; } if (0 == rva) { rva = sf.GetGlobalRVA(line, symType); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid symbol " + line); } else { Console.WriteLine(" " + ToHexNB(rva) + ", // " + line); } } } rvaArray.Add(rva); } else if (line == "") { // Skip blanks. } else { // We hit a non-global so we're done. if (!line.Equals("} DacGlobals;")) { throw new InvalidOperationException("Invalid dac header format at \"" + line + "\""); } break; } } if (!fFoundVptrs) throw new InvalidOperationException("Invalid dac header format. Vtable pointers not found."); }