public static void InstantiateSecurityAttributes() { var t = new SecurityTreatAsSafeAttribute(); var u = new SecuritySafeCriticalAttribute(); var v = new SecurityTransparentAttribute(); var w = new SecurityCriticalAttribute(); var x = new SuppressUnmanagedCodeSecurityAttribute(); var y = new UnverifiableCodeAttribute(); var z = new AllowPartiallyTrustedCallersAttribute(); }
public static void exportTranspiledMethods() { AssemblyName aName = new AssemblyName("RimWorldTranspiles"); //PermissionSet requiredPermission = new PermissionSet(PermissionState.Unrestricted); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave); ConstructorInfo Constructor2 = typeof(SecurityPermissionAttribute).GetConstructors()[0]; SecurityAction requestMinimum = SecurityAction.RequestMinimum; PropertyInfo skipVerificationProperty = Property(typeof(SecurityPermissionAttribute), "SkipVerification"); CustomAttributeBuilder sv2 = new CustomAttributeBuilder(Constructor2, new object[] { requestMinimum }, new PropertyInfo[] { skipVerificationProperty }, new object[] { true }); ab.SetCustomAttribute(sv2); //System.Security.AllowPartiallyTrustedCallersAttribute Att = new System.Security.AllowPartiallyTrustedCallersAttribute(); //ConstructorInfo Constructor1 = Att.GetType().GetConstructors()[0]; //object[] ObjectArray1 = new object[0]; //CustomAttributeBuilder AttribBuilder1 = new CustomAttributeBuilder(Constructor1, ObjectArray1); //ab.SetCustomAttribute(AttribBuilder1); ModuleBuilder modBuilder = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); UnverifiableCodeAttribute ModAtt = new System.Security.UnverifiableCodeAttribute(); ConstructorInfo Constructor = ModAtt.GetType().GetConstructors()[0]; object[] ObjectArray = new object[0]; CustomAttributeBuilder ModAttribBuilder = new CustomAttributeBuilder(Constructor, ObjectArray); modBuilder.SetCustomAttribute(ModAttribBuilder); Dictionary <string, TypeBuilder> typeBuilders = new Dictionary <string, TypeBuilder>(); IEnumerable <MethodBase> originalMethods = Harmony.GetAllPatchedMethods(); foreach (MethodBase originalMethod in originalMethods) { Patches patches = Harmony.GetPatchInfo(originalMethod); int transpiledCount = patches.Transpilers.Count; if (transpiledCount == 0) { continue; } if (originalMethod is MethodInfo methodInfo) // add support for constructors as well { Type returnType = methodInfo.ReturnType; string typeTranspiled = originalMethod.DeclaringType.FullName + "_Transpiled"; if (!typeBuilders.TryGetValue(typeTranspiled, out TypeBuilder tb)) { tb = modBuilder.DefineType(typeTranspiled, TypeAttributes.Public); typeBuilders[typeTranspiled] = tb; } ParameterInfo[] parameterInfos = methodInfo.GetParameters(); List <Type> types = new List <Type>(); int parameterOffset = 1; if (!methodInfo.Attributes.HasFlag(MethodAttributes.Static)) { types.Add(methodInfo.DeclaringType); parameterOffset = 2; } foreach (ParameterInfo parameterInfo in parameterInfos) { types.Add(parameterInfo.ParameterType); } MethodBuilder mb = tb.DefineMethod(originalMethod.Name, MethodAttributes.Public | MethodAttributes.Static, returnType, types.ToArray()); if (typeTranspiled.Equals("Verse.PawnGenerator_Transpiled") && !originalMethod.Name.Equals("")) { Log.Message(originalMethod.Name); } if (!methodInfo.Attributes.HasFlag(MethodAttributes.Static)) { ParameterAttributes pa = new ParameterAttributes(); ParameterBuilder pb = mb.DefineParameter(1, pa, methodInfo.DeclaringType.Name); } foreach (ParameterInfo parameterInfo in parameterInfos) { ParameterAttributes pa = new ParameterAttributes(); if (parameterInfo.IsOut) { pa |= ParameterAttributes.Out; } if (parameterInfo.IsIn) { pa |= ParameterAttributes.In; } if (parameterInfo.IsLcid) { pa |= ParameterAttributes.Lcid; } if (parameterInfo.IsOptional) { pa |= ParameterAttributes.Optional; } if (parameterInfo.IsRetval) { pa |= ParameterAttributes.Retval; } if (parameterInfo.HasDefaultValue) { pa |= ParameterAttributes.HasDefault; } ParameterBuilder pb = mb.DefineParameter(parameterInfo.Position + parameterOffset, pa, parameterInfo.Name); if (parameterInfo.HasDefaultValue && parameterInfo.DefaultValue != null) { pb.SetConstant(parameterInfo.DefaultValue); } } ILGenerator il = mb.GetILGenerator(); //il.Emit(OpCodes.Nop); //MethodCopier methodCopier = new MethodCopier(originalMethod, il); //List<Label> endLabels = new List<Label>(); //_ = methodCopier.Finalize(null, endLabels, out var hasReturnCode); //List<CodeInstruction> ciList = MethodCopier.GetInstructions(il, originalMethod, 9999); MethodInfo methodInfo2 = UpdateWrapper(originalMethod, il); //Log.Message(ciList.ToString()); //List<CodeInstruction> currentInstructions = PatchProcessor.GetCurrentInstructions(originalMethod); //Dictionary<Label, Label> labels = new Dictionary<Label, Label>(); //MethodBody methodBody = methodInfo.GetMethodBody(); //IList<LocalVariableInfo> localvars = methodBody.LocalVariables; //LocalBuilder[] localBuildersOrdered = new LocalBuilder[255]; //foreach (LocalVariableInfo localVar in localvars) //{ // Type type = localVar.LocalType; // LocalBuilder newLocalBuilder = il.DeclareLocal(type); // localBuildersOrdered[localVar.LocalIndex] = newLocalBuilder; //} //IList<ExceptionHandlingClause> exceptionHandlingClauses = methodBody.ExceptionHandlingClauses; ////LocalBuilder[] localBuildersOrdered = new LocalBuilder[255]; ////int localBuildersOrderedMax = 0; ////foreach (CodeInstruction currentInstruction in currentInstructions) ////{ //// object operand = currentInstruction.operand; //// if (operand is LocalBuilder localBuilder) //// { //// localBuildersOrdered[localBuilder.LocalIndex] = localBuilder; //// localBuildersOrderedMax = Math.Max(localBuildersOrderedMax, localBuilder.LocalIndex); //// } ////} ////Dictionary<LocalBuilder, LocalBuilder> localBuilders = new Dictionary<LocalBuilder, LocalBuilder>(); ////for (int i = 0; i <= localBuildersOrderedMax; i++) ////{ //// LocalBuilder localBuilderOrdered = localBuildersOrdered[i]; //// if (localBuilderOrdered == null) //// { //// il.DeclareLocal(typeof(object)); //// } //// else //// { //// LocalBuilder newLocalBuilder = il.DeclareLocal(localBuilderOrdered.LocalType); //// localBuilders.Add(localBuilderOrdered, newLocalBuilder); //// } ////} //foreach (CodeInstruction currentInstruction in currentInstructions) //{ // bool endFinally = false; // foreach (Label label in currentInstruction.labels) // { // if (!labels.TryGetValue(label, out Label translatedLabel)) // { // translatedLabel = il.DefineLabel(); // labels[label] = translatedLabel; // } // il.MarkLabel(translatedLabel); // } // //int i = il.ILOffset; // //foreach (ExceptionHandlingClause Clause in exceptionHandlingClauses) // //{ // // if (Clause.Flags != ExceptionHandlingClauseOptions.Clause && // // Clause.Flags != ExceptionHandlingClauseOptions.Finally) // // continue; // // // Look for an ending of an exception block first! // // if (Clause.HandlerOffset + Clause.HandlerLength == i) // // il.EndExceptionBlock(); // // // If this marks the beginning of a try block, emit that // // if (Clause.TryOffset == i) // // il.BeginExceptionBlock(); // // // Also check for the beginning of a catch block // // if (Clause.HandlerOffset == i && Clause.Flags == ExceptionHandlingClauseOptions.Clause) // // il.BeginCatchBlock(Clause.CatchType); // // // Lastly, check for a finally block // // if (Clause.HandlerOffset == i && Clause.Flags == ExceptionHandlingClauseOptions.Finally) // // il.BeginFinallyBlock(); // //} // foreach (ExceptionBlock block in currentInstruction.blocks) // { // switch (block.blockType) { // case ExceptionBlockType.BeginExceptionBlock: // { // il.BeginExceptionBlock(); // break; // } // case ExceptionBlockType.BeginCatchBlock: // { // il.BeginCatchBlock(block.catchType); // break; // } // case ExceptionBlockType.BeginExceptFilterBlock: // { // il.BeginExceptFilterBlock(); // break; // } // case ExceptionBlockType.BeginFaultBlock: // { // il.BeginFaultBlock(); // break; // } // case ExceptionBlockType.BeginFinallyBlock: // { // il.BeginFinallyBlock(); // break; // } // case ExceptionBlockType.EndExceptionBlock: // { // //il.EndExceptionBlock(); // endFinally = true; // break; // } // default: // { // Log.Error("Unknown ExceptionBlock"); // break; // } // } // } // OpCode opcode = currentInstruction.opcode; // object operand = currentInstruction.operand; // switch (operand) // { // case null: // { // il.Emit(opcode); // break; // } // case byte operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case sbyte operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case short operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case int operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case MethodInfo operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case SignatureHelper operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case ConstructorInfo operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case Type operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case long operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case float operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case double operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case Label operandCasted: // { // if (!labels.TryGetValue(operandCasted, out Label translatedLabel)) // { // translatedLabel = il.DefineLabel(); // labels[operandCasted] = translatedLabel; // } // il.Emit(opcode, translatedLabel); // break; // } // case Label[] operandCasted: // { // List<Label> newLabels = new List<Label>(); // foreach (Label operandCasted1 in operandCasted) // { // if (!labels.TryGetValue(operandCasted1, out Label translatedLabel)) // { // translatedLabel = il.DefineLabel(); // labels[operandCasted1] = translatedLabel; // } // newLabels.Add(translatedLabel); // } // il.Emit(opcode, newLabels.ToArray()); // break; // } // case FieldInfo operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case string operandCasted: // { // il.Emit(opcode, operandCasted); // break; // } // case LocalBuilder operandCasted: // { // il.Emit(opcode, localBuildersOrdered[operandCasted.LocalIndex]); // break; // } // default: // { // Log.Error("UNKNOWN OPERAND"); // break; // } // } // if (endFinally) // { // il.EndExceptionBlock(); // //endFinally = true; // } //} } } foreach (KeyValuePair <string, TypeBuilder> tb in typeBuilders) { tb.Value.CreateType(); } ab.Save(aName.Name + ".dll"); //ReImport DLL and create detour Assembly loadedAssembly = Assembly.UnsafeLoadFrom(aName.Name + ".dll"); IEnumerable <TypeInfo> transpiledTypes = loadedAssembly.DefinedTypes; Dictionary <string, Type> tTypeDictionary = new Dictionary <string, Type>(); foreach (TypeInfo transpiledType in transpiledTypes) { tTypeDictionary.Add(transpiledType.FullName, transpiledType.AsType()); } foreach (MethodBase originalMethod in originalMethods) { Patches patches = Harmony.GetPatchInfo(originalMethod); int transpiledCount = patches.Transpilers.Count; if (transpiledCount > 0) { if (originalMethod is MethodInfo methodInfo) // add support for constructors as well { Type transpiledType = tTypeDictionary[originalMethod.DeclaringType.FullName + "_Transpiled"]; ParameterInfo[] parameterInfos = methodInfo.GetParameters(); List <Type> types = new List <Type>(); if (!methodInfo.Attributes.HasFlag(MethodAttributes.Static)) { types.Add(methodInfo.DeclaringType); } foreach (ParameterInfo parameterInfo in parameterInfos) { types.Add(parameterInfo.ParameterType); } MethodInfo replacement = Method(transpiledType, originalMethod.Name, types.ToArray()); Memory.DetourMethod(originalMethod, replacement); } } } }