internal TypeDeobfuscator(XElement typeNode) { m_comparer = StringComparer.Ordinal; ObfuscatedName = ((string)typeNode.Element("newname")).Replace('/', '+'); OriginalName = ((string)typeNode.Element("name")).Replace('/', '+'); var declaringType = TypeNameRegex.ParseType(OriginalName); m_fields = (from fieldNode in typeNode.Elements("fieldlist").Elements("field") let originalName = (string)fieldNode.Element("name") let obfuscatedName = (string)fieldNode.Element("newname") select new ObfuscatedField(obfuscatedName, originalName, declaringType)).ToArray(); m_methods = typeNode.Elements("methodlist").Elements("method").Select(m => { string originalName = (string)m.Element("name"); String obfuscatedName = (string)m.Element("newname"); TypeName returnType = default(TypeName); string prefix; TypeName[] args; string sig = (string)m.Element("signature"); if (TypeNameRegex.TryExtractMethodInfo(sig.Replace('/', '+'), out prefix, out args)) { if (!string.IsNullOrEmpty(prefix)) { returnType = TypeNameRegex.ParseType(prefix); } } //TypeName returnType = null; return(new ObfuscatedMethod(obfuscatedName, originalName, returnType, args)); }).ToArray(); Array.Sort(m_fields, (left, right) => m_comparer.Compare(left.ObfuscatedName + left.DeclaringType, right.ObfuscatedName + right.DeclaringType)); Array.Sort(m_methods, (left, right) => m_comparer.Compare(left.SortKey, right.SortKey)); }
public string DeobfuscateCallstack(string callstack) { string[] lines = callstack.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (!line.Contains("System.Obfuscation")) { continue; } string prefix; TypeName[] args; if (TypeNameRegex.TryExtractMethodInfo(line, out prefix, out args)) { string declaringType = prefix.Substring(0, prefix.LastIndexOf(".")); string deObfType = DeobfuscateSimpleType(declaringType); string methodName = prefix.Substring(declaringType.Length + 1); for (int j = 0; j < args.Length; j++) { string before = args[j].Name; args[j] = DeobfuscateType(args[j]); if (before == args[j].Name) { if (TypeNameRegex.CouldBeNestedType(args[j].Name)) { //try as nested type..... var arg2 = declaringType + "+" + args[j].Name; var arg3 = DeobfuscateSimpleType(arg2); if (arg2 != arg3) { args[j] = new TypeName(arg3); } } } } var obf = GetTypeDeobfuscator(declaringType); if (obf != null) { List <ObfuscatedMethod> matches; if (obf.TryDeobfuscateMethod(methodName, args.Select(a => a.ToString()).ToArray(), out matches)) { if (matches.Count == 1) { lines[i] = $"{deObfType}.{matches[0].OriginalName}({string.Join(",", args)})"; } else { var options = matches.Select(m => $"{deObfType}.{m.OriginalName}({string.Join(",", args)})"); lines[i] = "--AMBIGUOUS--\r\n\t" + string.Join("\r\n\t", options); } } } } } return(string.Join(Environment.NewLine, lines)); }