MemberRef ReadMethodRef(Node node) { string name = ""; TypeSig declType = null; TypeSig retType = null; var paramSigs = new List <TypeSig>(); bool instance = false; for (int i = 0; i < node.Count; i++) { var child = node[i]; if (child.Id == (int)IRConstants.STR) { name = ((Token)child).Image; name = name.Substring(1, name.Length - 2); } else if (child.Id == (int)IRConstants.INSTANCE) { instance = true; } else if (child.Id == (int)IRConstants.METHOD_RET_TYPE) { retType = ReadTypeRef(child[0]); } else if (child.Id == (int)IRConstants.TYPE_REF) { declType = ReadTypeRef(child); } else if (child.Id == (int)IRConstants.METHOD_PARAMS) { for (int j = 0; j < child.Count; j++) { if (child[j].Id == (int)IRConstants.TYPE_REF) { paramSigs.Add(ReadTypeRef(child[j])); } } } } if (instance) { return(new MemberRefUser(module, name, MethodSig.CreateInstance(retType, paramSigs.ToArray()), declType.ToTypeDefOrRef())); } return(new MemberRefUser(module, name, MethodSig.CreateStatic(retType, paramSigs.ToArray()), declType.ToTypeDefOrRef())); }
public bool restore(MethodDef method) { this.method = method; bool atLeastOneFailed = false; if (method == null || method.Body == null) { return(!atLeastOneFailed); } var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.Operand != null) { continue; } TypeSig operandType = null; switch (instr.OpCode.Code) { case Code.Ldelema: var arrayType = MethodStack.getLoadedType(method, instrs, i, 1) as SZArraySig; if (arrayType == null) { break; } operandType = arrayType.Next; break; case Code.Ldobj: operandType = getPtrElementType(MethodStack.getLoadedType(method, instrs, i, 0)); break; case Code.Stobj: operandType = MethodStack.getLoadedType(method, instrs, i, 0); if (!isValidType(operandType)) { operandType = getPtrElementType(MethodStack.getLoadedType(method, instrs, i, 1)); } break; default: continue; } if (!isValidType(operandType)) { atLeastOneFailed = true; continue; } instr.Operand = operandType.ToTypeDefOrRef(); } return(!atLeastOneFailed); }
internal bool RegisterGeneric(TypeSig t) { Debug.Assert(t != null, $"{nameof(t)} != null"); // This is a temporary fix. // Type visibility should be handled in a much better way which would involved some analysis. var typeDef = t.ToTypeDefOrRef().ResolveTypeDef(); if (typeDef != null && !typeDef.IsVisibleOutside()) { return(false); } // Get proper type. t = SignatureUtils.GetLeaf(t); // scrambling voids leads to peverify errors, better leave them out. if (t.ElementType == ElementType.Void) { return(false); } if (!Generics.ContainsKey(t)) { GenericParam newGenericParam; if (t.IsGenericMethodParameter) { var mVar = t.ToGenericMVar(); Debug.Assert(mVar != null, $"{nameof(mVar)} != null"); newGenericParam = new GenericParamUser(GenericCount, mVar.GenericParam.Flags, $"T{GenericCount}") { Rid = mVar.Rid }; } else if (t.IsGenericTypeParameter) { var tVar = t.ToGenericVar(); Debug.Assert(tVar != null, $"{nameof(tVar)} != null"); newGenericParam = new GenericParamUser(GenericCount, tVar.GenericParam.Flags, $"T{GenericCount}") { Rid = tVar.Rid }; } else { newGenericParam = new GenericParamUser(GenericCount, GenericParamAttributes.NoSpecialConstraint, $"T{GenericCount}"); } Generics.Add(t, newGenericParam); GenericCount++; _trueTypes.Add(t); return(true); } else { return(false); } }
static bool DecodeArrayInitializer(TypeSig elementTypeRef, byte[] initialValue, ILExpression[] output) { elementTypeRef = elementTypeRef.RemovePinnedAndModifiers(); TypeCode elementType = TypeAnalysis.GetTypeCode(elementTypeRef); switch (elementType) { case TypeCode.Boolean: case TypeCode.Byte: return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)d[i])); case TypeCode.SByte: return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)unchecked ((sbyte)d[i]))); case TypeCode.Int16: return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)BitConverter.ToInt16(d, i))); case TypeCode.Char: case TypeCode.UInt16: return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)BitConverter.ToUInt16(d, i))); case TypeCode.Int32: case TypeCode.UInt32: return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToInt32)); case TypeCode.Int64: case TypeCode.UInt64: return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToInt64)); case TypeCode.Single: return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToSingle)); case TypeCode.Double: return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToDouble)); case TypeCode.Object: var typeDef = elementTypeRef.ToTypeDefOrRef().ResolveWithinSameModule(); if (typeDef != null && typeDef.IsEnum) { return(DecodeArrayInitializer(typeDef.GetEnumUnderlyingType(), initialValue, output)); } return(false); default: return(false); } }
private TypeSig RemapReference(TypeSig reference) { if (reference == null) { return(null); } var referenceTypeDefOrRef = reference.ToTypeDefOrRef(); if (referenceTypeDefOrRef.NumberOfGenericParameters > 0) { return(RemapGenericType(reference)); } return(Import(reference)); }
public static bool IsEnumType(TypeSig tySig, out TypeSig enumTypeSig) { if (tySig.IsValueType) { TypeDef tyDef = tySig.ToTypeDefOrRef().ResolveTypeDef(); if (tyDef.BaseType.FullName == "System.Enum") { FieldDef fldDef = tyDef.Fields.FirstOrDefault(f => !f.IsStatic); Debug.Assert(fldDef != null); enumTypeSig = fldDef.FieldType; return(true); } } enumTypeSig = null; return(false); }
object ConvertEnum <T>(TypeSig elemType, IList <CAArgument> oldList) { var ary = ConvertArray <EnumInfo>(elemType, oldList); var list = new T[ary.Length]; var sigComparer = new SigComparer(SigComparerOptions.CompareAssemblyPublicKeyToken); for (int i = 0; i < list.Length; i++) { if (ary[i].Value is T && sigComparer.Equals(elemType, ary[i].EnumType)) { list[i] = (T)ary[i].Value; } } return(new EnumInfo { EnumType = elemType.ToTypeDefOrRef(), Value = list, IsArray = true, }); }
public static TypeDef ToTypeDef(this TypeSig type) { TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef(); if (typeDef != null) { return(typeDef); } if (type.IsArray) { typeDef = type.Next.ToTypeDefOrRef().ResolveTypeDef(); } if (typeDef != null) { return(typeDef); } if (type.IsGenericInstanceType) { typeDef = type.ToGenericInstSig().ToTypeDefOrRef().ResolveTypeDef(); } return(typeDef); }
private static IEnumerable <TypeSig> BaseTypes(TypeSig type) { TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow(); if (typeDef.BaseType == null) { yield break; } TypeSig baseType = type; do { var args = new GenericArguments(); if (baseType.IsGenericInstanceType) { args.PushTypeArgs(((GenericInstSig)baseType).GenericArguments); } baseType = args.Resolve(typeDef.BaseType.ToTypeSig()); yield return(baseType); typeDef = typeDef.BaseType.ResolveTypeDef(); } while (typeDef != null && typeDef.BaseType != null); }
public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax, int depth) { if (depth++ > MAX_CONVERTTYPE_DEPTH || type == null) { return; } var ts = type as TypeSpec; if (ts != null && !(ts.TypeSig is FnPtrSig)) { WriteTo(((TypeSpec)type).TypeSig, writer, syntax, depth); return; } string typeFullName = type.FullName; string typeName = type.Name.String; if (ts != null) { var fnPtrSig = ts.TypeSig as FnPtrSig; typeFullName = DnlibExtensions.GetFnPtrFullName(fnPtrSig); typeName = DnlibExtensions.GetFnPtrName(fnPtrSig); } TypeSig typeSig = null; string name = type.DefinitionAssembly.IsCorLib() ? PrimitiveTypeName(typeFullName, type.Module, out typeSig) : null; if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) { WriteKeyword(writer, name, typeSig.ToTypeDefOrRef()); } else { writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type)); } } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { WriteKeyword(writer, name, typeSig.ToTypeDefOrRef()); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(DnlibExtensions.IsValueType(type) ? "valuetype" : "class", TextTokenType.Keyword); writer.WriteSpace(); } if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName, depth); writer.Write('/', TextTokenType.Operator); writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type)); } else { if (!(type is TypeDef) && type.Scope != null && !(type is TypeSpec)) { writer.Write('[', TextTokenType.Operator); writer.Write(Escape(type.Scope.GetScopeName()), TextTokenType.ILModule); writer.Write(']', TextTokenType.Operator); } if (ts != null || MustEscape(typeFullName)) { writer.WriteReference(Escape(typeFullName), type, TextTokenHelper.GetTextTokenType(type)); } else { WriteNamespace(writer, type.Namespace); if (!string.IsNullOrEmpty(type.Namespace)) { writer.Write('.', TextTokenType.Operator); } writer.WriteReference(IdentifierEscaper.Escape(type.Name), type, TextTokenHelper.GetTextTokenType(type)); } } } }
public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax, int depth) { if (depth++ > MAX_CONVERTTYPE_DEPTH) { return; } ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature; if (type is PinnedSig) { ((PinnedSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth); writer.WriteSpace(); writer.Write("pinned", TextTokenType.Keyword); } else if (type is ArraySig) { ArraySig at = (ArraySig)type; at.Next.WriteTo(writer, syntaxForElementTypes, depth); writer.Write('[', TextTokenType.Operator); for (int i = 0; i < at.Rank; i++) { if (i != 0) { writer.Write(',', TextTokenType.Operator); writer.WriteSpace(); } int? lower = i < at.LowerBounds.Count ? at.LowerBounds[i] : (int?)null; uint?size = i < at.Sizes.Count ? at.Sizes[i] : (uint?)null; if (lower != null) { writer.Write(lower.ToString(), TextTokenType.Number); if (size != null) { writer.Write("..", TextTokenType.Operator); writer.Write((lower.Value + (int)size.Value - 1).ToString(), TextTokenType.Number); } else { writer.Write("...", TextTokenType.Operator); } } } writer.Write(']', TextTokenType.Operator); } else if (type is SZArraySig) { SZArraySig at = (SZArraySig)type; at.Next.WriteTo(writer, syntaxForElementTypes, depth); writer.Write("[]", TextTokenType.Operator); } else if (type is GenericSig) { if (((GenericSig)type).IsMethodVar) { writer.Write("!!", TextTokenType.Operator); } else { writer.Write("!", TextTokenType.Operator); } string typeName = type.TypeName; if (string.IsNullOrEmpty(typeName) || typeName[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(((GenericSig)type).Number.ToString(), TextTokenType.Number); } else { writer.Write(Escape(typeName), TextTokenHelper.GetTextTokenType(type)); } } else if (type is ByRefSig) { ((ByRefSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth); writer.Write('&', TextTokenType.Operator); } else if (type is PtrSig) { ((PtrSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth); writer.Write('*', TextTokenType.Operator); } else if (type is GenericInstSig) { ((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes, depth); writer.Write('<', TextTokenType.Operator); var arguments = ((GenericInstSig)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) { writer.Write(',', TextTokenType.Operator); writer.WriteSpace(); } arguments[i].WriteTo(writer, syntaxForElementTypes, depth); } writer.Write('>', TextTokenType.Operator); } else if (type is CModOptSig) { ((ModifierSig)type).Next.WriteTo(writer, syntax, depth); writer.WriteSpace(); writer.Write("modopt", TextTokenType.Keyword); writer.Write('(', TextTokenType.Operator); ((ModifierSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName, depth); writer.Write(')', TextTokenType.Operator); writer.WriteSpace(); } else if (type is CModReqdSig) { ((ModifierSig)type).Next.WriteTo(writer, syntax, depth); writer.WriteSpace(); writer.Write("modreq", TextTokenType.Keyword); writer.Write('(', TextTokenType.Operator); ((ModifierSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName, depth); writer.Write(')', TextTokenType.Operator); writer.WriteSpace(); } else if (type is TypeDefOrRefSig) { WriteTo(((TypeDefOrRefSig)type).TypeDefOrRef, writer, syntax, depth); } else if (type is FnPtrSig) { WriteTo(type.ToTypeDefOrRef(), writer, syntax, depth); } //TODO: SentinelSig }
static void AppendTypeName(StringBuilder b, TypeSig type) { type = type.RemovePinnedAndModifiers(); if (type is null) { return; } if (type is GenericInstSig giType) { AppendTypeNameWithArguments(b, giType.GenericType is null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments); return; } if (type is ArraySigBase arrayType) { AppendTypeName(b, arrayType.Next); b.Append('['); var lowerBounds = arrayType.GetLowerBounds(); var sizes = arrayType.GetSizes(); for (int i = 0; i < arrayType.Rank; i++) { if (i > 0) { b.Append(','); } if (i < lowerBounds.Count && i < sizes.Count) { b.Append(lowerBounds[i]); b.Append(':'); b.Append(sizes[i] + lowerBounds[i] - 1); } } b.Append(']'); return; } if (type is ByRefSig refType) { AppendTypeName(b, refType.Next); b.Append('@'); return; } if (type is PtrSig ptrType) { AppendTypeName(b, ptrType.Next); b.Append('*'); return; } if (type is GenericSig gp) { b.Append('`'); if (gp.IsMethodVar) { b.Append('`'); } b.Append(gp.Number); } else { var typeRef = type.ToTypeDefOrRef(); if (typeRef.DeclaringType is not null) { AppendTypeName(b, typeRef.DeclaringType.ToTypeSig()); b.Append('.'); b.Append(typeRef.Name); } else { FullNameFactory.FullNameSB(type, false, null, null, null, b); } } }
private TypeSig FindHookTypeSigRaw(TypeSig originalSig) => FindHookTypeDefRaw(originalSig.ToTypeDefOrRef()).ToTypeSig();
static void AppendTypeName(StringBuilder b, TypeSig type) { if (type == null) { // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies return; } if (type is GenericInstSig) { GenericInstSig giType = (GenericInstSig)type; AppendTypeNameWithArguments(b, giType.GenericType == null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments); return; } ArraySigBase arrayType = type as ArraySigBase; if (arrayType != null) { AppendTypeName(b, arrayType.Next); b.Append('['); var lowerBounds = arrayType.GetLowerBounds(); var sizes = arrayType.GetSizes(); for (int i = 0; i < arrayType.Rank; i++) { if (i > 0) { b.Append(','); } if (i < lowerBounds.Count && i < sizes.Count) { b.Append(lowerBounds[i]); b.Append(':'); b.Append(sizes[i] + lowerBounds[i] - 1); } } b.Append(']'); return; } ByRefSig refType = type as ByRefSig; if (refType != null) { AppendTypeName(b, refType.Next); b.Append('@'); return; } PtrSig ptrType = type as PtrSig; if (ptrType != null) { AppendTypeName(b, ptrType.Next); b.Append('*'); return; } GenericSig gp = type as GenericSig; if (gp != null) { b.Append('`'); if (gp.IsMethodVar) { b.Append('`'); } b.Append(gp.Number); } else { var typeRef = type.ToTypeDefOrRef(); if (typeRef.DeclaringType != null) { AppendTypeName(b, typeRef.DeclaringType.ToTypeSig()); b.Append('.'); b.Append(typeRef.Name); } else { b.Append(type.FullName); } } }
static void AppendTypeName(StringBuilder b, TypeSig type) { if (type == null) { // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies return; } if (type is GenericInstSig) { GenericInstSig giType = (GenericInstSig)type; AppendTypeNameWithArguments(b, giType.GenericType.TypeDefOrRef, giType.GenericArguments); return; } SZArraySig arrayType = type as SZArraySig; // TODO: multi-dimensional array if (arrayType != null) { AppendTypeName(b, arrayType.Next); b.Append("[]"); } ByRefSig refType = type as ByRefSig; if (refType != null) { AppendTypeName(b, refType.Next); b.Append('@'); } PtrSig ptrType = type as PtrSig; if (ptrType != null) { AppendTypeName(b, ptrType.Next); b.Append('*'); } GenericSig gp = type as GenericSig; if (gp != null) { b.Append('`'); if (gp.IsMethodVar) { b.Append('`'); } b.Append(gp.Number); } else { var typeRef = type.ToTypeDefOrRef(); var declType = Decompiler.DnlibExtensions.GetDeclaringType(typeRef); if (declType != null) { AppendTypeName(b, declType.ToTypeSig()); b.Append('.'); b.Append(typeRef.Name); } else { b.Append(type.FullName); } } }
public static string ParsedTypeSignatureStr(this TypeSig typeSig, bool useValueTypes = true, string context = null, bool typesOnly = false) { switch (typeSig.ElementType) { case ElementType.Object: return("DLL2SDK::mscorlib::System::Object"); case ElementType.String: return("DLL2SDK::mscorlib::System::String"); case ElementType.Void when useValueTypes: return("void"); case ElementType.Boolean when useValueTypes: return("bool"); case ElementType.Char when useValueTypes: return("wchar_t"); case ElementType.I1 when useValueTypes: return("int8_t"); case ElementType.U1 when useValueTypes: return("uint8_t"); case ElementType.I2 when useValueTypes: return("int16_t"); case ElementType.U2 when useValueTypes: return("uint16_t"); case ElementType.I4 when useValueTypes: return("int32_t"); case ElementType.U4 when useValueTypes: return("uint32_t"); case ElementType.I8 when useValueTypes: return("int64_t"); case ElementType.U8 when useValueTypes: return("uint64_t"); case ElementType.R4 when useValueTypes: return("float"); case ElementType.R8 when useValueTypes: return("double"); case ElementType.I when useValueTypes: return("intptr_t"); case ElementType.U when useValueTypes: return("uintptr_t"); } var underlying = typeSig.GetNonNestedTypeRefScope().ResolveTypeDef(); if (underlying?.IsEnum ?? false) { return(underlying.ParsedFullName()); } if (typeSig.IsArray || typeSig.IsSZArray) { return($"DLL2SDK::Array<{typeSig.Next.ParsedReferenceTypeDefinition(context: context)}>"); } if (typeSig.IsGenericParameter) { return(typeSig.ToGenericSig().GenericParam.Name.String.Parseable()); } var genericCtx = new List <string>(); if (typeSig.IsGenericInstanceType) { var gi = typeSig.ToGenericInstSig(); genericCtx = new List <string>(gi.GenericArguments.Count); foreach (var t in gi.GenericArguments) { genericCtx.Add(t.ParsedReferenceTypeDefinition(context: context)); } } var typeDef = typeSig.TryGetTypeDef(); if (typeDef?.HasGenericParameters ?? false) { var gi = typeDef.GenericParameters; genericCtx = new List <string>(gi.Count); foreach (var t in gi) { genericCtx.Add(t.Name.String.Parseable()); } } if (genericCtx.Count > 0) { var builder = new StringBuilder(); if (!typesOnly) { builder.Append(typeSig.ToTypeDefOrRef().ParsedFullName()); } if (context == null) { builder.Append("<"); builder.Append(string.Join(", ", genericCtx)); builder.Append(">"); } else { builder.Append(context); } return(builder.ToString()); } if (typeSig.IsByRef || typeSig.IsPointer) { return($"{typeSig.Next.ParsedTypeSignatureStr(context: context)}"); } return(typeSig.ToTypeDefOrRef().ParsedFullName()); }
private static void DumpType(TypeSig typeSig, StringBuilder sb, ObjectReader reader, string name, int indent, bool isRoot = false) { var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow(); if (typeSig.IsPrimitive) { object value = null; switch (typeSig.TypeName) { case "Boolean": value = reader.ReadBoolean(); break; case "Byte": value = reader.ReadByte(); break; case "SByte": value = reader.ReadSByte(); break; case "Int16": value = reader.ReadInt16(); break; case "UInt16": value = reader.ReadUInt16(); break; case "Int32": value = reader.ReadInt32(); break; case "UInt32": value = reader.ReadUInt32(); break; case "Int64": value = reader.ReadInt64(); break; case "UInt64": value = reader.ReadUInt64(); break; case "Single": value = reader.ReadSingle(); break; case "Double": value = reader.ReadDouble(); break; case "Char": value = reader.ReadChar(); break; } reader.AlignStream(4); sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}"); return; } if (typeSig.FullName == "System.String") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\""); return; } if (typeSig.FullName == "System.Object") { return; } if (typeDef.IsDelegate) { return; } if (typeSig is ArraySigBase) { if (!typeDef.IsEnum && !IsBaseType(typeDef) && !IsAssignFromUnityObject(typeDef) && !IsEngineType(typeDef) && !typeDef.IsSerializable) { return; } var size = reader.ReadInt32(); sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}Array Array"); sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}"); for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(typeDef.ToTypeSig(), sb, reader, "data", indent + 2); } return; } if (!isRoot && typeSig is GenericInstSig genericInstSig) { if (genericInstSig.GenericArguments.Count == 1) { var type = genericInstSig.GenericArguments[0].ToTypeDefOrRef().ResolveTypeDefThrow(); if (!type.IsEnum && !IsBaseType(type) && !IsAssignFromUnityObject(type) && !IsEngineType(type) && !type.IsSerializable) { return; } var size = reader.ReadInt32(); sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}Array Array"); sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}"); for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(genericInstSig.GenericArguments[0], sb, reader, "data", indent + 2); } } return; } if (indent != -1 && IsAssignFromUnityObject(typeDef)) { var pptr = reader.ReadPPtr(); sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}"); return; } if (typeDef.IsEnum) { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}"); return; } if (indent != -1 && !IsEngineType(typeDef) && !typeDef.IsSerializable) { return; } if (typeDef.FullName == "UnityEngine.Rect") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var rect = reader.ReadSingleArray(4); return; } if (typeDef.FullName == "UnityEngine.LayerMask") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var value = reader.ReadInt32(); return; } if (typeDef.FullName == "UnityEngine.AnimationCurve") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var animationCurve = new AnimationCurve <float>(reader, reader.ReadSingle); return; } if (typeDef.FullName == "UnityEngine.Gradient") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); if (reader.version[0] == 5 && reader.version[1] < 5) { reader.Position += 68; } else if (reader.version[0] == 5 && reader.version[1] < 6) { reader.Position += 72; } else { reader.Position += 168; } return; } if (typeDef.FullName == "UnityEngine.RectOffset") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var left = reader.ReadSingle(); var right = reader.ReadSingle(); var top = reader.ReadSingle(); var bottom = reader.ReadSingle(); return; } if (typeDef.FullName == "UnityEngine.GUIStyle") //TODO { throw new NotSupportedException(); } if (typeDef.IsClass || typeDef.IsValueType) { if (name != null && indent != -1) { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); } if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object") { DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true); } if (indent != -1 && typeDef.BaseType.FullName != "System.Object") { DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true); } foreach (var fieldDef in typeDef.Fields) { var access = fieldDef.Access & FieldAttributes.FieldAccessMask; if (access != FieldAttributes.Public) { if (fieldDef.CustomAttributes.Any(x => x.TypeFullName.Contains("SerializeField"))) { DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1); } } else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0 && (fieldDef.Attributes & FieldAttributes.NotSerialized) == 0) { DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1); } } } }
protected override ITypeDefOrRef ToType(TypeSig type) => type.ToTypeDefOrRef();
public Instructions Emit(OpCode opCode, TypeSig value) { return(Insert(Instruction.Create(opCode, value.ToTypeDefOrRef()))); }
private static void DumpType(TypeSig typeSig, StringBuilder sb, AssetsFile assetsFile, string name, int indent, bool isRoot = false) { var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow(); var reader = assetsFile.reader; if (typeDef.IsPrimitive) { object value = null; switch (typeDef.Name) { case "Boolean": value = reader.ReadBoolean(); break; case "Byte": value = reader.ReadByte(); break; case "SByte": value = reader.ReadSByte(); break; case "Int16": value = reader.ReadInt16(); break; case "UInt16": value = reader.ReadUInt16(); break; case "Int32": value = reader.ReadInt32(); break; case "UInt32": value = reader.ReadUInt32(); break; case "Int64": value = reader.ReadInt64(); break; case "UInt64": value = reader.ReadUInt64(); break; case "Single": value = reader.ReadSingle(); break; case "Double": value = reader.ReadDouble(); break; } reader.AlignStream(4); sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}"); return; } if (typeDef.FullName == "System.String") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\""); return; } if (typeDef.IsEnum) { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}"); return; } if (typeSig is ArraySigBase) { var size = reader.ReadInt32(); sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}Array Array"); sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}"); for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(typeDef.ToTypeSig(), sb, assetsFile, "data", indent + 2); } return; } if (!isRoot && typeSig is GenericInstSig genericInstSig) { var size = reader.ReadInt32(); sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}Array Array"); sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}"); if (genericInstSig.GenericArguments.Count == 1) //vector { for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(genericInstSig.GenericArguments[0], sb, assetsFile, "data", indent + 2); } } else if (genericInstSig.GenericArguments.Count == 2) //map { for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(genericInstSig.GenericArguments[0], sb, assetsFile, "first", indent + 2); DumpType(genericInstSig.GenericArguments[1], sb, assetsFile, "second", indent + 2); } } return; } if (indent != -1 && typeDef.FullName == "UnityEngine.Object") { var pptr = assetsFile.ReadPPtr(); sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}"); return; } if (indent != -1 && typeDef.BaseType != null && typeDef.BaseType.FullName != "System.Object") { var flag = false; var type = typeDef; while (true) { if (type.BaseType.FullName == "UnityEngine.Object") { flag = true; break; } type = type.BaseType.ResolveTypeDefThrow(); if (type.BaseType == null) { break; } } if (flag) { var pptr = assetsFile.ReadPPtr(); sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}"); return; } } if (typeDef.IsClass || typeDef.IsValueType) { if (name != null && indent != -1) { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); } if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object") { DumpType(typeDef.BaseType.ToTypeSig(), sb, assetsFile, null, indent, true); } if (indent != -1 && typeDef.BaseType.FullName != "System.Object") { DumpType(typeDef.BaseType.ToTypeSig(), sb, assetsFile, null, indent, true); } /*if (typeDef.FullName == "UnityEngine.AnimationCurve") //TODO * { * var AnimationCurve = new AnimationCurve<float>(reader, reader.ReadSingle, assetsFile.version); * }*/ foreach (var fieldDef in typeDef.Fields) { var access = fieldDef.Access & FieldAttributes.FieldAccessMask; if (access != FieldAttributes.Public) { if (fieldDef.CustomAttributes.Any(x => x.TypeFullName.Contains("SerializeField"))) { DumpType(fieldDef.FieldType, sb, assetsFile, fieldDef.Name, indent + 1); } } else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0) { DumpType(fieldDef.FieldType, sb, assetsFile, fieldDef.Name, indent + 1); } } } }
private static void DumpType(TypeSig typeSig, StringBuilder sb, ObjectReader reader, string name, int indent, bool isRoot = false, bool align = true) { var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow(); if (typeSig.IsPrimitive) { object value = null; switch (typeSig.TypeName) { case "Boolean": value = reader.ReadBoolean(); break; case "Byte": value = reader.ReadByte(); break; case "SByte": value = reader.ReadSByte(); break; case "Int16": value = reader.ReadInt16(); break; case "UInt16": value = reader.ReadUInt16(); break; case "Int32": value = reader.ReadInt32(); break; case "UInt32": value = reader.ReadUInt32(); break; case "Int64": value = reader.ReadInt64(); break; case "UInt64": value = reader.ReadUInt64(); break; case "Single": value = reader.ReadSingle(); break; case "Double": value = reader.ReadDouble(); break; case "Char": value = reader.ReadChar(); break; } if (align) { reader.AlignStream(); } sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}"); return; } if (typeSig.FullName == "System.String") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\""); return; } if (typeSig.FullName == "System.Object") { return; } if (typeDef.IsDelegate) { return; } if (typeSig is ArraySigBase) { if (!typeDef.IsEnum && !IsBaseType(typeDef) && !IsAssignFromUnityObject(typeDef) && !IsEngineType(typeDef) && !typeDef.IsSerializable) { return; } var size = reader.ReadInt32(); sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}"); for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(typeDef.ToTypeSig(), sb, reader, "data", indent + 2); } return; } if (!isRoot && typeSig is GenericInstSig genericInstSig) { if (genericInstSig.GenericArguments.Count == 1) { var genericType = genericInstSig.GenericType.ToTypeDefOrRef().ResolveTypeDefThrow(); var type = genericInstSig.GenericArguments[0].ToTypeDefOrRef().ResolveTypeDefThrow(); if (genericInstSig.GenericArguments[0] is ArraySigBase) { return; } if (!type.IsEnum && !IsBaseType(type) && !IsAssignFromUnityObject(type) && !IsEngineType(type) && !type.IsSerializable) { return; } sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}"); if (genericType.Interfaces.Any(x => x.Interface.FullName == "System.Collections.Generic.ICollection`1<T>")) //System.Collections.Generic.IEnumerable`1<T> { var size = reader.ReadInt32(); sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}"); for (int i = 0; i < size; i++) { sb.AppendLine($"{new string('\t', indent + 2)}[{i}]"); DumpType(genericInstSig.GenericArguments[0], sb, reader, "data", indent + 2, false, false); } reader.AlignStream(); } else { DumpType(genericType.ToTypeSig(), sb, reader, "data", indent + 1); } } return; } if (indent != -1 && IsAssignFromUnityObject(typeDef)) { var pptr = new PPtr <Object>(reader); sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}"); return; } if (typeDef.IsEnum) { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}"); return; } if (!isRoot && !IsEngineType(typeDef) && !typeDef.IsSerializable) { return; } if (typeDef.FullName == "UnityEngine.Rect") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var prefix = new string('\t', indent + 1); sb.AppendLine($"{prefix}float x = {reader.ReadSingle()}"); sb.AppendLine($"{prefix}float y = {reader.ReadSingle()}"); sb.AppendLine($"{prefix}float width = {reader.ReadSingle()}"); sb.AppendLine($"{prefix}float height = {reader.ReadSingle()}"); return; } if (typeDef.FullName == "UnityEngine.LayerMask") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}uint m_Bits = {reader.ReadUInt32()}"); return; } if (typeDef.FullName == "UnityEngine.AnimationCurve") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}<truncated>"); var animationCurve = new AnimationCurve <float>(reader, reader.ReadSingle); return; } if (typeDef.FullName == "UnityEngine.Gradient") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}<truncated>"); if (reader.version[0] == 5 && reader.version[1] < 5) { reader.Position += 68; } else if (reader.version[0] == 5 && reader.version[1] < 6) { reader.Position += 72; } else { reader.Position += 168; } return; } if (typeDef.FullName == "UnityEngine.RectOffset") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var prefix = new string('\t', indent + 1); sb.AppendLine($"{prefix}float left = {reader.ReadSingle()}"); sb.AppendLine($"{prefix}float right = {reader.ReadSingle()}"); sb.AppendLine($"{prefix}float top = {reader.ReadSingle()}"); sb.AppendLine($"{prefix}float bottom = {reader.ReadSingle()}"); return; } if (typeDef.FullName == "UnityEngine.PropertyName") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}int id = {reader.ReadInt32()}"); return; } if (typeDef.FullName == "UnityEngine.Color32") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var prefix = new string('\t', indent + 1); sb.AppendLine($"{prefix}byte r = {reader.ReadByte()}"); sb.AppendLine($"{prefix}byte g = {reader.ReadByte()}"); sb.AppendLine($"{prefix}byte b = {reader.ReadByte()}"); sb.AppendLine($"{prefix}byte a = {reader.ReadByte()}"); reader.AlignStream(); return; } if (typeDef.FullName == "UnityEngine.Vector2Int") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var prefix = new string('\t', indent + 1); sb.AppendLine($"{prefix}int x = {reader.ReadInt32()}"); sb.AppendLine($"{prefix}int y = {reader.ReadInt32()}"); return; } if (typeDef.FullName == "UnityEngine.Vector3Int") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); var prefix = new string('\t', indent + 1); sb.AppendLine($"{prefix}int x = {reader.ReadInt32()}"); sb.AppendLine($"{prefix}int y = {reader.ReadInt32()}"); sb.AppendLine($"{prefix}int z = {reader.ReadInt32()}"); return; } if (typeDef.FullName == "UnityEngine.Bounds") { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); sb.AppendLine($"{new string('\t', indent + 1)}<truncated>"); new AABB(reader); return; } if (typeDef.FullName == "UnityEngine.GUIStyle") //TODO { throw new NotSupportedException(); } if (typeDef.IsClass || typeDef.IsValueType) { if (name != null && indent != -1) { sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}"); } if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object") { DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true); } if (indent != -1 && typeDef.BaseType.FullName != "System.Object") { DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true); } foreach (var fieldDef in typeDef.Fields) { var flag = false; var access = fieldDef.Access & FieldAttributes.FieldAccessMask; if (access != FieldAttributes.Public) { if (fieldDef.CustomAttributes.Any(x => x.TypeFullName == "UnityEngine.SerializeField")) { flag = true; } } else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0 && (fieldDef.Attributes & FieldAttributes.NotSerialized) == 0) { flag = true; } if (flag) { if (fieldDef.FieldType.IsGenericParameter) { for (var i = 0; i < typeDef.GenericParameters.Count; i++) { var g = typeDef.GenericParameters[i]; if (g.FullName == fieldDef.FieldType.FullName) { var type = ((GenericInstSig)typeSig).GenericArguments[i]; DumpType(type, sb, reader, fieldDef.Name, indent + 1); break; } } } else { DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1); } } } } }
public bool Restore(MethodDef method) { this.method = method; bool atLeastOneFailed = false; if (method == null || method.Body == null) { return(!atLeastOneFailed); } var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.Operand != null) { continue; } TypeSig operandType = null, operandTypeTmp; OpCode newOpCode = null; SZArraySig arrayType; switch (instr.OpCode.Code) { case Code.Ldelem: arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig; if (arrayType == null) { break; } operandTypeTmp = arrayType.Next; if (operandTypeTmp == null) { newOpCode = OpCodes.Ldelem_Ref; } else { switch (operandTypeTmp.ElementType) { case ElementType.Boolean: newOpCode = OpCodes.Ldelem_I1; break; case ElementType.Char: newOpCode = OpCodes.Ldelem_U2; break; case ElementType.I: newOpCode = OpCodes.Ldelem_I; break; case ElementType.I1: newOpCode = OpCodes.Ldelem_I1; break; case ElementType.I2: newOpCode = OpCodes.Ldelem_I2; break; case ElementType.I4: newOpCode = OpCodes.Ldelem_I4; break; case ElementType.I8: newOpCode = OpCodes.Ldelem_I8; break; case ElementType.U: newOpCode = OpCodes.Ldelem_I; break; case ElementType.U1: newOpCode = OpCodes.Ldelem_U1; break; case ElementType.U2: newOpCode = OpCodes.Ldelem_U2; break; case ElementType.U4: newOpCode = OpCodes.Ldelem_U4; break; case ElementType.U8: newOpCode = OpCodes.Ldelem_I8; break; case ElementType.R4: newOpCode = OpCodes.Ldelem_R4; break; case ElementType.R8: newOpCode = OpCodes.Ldelem_R8; break; default: newOpCode = OpCodes.Ldelem_Ref; break; //TODO: Ldelem } } break; case Code.Stelem: arrayType = MethodStack.GetLoadedType(method, instrs, i, 2) as SZArraySig; if (arrayType == null) { break; } operandTypeTmp = arrayType.Next; if (operandTypeTmp == null) { newOpCode = OpCodes.Stelem_Ref; } else { switch (operandTypeTmp.ElementType) { case ElementType.U: case ElementType.I: newOpCode = OpCodes.Stelem_I; break; case ElementType.Boolean: case ElementType.U1: case ElementType.I1: newOpCode = OpCodes.Stelem_I1; break; case ElementType.Char: case ElementType.U2: case ElementType.I2: newOpCode = OpCodes.Stelem_I2; break; case ElementType.U4: case ElementType.I4: newOpCode = OpCodes.Stelem_I4; break; case ElementType.U8: case ElementType.I8: newOpCode = OpCodes.Stelem_I8; break; case ElementType.R4: newOpCode = OpCodes.Stelem_R4; break; case ElementType.R8: newOpCode = OpCodes.Stelem_R8; break; default: newOpCode = OpCodes.Stelem_Ref; break; //TODO: Stelem } } break; case Code.Ldelema: arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig; if (arrayType == null) { break; } operandType = arrayType.Next; break; case Code.Ldobj: operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 0)); break; case Code.Stobj: operandType = MethodStack.GetLoadedType(method, instrs, i, 0); if (!IsValidType(operandType)) { operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 1)); } break; default: continue; } if (newOpCode == null && !IsValidType(operandType)) { atLeastOneFailed = true; continue; } instr.Operand = operandType.ToTypeDefOrRef(); if (newOpCode != null) { instr.OpCode = newOpCode; } } return(!atLeastOneFailed); }
protected override ITypeDefOrRef ToType(TypeSig type) { return(type.ToTypeDefOrRef()); }
static TypeSig ICast/* needs a better name */ (TypeSig a, TypeSig b, ICorLibTypes ts) { if (comp.Equals(a, b)) { return(a); } if (comp.Equals(a, ts.String)) { return(a); } if (comp.Equals(b, ts.String)) { return(b); } if (comp.Equals(a, ts.IntPtr) || comp.Equals(a, ts.UIntPtr)) { return(a); } if (comp.Equals(b, ts.IntPtr) || comp.Equals(b, ts.UIntPtr)) { return(b); } if (comp.Equals(a, ts.Double)) { return(a); } if (comp.Equals(b, ts.Double)) { return(b); } if (comp.Equals(a, ts.Single)) { return(a); } if (comp.Equals(b, ts.Single)) { return(b); } if (comp.Equals(a, ts.Int64) || comp.Equals(a, ts.UInt64)) { return(a); } if (comp.Equals(b, ts.Int64) || comp.Equals(b, ts.UInt64)) { return(b); } if (!a.IsByRef || !b.IsByRef) { return(ts.Object); } var ad = a.ToTypeDefOrRef().ResolveTypeDefThrow(); var bd = b.ToTypeDefOrRef().ResolveTypeDefThrow(); if ((!ad.IsSequentialLayout || !ad.IsExplicitLayout) && (!bd.IsSequentialLayout || !bd.IsExplicitLayout)) { return(ts.IntPtr); } // close enough return(ad.PackingSize > bd.PackingSize ? a : b); }
private int ProcessMethod(MethodDef md) { List <GenInfo> toPatch = new List <GenInfo>(); if (!md.HasGenericParameters) { return(0); } List <MethodSpec> callers = FindCallingSpecs(md); if (callers.Count == 0) { return(0); } Dictionary <int, TypeSig> locals = new Dictionary <int, TypeSig>(); for (int i = 0; i < callers.Count; i++) { MethodSpec spec = callers[i]; for (int x = 0; x < md.Body.Variables.Count; x++) { Local l = md.Body.Variables[x]; if (!l.Type.IsGenericMethodParameter) { continue; } if (!(l.Type is GenericSig)) { continue; } GenericSig gSig = l.Type as GenericSig; GenericParam gParam = md.GenericParameters.Where(y => y.Number == gSig.Number).FirstOrDefault(); int indexOf = md.GenericParameters.IndexOf(gParam); if (gSig.Number > spec.GenericInstMethodSig.GenericArguments.Count - 1 || gSig.Number < 0) { continue; } TypeSig tSig = spec.GenericInstMethodSig.GenericArguments[(int)gSig.Number]; ITypeDefOrRef c**t = tSig.ToTypeDefOrRef(); ITypeDefOrRef tRef = c**t.ScopeType; if (tSig.IsSZArray) { } l.Type = tRef.ToTypeSig(); if (locals.ContainsKey(l.Index)) { if (locals[l.Index] == tRef.ToTypeSig()) { continue; } else { locals[l.Index] = tRef.ToTypeSig(); } } else { locals.Add(l.Index, tRef.ToTypeSig()); } //md.GenericParameters.Remove(gParam); } } if (locals.Count == 0) { return(0); } Dictionary <int, Local> newLocals = new Dictionary <int, Local>(); foreach (var pair in locals) { int index = pair.Key; TypeSig tSig = pair.Value; Local newLocal = new Local(tSig); //newLocal.Name = "TESTING!!!" + Guid.NewGuid().ToString(); newLocal.Index = index; newLocals.Add(index, newLocal); } for (int i = 0; i < md.Body.Instructions.Count; i++) { Instruction inst = md.Body.Instructions[i]; if (inst.OpCode == OpCodes.Stloc || inst.OpCode == OpCodes.Ldloc) { Local l = inst.Operand as Local; if (newLocals.ContainsKey(l.Index)) { md.Body.Instructions[i].Operand = newLocals[l.Index]; } } } md.Body.Variables.Clear(); foreach (var pair in newLocals) { md.Body.Variables.Add(pair.Value); } // New local is not added at all, it is simply f****d. if (md.Name == "") { } /*for (int i = 0; i < md.Body.Variables.Count; i++) * { * Local l = md.Body.Variables[i]; * * if (!l.Type.IsGenericMethodParameter) * { * continue; * } * if (!(l.Type is GenericSig)) * { * continue; * } * * if (locals.ContainsKey(l)) * { * md.Body.Variables[i].Type = locals[l]; * } * }*/ /*for (int i = 0; i < md.Body.Instructions.Count; i++) * { * Instruction inst = md.Body.Instructions[i]; * * // If it is a generic method * if (inst.Operand != null && inst.Operand is MethodSpec) * { * // Investigate the method body to see if all locals are outlined, use gen param count vs local count...? * // If it is the same then we know that there are variables to outline. Next is trying to identify when a legitimate generic type is there... * // We need to collate them into a list so we can link how many have the same generic sig types listed * // (a generic should technically have several different types). * * * MethodSpec mSpec = inst.Operand as MethodSpec; * if (mSpec == null) * { * // Failsafe check * continue; * } * * MethodDef mDef = mSpec.ResolveMethodDef(); * if (mDef == null) * { * Logger.Log(this, string.Format("Resolved MethodDef is null for {0}", mSpec)); * continue; * } * * if (mDef.Body == null) * { * continue; * } * * int lCount = mDef.Body.Variables.Count; * int gpCount = mSpec.GenericInstMethodSig.GenericArguments.Count; * * * * toPatch.Add(new GenInfo() { CallingInst = inst, GenCount = gpCount, LocalCount = lCount, RawMethod = mDef, TargetGeneric = mSpec, * GenericArgs = mSpec.GenericInstMethodSig.GenericArguments.ToList(), * CallIndex = i, * ParentMethod = md}); * * } * }*/ List <GenInfo> Completed = new List <GenInfo>(); //Completed.AddRange(toPatch); foreach (GenInfo inf in toPatch) { // Get count of other similar generic instances // ... should put in a dictionary the link between the method, and numbers. // Let's get it working without that for now // get generic param from generic arg // Go to local, go to type, cast type to genericsig. // You can then get the 'number' which corresponds to the generic parameter on the raw method // Relate that back to the index on the locals maybe? bool comp = false; List <GenericParam> toDelete = new List <GenericParam>(); List <Local> toAdd = new List <Local>(); for (int i = 0; i < inf.RawMethod.Body.Variables.Count; i++) { Local l = inf.RawMethod.Body.Variables[i]; if (!l.Type.IsGenericMethodParameter) { continue; } if (!(l.Type is GenericSig)) { continue; } GenericSig gSig = l.Type as GenericSig; if (gSig.Number > inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Count - 1 || gSig.Number < 0) { continue; } TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[(int)gSig.Number]; if (inf.RawMethod.Name == "method_1") { } if (tSig.IsGenericParameter) { } if (tSig == null) { continue; } ((MethodDef)inf.TargetGeneric.Method).Body.Variables[i].Type = tSig; ((MethodDef)inf.TargetGeneric.Method).Body.Variables[i].Name = "CANCER_" + Guid.NewGuid().ToString(); //toAdd.Add(new Local(tSig)); } //toAdd.ForEach(x => ((MethodDef)inf.TargetGeneric.Method).Body.Variables.Add(x)); /*for (int i = 0; i < inf.RawMethod.Parameters.Count; i++) * { * Parameter param = inf.RawMethod.Parameters[i]; * * if (!param.Type.IsGenericParameter) * continue; * * * GenericSig gSig = param.Type.ToGenericSig(); * * TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[(int)gSig.Number]; * * if (tSig == null) * continue; * * if (inf.RawMethod.Name == "method_4") * { * * } * if (tSig.IsGenericParameter) * continue; * param.Type = tSig; * * //toDelete.Add(inf.RawMethod.GenericParameters.Where(x => x.Number == gSig.Number).FirstOrDefault()); * * * }*/ /*for (int i = 0; i < inf.RawMethod.GenericParameters.Count; i++) * { * GenericParam gParam = inf.RawMethod.GenericParameters[i]; * * * TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[i]; * * if (tSig == null) * continue; * * MethodDef mDef = inf.TargetGeneric.Method as MethodDef; * * Parameter p = mDef.Parameters.Where(x => !x.IsHiddenThisParameter && x.Type.FullName == gParam.FullName).FirstOrDefault(); * * * if (p == null) * { * continue; * } * * p.Type = tSig; * * toDelete.Add(gParam); * * * }*/ toDelete.ForEach(x => inf.RawMethod.GenericParameters.Remove(x)); /*for (int i = 0; i < inf.RawMethod.Body.Variables.Count; i++) * { * Local l = inf.RawMethod.Body.Variables[i]; * * if (!l.Type.IsGenericMethodParameter) * { * continue; * } * if (!(l.Type is GenericSig)) * { * continue; * } * * GenericSig gSig = l.Type as GenericSig; * //if (gSig.Number > inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Count - 1) * // continue; * TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Where( * (x) => * { * if (!x.IsGenericMethodParameter) * return false; * * GenericSig gSig2 = x.ToGenericSig(); * if (gSig2 == null) * return false; * * return gSig2.Number == gSig.Number; * //return true; * } * ).FirstOrDefault(); * * if (tSig == null) * continue; * * inf.RawMethod.Body.Variables[i].Type = tSig; * * comp = true; * } * * if (comp) * Completed.Add(inf);*/ } return(Completed.Count); }
static TypeSig GetCommonBaseClass(ModuleDef module, TypeSig a, TypeSig b) { if (DotNetUtils.IsDelegate(a) && DotNetUtils.DerivesFromDelegate(module.Find(b.ToTypeDefOrRef()))) { return(b); } if (DotNetUtils.IsDelegate(b) && DotNetUtils.DerivesFromDelegate(module.Find(a.ToTypeDefOrRef()))) { return(a); } return(null); //TODO: }
void ManualFixes(ModuleDefMD mod) { var UMM = mod.Find("UnityModManagerNet.UnityModManager", false); if (UMM != null) { mod.Types.Remove(UMM); } //Fix Base Constructor var UnitInteractWithObject = mod.Find("Kingmaker.UnitLogic.Commands.UnitInteractWithObject", false); if (UnitInteractWithObject != null) { var UnitCommand = mod.Find("Kingmaker.UnitLogic.Commands.Base.UnitCommand", false); var baseCtor = UnitCommand.FindMethod(".ctor"); var ctor = UnitInteractWithObject.FindMethod(".ctor"); ReplaceBody(ctor.Body, new List <Instruction>() { OpCodes.Ldarg_0.ToInstruction(), OpCodes.Ldc_I4_1.ToInstruction(), OpCodes.Ldnull.ToInstruction(), OpCodes.Call.ToInstruction(baseCtor), OpCodes.Ret.ToInstruction() }); } //Remove type var ExampleSelectable = mod.Find("UnityEngine.UI.Extensions.ExampleSelectable", false); if (ExampleSelectable != null) { mod.Types.Remove(ExampleSelectable); } //Remove override property var QuickGraphQueue = mod.Find("QuickGraph.Collections.Queue`1", false); if (QuickGraphQueue != null) { var method = QuickGraphQueue.FindMethod("QuickGraph.Collections.IQueue.get_Count"); QuickGraphQueue.Methods.Remove(method); } /* Remove block from QuickGraph.Collections * Comparer<TKey> @default = Comparer<TKey>.Default; * this._002Ector(maximumErrorRate, keyMaxValue, (Func<TKey, TKey, int>)@default.Compare); */ var BidirectionAdapterGraph = mod.Find("QuickGraph.BidirectionAdapterGraph`2", false); if (BidirectionAdapterGraph != null) { ClearMethod(BidirectionAdapterGraph.FindMethod(".ctor")); } var BinaryHeap = mod.Find("QuickGraph.Collections.BinaryHeap`2", false); if (BinaryHeap != null) { ClearMethod(BinaryHeap.FindMethod(".ctor")); } var FibonacciHeap = mod.Find("QuickGraph.Collections.FibonacciHeap`2", false); if (FibonacciHeap != null) { foreach (var ctor in FibonacciHeap.Methods.Where(m => m.Name == ".ctor")) { ClearMethod(ctor); } } var FibonacciQueue = mod.Find("QuickGraph.Collections.FibonacciQueue`2", false); if (FibonacciQueue != null) { foreach (var ctor in FibonacciQueue.Methods.Where(m => m.Name == ".ctor")) { ClearMethod(ctor); } } var BinaryQueue = mod.Find("QuickGraph.Collections.BinaryQueue`2", false); if (BinaryQueue != null) { ClearMethod(BinaryQueue.FindMethod(".ctor")); } var SoftHeap = mod.Find("QuickGraph.Collections.SoftHeap`2", false); if (SoftHeap != null) { ClearMethod(SoftHeap.FindMethod(".ctor")); } foreach (var type in mod.Types.ToArray()) { if (type.Namespace == "ProBuilder2.Examples") { mod.Types.Remove(type); } } //Positional Arguments var CameraController = mod.Find("Kingmaker.Controllers.Rest.CameraController", false); if (CameraController != null) { CameraController.Remove(CameraController.FindMethod(".ctor")); } var KingdomCameraController = mod.Find("Kingmaker.Controllers.KingdomCameraController", false); if (KingdomCameraController != null) { KingdomCameraController.Remove(KingdomCameraController.FindMethod(".ctor")); } //Clear cctor var DefaultJsonSettings = mod.Find("Kingmaker.EntitySystem.Persistence.JsonUtility.DefaultJsonSettings", false); if (DefaultJsonSettings != null) { ClearMethod(DefaultJsonSettings.FindMethod(".cctor")); } //Change UnitPartVisualChanges.SourceBone from Boo.List to System.List var UnitPartVisualChanges = mod.Find("Kingmaker.UnitLogic.Parts.UnitPartVisualChanges", false); if (DefaultJsonSettings != null) { var booList = UnitPartVisualChanges.FindField("SourceBone"); Importer importer = new Importer(mod); TypeSig listGenericInstSig = importer.ImportAsTypeSig(typeof(System.Collections.Generic.List <String>)); booList.FieldSig = new FieldSig(listGenericInstSig); var ctor = UnitPartVisualChanges.FindMethod(".ctor"); foreach (var inst in ctor.Body.Instructions.ToArray()) { if (inst.OpCode == OpCodes.Newobj && inst.Operand is MemberRef memberRef) { memberRef.Class = listGenericInstSig.ToTypeDefOrRef(); } } } }
static Instruction LoadIndirect(TypeSig type) { switch (type.GetElementType()) { case ElementType.Boolean: return(Instruction.Create(OpCodes.Ldind_I1)); case ElementType.Char: return(Instruction.Create(OpCodes.Ldind_U2)); case ElementType.I1: return(Instruction.Create(OpCodes.Ldind_I1)); case ElementType.U1: return(Instruction.Create(OpCodes.Ldind_U1)); case ElementType.I2: return(Instruction.Create(OpCodes.Ldind_I2)); case ElementType.U2: return(Instruction.Create(OpCodes.Ldind_U2)); case ElementType.I4: return(Instruction.Create(OpCodes.Ldind_I4)); case ElementType.U4: return(Instruction.Create(OpCodes.Ldind_U4)); case ElementType.I8: return(Instruction.Create(OpCodes.Ldind_I8)); case ElementType.U8: return(Instruction.Create(OpCodes.Ldind_I8)); case ElementType.R4: return(Instruction.Create(OpCodes.Ldind_R4)); case ElementType.R8: return(Instruction.Create(OpCodes.Ldind_R8)); case ElementType.String: return(Instruction.Create(OpCodes.Ldind_Ref)); case ElementType.I: return(Instruction.Create(OpCodes.Ldind_I)); case ElementType.U: return(Instruction.Create(OpCodes.Ldind_I)); case ElementType.ValueType: return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef())); case ElementType.Class: return(Instruction.Create(OpCodes.Ldind_Ref)); case ElementType.Array: return(Instruction.Create(OpCodes.Ldind_Ref)); case ElementType.Object: return(Instruction.Create(OpCodes.Ldind_Ref)); case ElementType.SZArray: return(Instruction.Create(OpCodes.Ldind_Ref)); case ElementType.Ptr: return(Instruction.Create(OpCodes.Ldind_I)); case ElementType.FnPtr: return(Instruction.Create(OpCodes.Ldind_I)); case ElementType.Var: return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef())); case ElementType.MVar: return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef())); case ElementType.TypedByRef: return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef())); case ElementType.GenericInst: var gis = type as GenericInstSig; if (gis.GenericType.IsValueTypeSig) { return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef())); } return(Instruction.Create(OpCodes.Ldind_Ref)); case ElementType.End: case ElementType.Void: case ElementType.ByRef: case ElementType.ValueArray: case ElementType.R: case ElementType.CModReqd: case ElementType.CModOpt: case ElementType.Internal: case ElementType.Module: case ElementType.Sentinel: case ElementType.Pinned: default: return(Instruction.Create(OpCodes.Nop)); } }
/// <summary> /// Relocates the <see cref="TypeSig"/>. /// </summary> /// <param name="typeSig">The type sig.</param> /// <returns>A new type if it was relocated, null otherwise</returns> /// <exception cref="InvalidOperationException">If signature is of unknown type.</exception> public virtual TypeSig TryRelocateTypeSig(TypeSig typeSig) { if (typeSig == null) { return(null); } if (typeSig is CorLibTypeSig corLibTypeSig) { return(TryRelocateCorLibTypeSig(corLibTypeSig)); } if (typeSig is GenericInstSig genericInstSig) { return(TryRelocateGeneric(genericInstSig)); } //if (typeSig is PtrSig) // return null; if (typeSig is ByRefSig byRefSig) { return(TryRelocateByRef(byRefSig)); } if (typeSig is ArraySig arraySig) { return(TryRelocateArray(arraySig)); } if (typeSig is SZArraySig szArraySig) { return(TryRelocateSZArray(szArraySig)); } if (typeSig is GenericVar) { return(null); // TODO constraints } if (typeSig is GenericMVar) { return(null); // TODO constraints } if (typeSig is ClassOrValueTypeSig) { var typeRef = typeSig.TryGetTypeRef(); var typeDefOrRef = typeRef != null?TryRelocateTypeRef(typeRef) : TryRelocateTypeDefOrRef(typeSig.ToTypeDefOrRef()); if (typeDefOrRef == null) { return(null); } if (typeSig is ValueTypeSig) { return(new ValueTypeSig(typeDefOrRef)); } return(typeDefOrRef.ToTypeSig()); } if (typeSig is CModOptSig cModOptSig) { var next = TryRelocateTypeSig(cModOptSig.Next); var modifier = TryRelocateTypeDefOrRef(cModOptSig.Modifier); if (next == null && modifier == null) { return(null); } return(new CModOptSig(modifier ?? cModOptSig.Modifier, next ?? cModOptSig.Next)); } if (typeSig is CModReqdSig cModReqdSig) { var next = TryRelocateTypeSig(cModReqdSig.Next); var modifier = TryRelocateTypeDefOrRef(cModReqdSig.Modifier); if (next == null && modifier == null) { return(null); } return(new CModReqdSig(modifier ?? cModReqdSig.Modifier, next ?? cModReqdSig.Next)); } if (typeSig is FnPtrSig) { return(null); // TODO } if (typeSig is PtrSig) { var next = TryRelocateTypeSig(typeSig.Next); return(next != null ? new PtrSig(next) : null); } if (typeSig is PinnedSig) { var next = TryRelocateTypeSig(typeSig.Next); return(next != null ? new PinnedSig(next) : null); } throw new InvalidOperationException($"type {typeSig.GetType()} not supported (MoFo)"); }