TypeSig GetThisType(CorFunction func) { if (func == null) { return(null); } var funcClass = func.Class; var mod = funcClass == null ? null : funcClass.Module; var mdi = mod == null ? null : mod.GetMetaDataInterface <IMetaDataImport>(); if (mdi == null) { return(null); } int numTypeGenArgs = MetaDataUtils.GetCountGenericParameters(mdi, funcClass.Token); var genTypeArgs = this.TypeParameters.Take(numTypeGenArgs).ToArray(); var td = DebugSignatureReader.CreateTypeDef(mdi, funcClass.Token); // Assume it's a class for now. The code should ignore ClassSig and just use the TypeDef var sig = new ClassSig(td); if (genTypeArgs.Length == 0) { return(sig); } var genArgs = new List <TypeSig>(genTypeArgs.Length); for (int i = 0; i < genTypeArgs.Length; i++) { genArgs.Add(new GenericVar(i)); } return(new GenericInstSig(sig, genArgs)); }
public TypeSig GetThisTypeSig() { ClassOrValueTypeSig tySig; if (IsValueType) { tySig = new ValueTypeSig(Def); } else { tySig = new ClassSig(Def); } TypeSig thisSig = tySig; if (HasGenArgs) { thisSig = new GenericInstSig(tySig, GenArgs); } if (IsValueType) { thisSig = new ByRefSig(thisSig); } return(thisSig); }
public TypeSig GetTypeSig() { if (IsArrayType) { if (ArrayInfo.IsSZArray) { return(new SZArraySig(GenArgs[0])); } return(new ArraySig(GenArgs[0], ArrayInfo.Rank, ArrayInfo.Sizes, ArrayInfo.LowerBounds)); } if (HasGenArgs) { ClassOrValueTypeSig tySig; if (IsValueType) { tySig = new ValueTypeSig(Def); } else { tySig = new ClassSig(Def); } return(new GenericInstSig(tySig, GenArgs)); } else { return(Def.ToTypeSig()); } }
void OnTypeKindChanged2() { switch ((Types.TypeKind)TypeKind.SelectedItem) { case Types.TypeKind.Unknown: break; case Types.TypeKind.Class: if (!IsClassBaseType(BaseTypeSig)) { BaseTypeSig = ownerModule.CorLibTypes.Object; } TypeSemantics.SelectedItem = Types.TypeSemantics.Class; break; case Types.TypeKind.StaticClass: BaseTypeSig = ownerModule.CorLibTypes.Object; TypeLayout.SelectedItem = Types.TypeLayout.AutoLayout; TypeSemantics.SelectedItem = Types.TypeSemantics.Class; Abstract = true; Sealed = true; break; case Types.TypeKind.Interface: BaseTypeSig = null; TypeLayout.SelectedItem = Types.TypeLayout.AutoLayout; TypeSemantics.SelectedItem = Types.TypeSemantics.Interface; Abstract = true; Sealed = false; break; case Types.TypeKind.Struct: BaseTypeSig = new ClassSig(ownerModule.CorLibTypes.GetTypeRef("System", "ValueType")); TypeSemantics.SelectedItem = Types.TypeSemantics.Class; Abstract = false; Sealed = true; break; case Types.TypeKind.Enum: BaseTypeSig = new ClassSig(ownerModule.CorLibTypes.GetTypeRef("System", "Enum")); TypeLayout.SelectedItem = Types.TypeLayout.AutoLayout; TypeSemantics.SelectedItem = Types.TypeSemantics.Class; Abstract = false; Sealed = true; break; case Types.TypeKind.Delegate: BaseTypeSig = new ClassSig(ownerModule.CorLibTypes.GetTypeRef("System", "MulticastDelegate")); TypeLayout.SelectedItem = Types.TypeLayout.AutoLayout; TypeSemantics.SelectedItem = Types.TypeSemantics.Class; Abstract = false; Sealed = true; break; default: throw new InvalidOperationException(); } }
private TypeSig ReadFieldOrPropType() { if (!recursionCounter.Increment()) { throw new CABlobParserException("Too much recursion"); } TypeSig result; switch ((SerializationType)reader.ReadByte()) { case SerializationType.Boolean: result = module.CorLibTypes.Boolean; break; case SerializationType.Char: result = module.CorLibTypes.Char; break; case SerializationType.I1: result = module.CorLibTypes.SByte; break; case SerializationType.U1: result = module.CorLibTypes.Byte; break; case SerializationType.I2: result = module.CorLibTypes.Int16; break; case SerializationType.U2: result = module.CorLibTypes.UInt16; break; case SerializationType.I4: result = module.CorLibTypes.Int32; break; case SerializationType.U4: result = module.CorLibTypes.UInt32; break; case SerializationType.I8: result = module.CorLibTypes.Int64; break; case SerializationType.U8: result = module.CorLibTypes.UInt64; break; case SerializationType.R4: result = module.CorLibTypes.Single; break; case SerializationType.R8: result = module.CorLibTypes.Double; break; case SerializationType.String: result = module.CorLibTypes.String; break; case SerializationType.SZArray: result = new SZArraySig(ReadFieldOrPropType()); break; case SerializationType.Type: result = new ClassSig(module.CorLibTypes.GetTypeRef("System", "Type")); break; case SerializationType.TaggedObject: result = module.CorLibTypes.Object; break; case SerializationType.Enum: result = ReadType(false); break; default: throw new CABlobParserException("Invalid type"); } recursionCounter.Decrement(); return(result); }
public ClassOrValueTypeSig Type(bool isValueType, string ns, string name, IResolutionScope resolutionScope) { var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, resolutionScope)); ClassOrValueTypeSig type; if (isValueType) { type = new ValueTypeSig(typeRef); } else { type = new ClassSig(typeRef); } return((ClassOrValueTypeSig)Add(type)); }
public void PerformRemoval(ClarifierContext ctx) { foreach (var v in staticProtectionsManager.DestinationMap) { foreach (var vv in v.matchingMethods) { var typeRef = ctx.CurrentModule.UpdateRowId(new TypeRefUser(ctx.CurrentModule, "System.Diagnostics", "Debugger", ctx.CurrentModule.CorLibTypes.AssemblyRef)); var classSignature = new ClassSig(typeRef); var methodSig = MethodSig.CreateStatic(ctx.CurrentModule.CorLibTypes.Void); MemberRefUser mff = ctx.CurrentModule.UpdateRowId(new MemberRefUser(ctx.CurrentModule, "Break", methodSig, classSignature.TypeDefOrRef)); vv.Body.Instructions.Insert(vv.Body.Instructions.Count - 1, Instruction.Create(OpCodes.Call, mff)); } } }
public void InjectArray(Array arrayToInject, MethodDef method, ITypeDefOrRef arrayType, int elementSize, int instructionIndex) { var runtimeHelpersRef = method.Module.UpdateRowId(new TypeRefUser(method.Module, "System.Runtime.CompilerServices", "RuntimeHelpers", method.Module.CorLibTypes.AssemblyRef)); var runtimeHelpersSig = new ClassSig(runtimeHelpersRef); var arrayRef = method.Module.UpdateRowId(new TypeRefUser(method.Module, "System", "Array", method.Module.CorLibTypes.AssemblyRef)); var arrayRefSig = new ClassSig(arrayRef); var runtimeFieldHandleRef = method.Module.UpdateRowId(new TypeRefUser(method.Module, "System", "RuntimeFieldHandle", method.Module.CorLibTypes.AssemblyRef)); var RuntimeFieldHandleSig = new ValueTypeSig(runtimeFieldHandleRef); var initArraySig = MethodSig.CreateStatic(method.Module.CorLibTypes.Void, arrayRefSig, RuntimeFieldHandleSig); MemberRefUser initArrayRef = method.Module.UpdateRowId(new MemberRefUser(method.Module, "InitializeArray", initArraySig, runtimeHelpersSig.TypeDefOrRef)); // The following will insert these instructions: // Ldc_I4 arraySize // Newarr arrayType // Dup // Ldtoken initArrayToken method.Body.Instructions[instructionIndex] = new Instruction(OpCodes.Call, initArrayRef); method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Ldtoken, Create(arrayToInject, method.Module, elementSize))); method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Dup)); method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Newarr, arrayType)); method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Ldc_I4, arrayToInject.Length)); }
/// <summary> /// Reads the next type /// </summary> /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns> TypeSig ReadType() { if (!recursionCounter.Increment()) { return(null); } uint num, i; TypeSig nextType, result = null; switch ((ElementType)reader.ReadByte()) { case ElementType.Void: result = corLibTypes.Void; break; case ElementType.Boolean: result = corLibTypes.Boolean; break; case ElementType.Char: result = corLibTypes.Char; break; case ElementType.I1: result = corLibTypes.SByte; break; case ElementType.U1: result = corLibTypes.Byte; break; case ElementType.I2: result = corLibTypes.Int16; break; case ElementType.U2: result = corLibTypes.UInt16; break; case ElementType.I4: result = corLibTypes.Int32; break; case ElementType.U4: result = corLibTypes.UInt32; break; case ElementType.I8: result = corLibTypes.Int64; break; case ElementType.U8: result = corLibTypes.UInt64; break; case ElementType.R4: result = corLibTypes.Single; break; case ElementType.R8: result = corLibTypes.Double; break; case ElementType.String: result = corLibTypes.String; break; case ElementType.TypedByRef: result = corLibTypes.TypedReference; break; case ElementType.I: result = corLibTypes.IntPtr; break; case ElementType.U: result = corLibTypes.UIntPtr; break; case ElementType.Object: result = corLibTypes.Object; break; case ElementType.Ptr: result = new PtrSig(ReadType()); break; case ElementType.ByRef: result = new ByRefSig(ReadType()); break; case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break; case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break; case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break; case ElementType.SZArray: result = new SZArraySig(ReadType()); break; case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break; case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break; case ElementType.Sentinel: result = new SentinelSig(); break; case ElementType.Pinned: result = new PinnedSig(ReadType()); break; case ElementType.Var: if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new GenericVar(num, gpContext.Type); break; case ElementType.MVar: if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new GenericMVar(num, gpContext.Method); break; case ElementType.ValueArray: nextType = ReadType(); if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new ValueArraySig(nextType, num); break; case ElementType.Module: if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new ModuleSig(num, ReadType()); break; case ElementType.GenericInst: nextType = ReadType(); if (!reader.TryReadCompressedUInt32(out num)) { break; } var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); var args = genericInstSig.GenericArguments; for (i = 0; i < num; i++) { args.Add(ReadType()); } result = genericInstSig; break; case ElementType.Array: nextType = ReadType(); uint rank; if (!reader.TryReadCompressedUInt32(out rank)) { break; } if (rank > MaxArrayRank) { break; } if (rank == 0) { result = new ArraySig(nextType, rank); break; } if (!reader.TryReadCompressedUInt32(out num)) { break; } if (num > MaxArrayRank) { break; } var sizes = new List <uint>((int)num); for (i = 0; i < num; i++) { if (!reader.TryReadCompressedUInt32(out uint size)) { goto exit; } sizes.Add(size); } if (!reader.TryReadCompressedUInt32(out num)) { break; } if (num > MaxArrayRank) { break; } var lowerBounds = new List <int>((int)num); for (i = 0; i < num; i++) { if (!reader.TryReadCompressedInt32(out int size)) { goto exit; } lowerBounds.Add(size); } result = new ArraySig(nextType, rank, sizes, lowerBounds); break; case ElementType.Internal: IntPtr address; if (IntPtr.Size == 4) { address = new IntPtr(reader.ReadInt32()); } else { address = new IntPtr(reader.ReadInt64()); } result = helper.ConvertRTInternalAddress(address); break; case ElementType.End: case ElementType.R: default: result = null; break; } exit: recursionCounter.Decrement(); return(result); }
public static void Run() { // 创建一个新模块。 传入的字符串是模块的名称,而不是文件名。 ModuleDef mod = new ModuleDefUser("MyModule.exe"); // 这是一个控制台应用程序 mod.Kind = ModuleKind.Console; //将模块添加到装配中 AssemblyDef asm = new AssemblyDefUser("MyAssembly", new Version(1, 2, 3, 4), null, ""); asm.Modules.Add(mod); //添加.NET资源 // byte[] resourceData = Encoding.UTF8.GetBytes("Hello, world!"); //mod.Resources.Add(new EmbeddedResource("My.Resource", resourceData, // ManifestResourceAttributes.Private)); // 添加启动类型。 它派生自System.Object。 TypeDef startUpType = new TypeDefUser("My.Namespace", "Startup", mod.CorLibTypes.Object.TypeDefOrRef); startUpType.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.AnsiClass; // 将类型添加到模块 mod.Types.Add(startUpType); // 创建入口点方法 MethodDef entryPoint = new MethodDefUser("Main", MethodSig.CreateStatic(mod.CorLibTypes.Void, new SZArraySig(mod.CorLibTypes.String))); entryPoint.Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot; entryPoint.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed; // 命名第一个参数(参数0是返回类型) entryPoint.ParamDefs.Add(new ParamDefUser("args", 1)); // 将方法添加到启动类型 startUpType.Methods.Add(entryPoint); // 设置模块入口点 mod.EntryPoint = entryPoint; // 创建TypeRef到System.Console TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef); // 创建方法ref为'System.Void System.Console :: WriteLine(System.String)' MemberRef consoleWrite1 = new MemberRefUser(mod, "WriteLine", MethodSig.CreateStatic(mod.CorLibTypes.Void, mod.CorLibTypes.String), consoleRef); TypeRef ConsoleKeyInfo = new TypeRefUser(mod, "System", "ConsoleKeyInfo", mod.CorLibTypes.AssemblyRef); //TypeRef stream = new TypeRefUser(mod, "System.IO", "Stream", mod.CorLibTypes.AssemblyRef); ClassSig classSig = new ClassSig(ConsoleKeyInfo); SZArraySig array5 = new SZArraySig(classSig); ITypeDefOrRef type1 = array5.ToTypeDefOrRef(); ITypeDefOrRef type2 = classSig.ToTypeDefOrRef(); TypeSig type11 = type1.ToTypeSig(); TypeSig type22 = type2.ToTypeSig(); // 创建方法ref为'System.ConsoleKeyInfo //System.Console::ReadKey()' MemberRef consoleReadKey = new MemberRefUser( mod, "ReadLine", //MethodSig.CreateStatic(mod.CorLibTypes.Void), MethodSig.CreateStatic(mod.CorLibTypes.String), consoleRef ); //LocalList localList=new LocalList(new LazyList<Local>()); Local local = new Local(mod.CorLibTypes.String); //localList.Add(local); //SZArraySig SZArraySig = new SZArraySig(local); // 将CIL方法体添加到入口点方法 CilBody epBody = new CilBody(); entryPoint.Body = epBody; epBody.Variables.Add(local); epBody.Instructions.Add(OpCodes.Nop.ToInstruction()); epBody.Instructions.Add(OpCodes.Ldstr.ToInstruction("小宇专属")); epBody.Instructions.Add(OpCodes.Call.ToInstruction(consoleWrite1)); epBody.Instructions.Add(OpCodes.Ldstr.ToInstruction("xiaoyu")); epBody.Instructions.Add(OpCodes.Call.ToInstruction(consoleWrite1)); epBody.Instructions.Add(OpCodes.Nop.ToInstruction()); epBody.Instructions.Add(OpCodes.Call.ToInstruction(consoleReadKey)); //epBody.Instructions.Add(OpCodes.Ldc_I4_0.ToInstruction()); epBody.Instructions.Add(OpCodes.Stloc_0.ToInstruction()); epBody.Instructions.Add(OpCodes.Ldloc_0.ToInstruction()); epBody.Instructions.Add(OpCodes.Call.ToInstruction(consoleWrite1)); epBody.Instructions.Add(OpCodes.Nop.ToInstruction()); epBody.Instructions.Add(OpCodes.Ret.ToInstruction()); // 将程序集保存到磁盘上的文件中 mod.Write(@"saved-assembly.exe"); }
bool ReadCore(out TypeSig type, out object value) { if (!recursionCounter.Increment()) { type = null; value = null; return(false); } bool res; ITypeDefOrRef tdr; UTF8String ns, name; var et = (ElementType)reader.ReadByte(); switch (et) { case ElementType.Boolean: type = module.CorLibTypes.Boolean; value = reader.ReadBoolean(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.Char: type = module.CorLibTypes.Char; value = reader.ReadChar(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.I1: type = module.CorLibTypes.SByte; value = reader.ReadSByte(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.U1: type = module.CorLibTypes.Byte; value = reader.ReadByte(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.I2: type = module.CorLibTypes.Int16; value = reader.ReadInt16(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.U2: type = module.CorLibTypes.UInt16; value = reader.ReadUInt16(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.I4: type = module.CorLibTypes.Int32; value = reader.ReadInt32(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.U4: type = module.CorLibTypes.UInt32; value = reader.ReadUInt32(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.I8: type = module.CorLibTypes.Int64; value = reader.ReadInt64(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.U8: type = module.CorLibTypes.UInt64; value = reader.ReadUInt64(); if (reader.Position < reader.Length) { type = ReadTypeDefOrRefSig(); } res = true; break; case ElementType.R4: type = module.CorLibTypes.Single; value = reader.ReadSingle(); res = true; break; case ElementType.R8: type = module.CorLibTypes.Double; value = reader.ReadDouble(); res = true; break; case ElementType.String: type = module.CorLibTypes.String; value = ReadString(); res = true; break; case ElementType.Ptr: res = ReadCatch(out type, out value); if (res) { type = new PtrSig(type); } break; case ElementType.ByRef: res = ReadCatch(out type, out value); if (res) { type = new ByRefSig(type); } break; case ElementType.Object: type = module.CorLibTypes.Object; value = null; res = true; break; case ElementType.ValueType: tdr = ReadTypeDefOrRef(); type = tdr.ToTypeSig(); value = null; if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib()) { if (name == stringDecimal) { if (reader.Length - reader.Position != 13) { goto default; } try { byte b = reader.ReadByte(); value = new Decimal(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), (b & 0x80) != 0, (byte)(b & 0x7F)); } catch { goto default; } } else if (name == stringDateTime) { if (reader.Length - reader.Position != 8) { goto default; } try { value = new DateTime(reader.ReadInt64()); } catch { goto default; } } } if (value == null && reader.Position != reader.Length) { value = reader.ReadRemainingBytes(); } res = true; break; case ElementType.Class: type = new ClassSig(ReadTypeDefOrRef()); value = reader.Position == reader.Length ? null : reader.ReadRemainingBytes(); res = true; break; case ElementType.CModReqd: tdr = ReadTypeDefOrRef(); res = ReadCatch(out type, out value); if (res) { type = new CModReqdSig(tdr, type); } break; case ElementType.CModOpt: tdr = ReadTypeDefOrRef(); res = ReadCatch(out type, out value); if (res) { type = new CModOptSig(tdr, type); } break; case ElementType.Var: case ElementType.Array: case ElementType.GenericInst: case ElementType.TypedByRef: case ElementType.I: case ElementType.U: case ElementType.FnPtr: case ElementType.SZArray: case ElementType.MVar: case ElementType.End: case ElementType.Void: case ElementType.ValueArray: case ElementType.R: case ElementType.Internal: case ElementType.Module: case ElementType.Sentinel: case ElementType.Pinned: default: Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString()); res = false; type = null; value = null; break; } recursionCounter.Decrement(); return(res); }
private string injectDeepTrace(List <string> MethodToken, string assemblyPath, string outputDirectory, bool WithTrace = false) { AssemblyDef asmDef; // New assembly path string fileName = Path.GetFileName(assemblyPath); // Append Date and Time to new filename string newPath = Path.Combine(outputDirectory, DateTime.UtcNow.ToString("yyyy-MM-dd HH.mm.ss.fff", CultureInfo.InvariantCulture) + "_" + fileName); // Check if Output directory already exists, if not, create one if (!Directory.Exists(outputDirectory)) { try { Directory.CreateDirectory(outputDirectory); } catch (Exception ex) { //MessageBox.Show(ex.ToString()); MainWindow.Instance.mBox("Injector Exception", ex.ToString()); } } try { // AssemblyResolver if (_AssmeblyResolver == null) { _AssmeblyResolver = new AssemblyResolver(); } if (Directory.Exists(Path.GetDirectoryName(assemblyPath))) { AddSearchPath(Path.GetDirectoryName(assemblyPath)); } // how to use AssemblyResolver with dnLib? //_AssmeblyResolver // Load assembly //asmDef = AssemblyDef.Load(assemblyPath); ModuleDefMD mod = ModuleDefMD.Load(assemblyPath); // import our pritObj Class Importer importer = new Importer(mod); Type PrintObjType = typeof(PrintObj); ITypeDefOrRef _printObjTypeRef = importer.Import(PrintObjType); // This creates a new namespace Logging and class PrintObj in the new assembly, we don't want that //TypeDef _printObj = new TypeDefUser("Logging", "PrintObj", mod.CorLibTypes.Object.TypeDefOrRef); //var _printObjCtor = _printObj.FindDefaultConstructor(); //mod.Types.Add(_printObj); Type t = typeof(System.Reflection.MethodBase); string methodname = "GetCurrentMethod"; IMethod _methodGetCurrentMethod = importer.Import(t.GetMethod(methodname)); methodname = "set_CurrentMethod"; IMethod _methodSetMethod = importer.Import(PrintObjType.GetMethod(methodname)); t = typeof(System.Reflection.Assembly); methodname = "GetExecutingAssembly"; IMethod _methodGetExecutingAssembly = importer.Import(t.GetMethod(methodname)); methodname = "set_CurrentAssembly"; IMethod _methodSetExecutingAssembly = importer.Import(PrintObjType.GetMethod(methodname)); methodname = "get_CurrentArguments"; IMethod _methodGetArguments = importer.Import(PrintObjType.GetMethod(methodname)); methodname = "set_CurrentArguments"; IMethod _methodSetArguments = importer.Import(PrintObjType.GetMethod(methodname)); methodname = "PrintArgs"; IMethod _methodPrintArgs = importer.Import(PrintObjType.GetMethod(methodname)); methodname = ".ctor"; IMethod _printObjCtor = importer.Import(PrintObjType.GetMethod(methodname)); foreach (ModuleDef modDef in mod.Assembly.Modules) { foreach (TypeDef typDef in modDef.Types) { foreach (MethodDef metDef in typDef.Methods) { //if (MethodToken.Contains(metDef.MDToken.ToString()) && metDef.Name == "About1_Closed") if (MethodToken.Contains(metDef.MDToken.ToString())) { if (WithTrace) { Trace.WriteLine("Found method " + metDef.ToString() + " Token: " + metDef.MDToken.ToString()); } try { string variablesInfo = string.Empty; if (metDef.Body != null && metDef.Body.Variables != null && metDef.Body.Variables.Count > 0) { foreach (var variable in metDef.Body.Variables) { string varInfo = " Variable - Type: " + variable.Type.ToString() + " Name: " + variable.Name + NewLine; varInfo += " Index: " + variable.Index.ToString(); if (WithTrace) { Trace.WriteLine(varInfo); } variablesInfo += varInfo; } } /* * if we want to skip anything * if (metDef.IsConstructor || * metDef.IsAbstract || * metDef.IsSetter || * (metDef.IsSpecialName && !metDef.IsGetter) || // to allow getter methods * metDef.IsInstanceConstructor || * metDef.IsManaged == false * ) * { * if (WithTrace) Trace.WriteLine("Skipped unsupported metDef " + metDef.Name); * } * else if (metDef != null && metDef.Body != null) */ if (metDef != null && metDef.Body != null) { var instructions = metDef.Body.Instructions; var newInstructions = new List <Instruction>(); Instruction firstExistingInstruction = metDef.Body.Instructions[0]; uint firstExistingInstrunctionOffset = firstExistingInstruction.Offset; int fIndex = (int)firstExistingInstrunctionOffset; // not working // nop Test //instructions.Insert((int)firstExistingInstruction.Offset, new Instruction(OpCodes.Nop)); //instructions.Insert((int)firstExistingInstruction.Offset, new Instruction(OpCodes.Nop)); /// /// Simple TraceLine /// // Load fully qualified method name as string //not working: (int)firstExistingInstruction.Offset //newInstructions.Add(new Instruction(OpCodes.Ldstr, metDef.ToString() + variablesInfo)); //newInstructions.Add(new Instruction(OpCodes.Call, metDef.Module.Import(typeof(Trace).GetMethod("WriteLine", new[] { typeof(string) })))); /// /// PrintObj (injected Logging.dll) /// extended by using code and comments from CInject /// https://codeinject.codeplex.com/ /// /* * 0 0000 nop * 1 0001 newobj instance void [Logging]Logging.PrintObj::.ctor() * 2 0006 stloc V_0 (0) * 3 000A ldloc V_0 (0) * 4 000E call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetCurrentMethod() * 5 0013 callvirt instance void [Logging]Logging.PrintObj::set_CurrentMethod(class [mscorlib]System.Reflection.MethodBase) * 6 0018 nop * 7 0019 ldloc.s V_0 (0) * 8 001B ldc.i4 2 * 9 0020 newarr [mscorlib]System.Object * 10 0025 stloc.s V_1 (1) * 11 0027 ldloc.s V_1 (1) * 12 0029 ldc.i4 0 * 13 002E ldarg sender (1) * 14 0032 box [mscorlib]System.Object * 15 0037 stelem.ref * 16 0038 ldloc.s V_1 (1) * 17 003A ldc.i4 1 * 18 003F ldarg e (2) * 19 0043 stelem.ref * 20 0044 ldloc.s V_1 (1) * 21 0046 callvirt instance void [Logging]Logging.PrintObj::set_CurrentArguments(object[]) * 22 004B ldloc.s V_0 (0) * 23 004D callvirt instance void [Logging]Logging.PrintObj::PrintArgs() * 24 0052 nop * */ // Add new variables metDef.Body.InitLocals = true; Local printO = new Local(_printObjTypeRef.ToTypeSig()); metDef.Body.Variables.Add(printO); var objType = mod.CorLibTypes.Object.ToTypeDefOrRef(); var objTypeArr = importer.Import(typeof(object[])); Local oArray = new Local(objTypeArr.ToTypeSig()); metDef.Body.Variables.Add(oArray); newInstructions.Add(new Instruction(OpCodes.Nop)); // using MemberRef cTor will create the logging.PrintObj: new Logging.PrintObj() var objectCtor = new MemberRefUser(mod, ".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void), _printObjTypeRef); newInstructions.Add(new Instruction(OpCodes.Newobj, objectCtor)); newInstructions.Add(OpCodes.Stloc.ToInstruction(printO)); newInstructions.Add(OpCodes.Ldloc.ToInstruction(printO)); newInstructions.Add(new Instruction(OpCodes.Call, _methodGetCurrentMethod)); newInstructions.Add(new Instruction(OpCodes.Callvirt, _methodSetMethod)); newInstructions.Add(new Instruction(OpCodes.Nop)); newInstructions.Add(new Instruction(OpCodes.Ldloc_S, printO)); // DNlib counts additionally hidden "this" List <Parameter> pList = new List <Parameter>(); for (int i = 0; i < metDef.Parameters.Count; i++) { if (!metDef.Parameters[i].IsHiddenThisParameter) { pList.Add(metDef.Parameters[i]); } } newInstructions.Add(new Instruction(OpCodes.Ldc_I4, pList.Count)); newInstructions.Add(new Instruction(OpCodes.Newarr, objType)); newInstructions.Add(new Instruction(OpCodes.Stloc_S, oArray)); //for (int i = 0; i < metDef.Parameters.Count; i++) for (int i = 0; i < pList.Count; i++) { if (WithTrace) { Trace.WriteLine("Found Parameter " + pList[i].Name.ToString()); } bool processAsNormal = true; //if (metDef.Parameters[i].Type.IsByRef) if (pList[i].Type.IsByRef) { if (WithTrace) { Trace.WriteLine("(IsByRef) " + pList[i].Name.ToString()); } //* Sample Instruction set: //* L_002a: ldloc.2 //* L_002b: ldc.i4.0 //* L_002c: ldarg.1 //* L_002d: ldind.ref //* L_002e: stelem.ref //* newInstructions.Add(new Instruction(OpCodes.Ldloc_S, oArray)); newInstructions.Add(new Instruction(OpCodes.Ldc_I4, i)); newInstructions.Add(new Instruction(OpCodes.Ldarg, pList[i])); newInstructions.Add(new Instruction(OpCodes.Ldind_Ref)); newInstructions.Add(new Instruction(OpCodes.Stelem_Ref)); processAsNormal = false; } //else if (pList[i].IsHiddenThisParameter) //{ //processAsNormal = false; //} else if (pList[i].Type.IsClassSig) { if (WithTrace) { Trace.WriteLine("(IsClassSig) " + pList[i].Name.ToString() + " Type: " + pList[i].Type + " Type.ReflectionFullName: " + pList[i].Type.ReflectionFullName); } newInstructions.Add(new Instruction(OpCodes.Ldloc_S, oArray)); newInstructions.Add(new Instruction(OpCodes.Ldc_I4, i)); newInstructions.Add(new Instruction(OpCodes.Ldarg, pList[i])); //newInstructions.Add(new Instruction(OpCodes.Box, pList[i].Type)); // causing System.InvalidCastException: Type "dnlib.DotNet.ClassSig" cannot be converted to Type "dnlib.DotNet.TypeSpec" ClassSig cSig = new ClassSig(pList[i].Type.ToTypeDefOrRef()); Trace.WriteLine("(IsClassSig) cSig: " + cSig.ToString()); newInstructions.Add(new Instruction(OpCodes.Stelem_Ref)); processAsNormal = false; } else if (pList[i].Type.IsCorLibType) { if (WithTrace) { Trace.WriteLine("(IsCorLibType) " + pList[i].Name.ToString() + " Type: " + pList[i].Type + " Type.ReflectionFullName: " + pList[i].Type.ReflectionFullName); } if (WithTrace) { Trace.WriteLine("(IsCorLibType...) " + " ElementType: " + pList[i].Type.ElementType + " Type.FullName: " + pList[i].Type.FullName); } if (WithTrace) { Trace.WriteLine("(IsCorLibType...) " + " Module: " + pList[i].Type.Module + " Type.Next: " + pList[i].Type.Next); } if (WithTrace) { Trace.WriteLine("(IsCorLibType...) " + " ReflectionName: " + pList[i].Type.ReflectionName + " Type.ReflectionNamespace: " + pList[i].Type.ReflectionNamespace); } newInstructions.Add(new Instruction(OpCodes.Ldloc_S, oArray)); newInstructions.Add(new Instruction(OpCodes.Ldc_I4, i)); newInstructions.Add(new Instruction(OpCodes.Ldarg, pList[i])); //newInstructions.Add(new Instruction(OpCodes.Box, pList[i].Type)); // causing System.InvalidCastException: Type "dnlib.DotNet.CorLibTypeSig" cannot be converted to Type "dnlib.DotNet.TypeSpec" //newInstructions.Add(new Instruction(OpCodes.Box, mod.CorLibTypes.Int32)); // working for Int32 as example CorLibTypeSig cLibTypeSig = new CorLibTypeSig(pList[i].Type.ToTypeDefOrRef(), pList[i].Type.ElementType); newInstructions.Add(OpCodes.Box.ToInstruction(cLibTypeSig)); newInstructions.Add(new Instruction(OpCodes.Stelem_Ref)); processAsNormal = false; } //else if (metDef.Parameters[i].ParameterType.IsArray) //{ //} //else if (metDef.Parameters[i].ParameterType.IsDefinition) // delegate needs no seperate handling //{ //} //else if (metDef.Parameters[i].Type.IsFunctionPointer) else if (pList[i].Type.IsFunctionPointer) { if (WithTrace) { Trace.WriteLine("(IsFunctionPointer) " + pList[i].Name.ToString()); } } //else if (metDef.Parameters[i].ParameterType.IsOptionalModifier) //{ //} //else if (metDef.Parameters[i].Type.IsPointer) else if (pList[i].Type.IsPointer) { if (WithTrace) { Trace.WriteLine("(IsPointer) " + pList[i].Name.ToString()); } } else { processAsNormal = true; } //if (processAsNormal && !metDef.Parameters[i].Type.IsClassSig && !metDef.Parameters[i].Type.IsCorLibType) if (processAsNormal) { if (WithTrace) { Trace.WriteLine("processAsNormal: " + pList[i].Name.ToString()); } // Sample Instruction set: for simple PARAMETER //* L_0036: ldloc.s objArray //* L_0038: ldc.i4 0 //* L_003d: ldarg array //* L_0041: box Int32 <-------------- anything can be here //* L_0046: stelem.ref // Sample Instruction set: for ARRAY // L_0036: ldloc.s objArray // L_0038: ldc.i4 0 // L_003d: ldarg array // L_0041: box string[] // L_0046: stelem.ref newInstructions.Add(new Instruction(OpCodes.Ldloc_S, oArray)); newInstructions.Add(new Instruction(OpCodes.Ldc_I4, i)); newInstructions.Add(new Instruction(OpCodes.Ldarg, metDef.Parameters[i])); newInstructions.Add(new Instruction(OpCodes.Box, pList[i].Type)); newInstructions.Add(new Instruction(OpCodes.Stelem_Ref)); } } // fill Arguments array newInstructions.Add(new Instruction(OpCodes.Ldloc_S, oArray)); newInstructions.Add(new Instruction(OpCodes.Callvirt, _methodSetArguments)); // call PrintArgs newInstructions.Add(new Instruction(OpCodes.Ldloc_S, printO)); newInstructions.Add(new Instruction(OpCodes.Callvirt, _methodPrintArgs)); // Finally add instructions to beginning for (int j = 0; j < newInstructions.Count; j++) { instructions.Insert(j, newInstructions[j]); } } else { if (WithTrace) { Trace.WriteLine("metDef or metDef.Body was null"); } } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); MainWindow.Instance.mBox("Injector Exception", ex.ToString()); } } } } } // Save modified assembly //asmDef.Write(newPath); var wopts = new dnlib.DotNet.Writer.ModuleWriterOptions(mod); wopts.WritePdb = true; //write assembly if (mod.IsILOnly) { mod.Write(newPath); } else { mod.NativeWrite(newPath); } } catch (Exception ex) { if (WithTrace) { Trace.WriteLine(DateTime.Now + " injectDeepTrace exception: " + ex.ToString()); } return(DateTime.Now + " injectDeepTrace exception: " + ex.ToString()); } InjectedFile = newPath; Text = "Injector finished: " + newPath; return(newPath); }