示例#1
0
 public void OnWriterEvent(ModuleWriterBase writer, ModuleWriterEvent evt)
 {
     if (evt == ModuleWriterEvent.MDEndWriteMethodBodies)
     {
         byte[] native_ = Encode_();
         codeChunk = writer.MethodBodies.Add(new dnlib.DotNet.Writer.MethodBody(native_));
     }
     else if (evt == ModuleWriterEvent.EndCalculateRvasAndFileOffsets)
     {
         uint rid = writer.MetaData.GetRid(Protections.Constants.ConstantsProtection.native_);
         writer.MetaData.TablesHeap.MethodTable[rid].RVA = (uint)codeChunk.RVA;
     }
 }
示例#2
0
            void InjectNativeCode(object sender, ModuleWriterListenerEventArgs e)
            {
                var writer = (ModuleWriterBase)sender;

                if (e.WriterEvent == ModuleWriterEvent.MDEndWriteMethodBodies)
                {
                    codeChunk = writer.MethodBodies.Add(new MethodBody(code));
                }
                else if (e.WriterEvent == ModuleWriterEvent.EndCalculateRvasAndFileOffsets)
                {
                    var rid = writer.MetaData.GetRid(native);
                    writer.MetaData.TablesHeap.MethodTable[rid].RVA = (uint)codeChunk.RVA;
                }
            }
示例#3
0
		/// <summary>
		/// Adds a <see cref="MethodBody"/> and returns the one that has been cached
		/// </summary>
		/// <param name="methodBody">The method body</param>
		/// <returns>The cached method body</returns>
		public MethodBody Add(MethodBody methodBody) {
			if (setOffsetCalled)
				throw new InvalidOperationException("SetOffset() has already been called");
			if (shareBodies) {
				var dict = methodBody.IsFat ? fatMethodsDict : tinyMethodsDict;
				MethodBody cached;
				if (dict.TryGetValue(methodBody, out cached)) {
					savedBytes += (uint)methodBody.GetSizeOfMethodBody();
					return cached;
				}
				dict[methodBody] = methodBody;
			}
			var list = methodBody.IsFat ? fatMethods : tinyMethods;
			list.Add(methodBody);
			return methodBody;
		}
示例#4
0
            void InjectNativeCode(object sender, ModuleWriterEventArgs e)
            {
                var writer = e.Writer;

                switch (e.Event)
                {
                case ModuleWriterEvent.MDEndWriteMethodBodies:
                    codeChunk = writer.MethodBodies.Add(new MethodBody(code));
                    break;

                case ModuleWriterEvent.EndCalculateRvasAndFileOffsets:
                    uint rid       = writer.Metadata.GetRid(native);
                    var  methodRow = writer.Metadata.TablesHeap.MethodTable[rid];
                    writer.Metadata.TablesHeap.MethodTable[rid] = new RawMethodRow(
                        (uint)codeChunk.RVA,
                        methodRow.ImplFlags,
                        methodRow.Flags,
                        methodRow.Name,
                        methodRow.Signature,
                        methodRow.ParamList);
                    break;
                }
            }
示例#5
0
		/// <summary>
		/// Removes the specified method body from this chunk
		/// </summary>
		/// <param name="methodBody">The method body</param>
		/// <returns><c>true</c> if the method body is removed</returns>
		public bool Remove(MethodBody methodBody) {
			if (setOffsetCalled)
				throw new InvalidOperationException("SetOffset() has already been called");
			var list = methodBody.IsFat ? fatMethods : tinyMethods;
			return list.Remove(methodBody);
		}
        /// <summary>
        ///     Copies the information from the origin method to injected method.
        /// </summary>
        /// <param name="methodDef">The origin MethodDef.</param>
        /// <param name="ctx">The injection context.</param>
        void CopyMethodDef(MethodDef methodDef, InjectContext ctx)
        {
            if (ctx.Filter != null && !ctx.Filter.Contains(methodDef))
            {
                return;
            }

            var newMethodDef = (MethodDef)ctx.Map[methodDef];

            newMethodDef.Signature = ctx.Importer.Import(methodDef.Signature);
            newMethodDef.Parameters.UpdateParameterTypes();

            if (methodDef.ImplMap != null)
            {
                newMethodDef.ImplMap = new ImplMapUser(new ModuleRefUser(ctx.TargetModule, methodDef.ImplMap.Module.Name), methodDef.ImplMap.Name, methodDef.ImplMap.Attributes);
            }

            foreach (CustomAttribute ca in methodDef.CustomAttributes)
            {
                newMethodDef.CustomAttributes.Add(new CustomAttribute((ICustomAttributeType)ctx.Importer.Import(ca.Constructor)));
            }

            if (methodDef.CodeType == MethodImplAttributes.Native)
            {
                dnlib.PE.RVA methodRVA  = methodDef.NativeBody.RVA;
                List <byte>  methodBody = new List <byte>();

                ModuleDefMD moduleMD = (ModuleDefMD)methodDef.Module;
                var         stream   = moduleMD.MetaData.PEImage.CreateStream(moduleMD.MetaData.PEImage.ToFileOffset(methodRVA));
                byte        byteToAdd;
                do
                {
                    byteToAdd = stream.ReadByte();
                    methodBody.Add(byteToAdd);
                } while (byteToAdd != 0xc3);

                code[newMethodDef] = new dnlib.DotNet.Writer.MethodBody(methodBody.ToArray());

                if (!eventAdded)
                {
                    this.ctx.WriterListener.OnWriter += InjectNativeCode;
                    eventAdded = true;
                }
                return;
            }

            if (methodDef.HasBody)
            {
                newMethodDef.Body          = new CilBody(methodDef.Body.InitLocals, new List <Instruction>(), new List <ExceptionHandler>(), new List <Local>());
                newMethodDef.Body.MaxStack = methodDef.Body.MaxStack;

                var bodyMap = new Dictionary <object, object>();

                foreach (Local local in methodDef.Body.Variables)
                {
                    var newLocal = new Local(ctx.Importer.Import(local.Type));
                    newMethodDef.Body.Variables.Add(newLocal);
                    newLocal.Name          = local.Name;
                    newLocal.PdbAttributes = local.PdbAttributes;

                    bodyMap[local] = newLocal;
                }

                foreach (Instruction instr in methodDef.Body.Instructions)
                {
                    var newInstr = new Instruction(instr.OpCode, instr.Operand);
                    newInstr.SequencePoint = instr.SequencePoint;

                    if (newInstr.Operand is IType)
                    {
                        newInstr.Operand = ctx.Importer.Import((IType)newInstr.Operand);
                    }

                    else if (newInstr.Operand is IMethod)
                    {
                        newInstr.Operand = ctx.Importer.Import((IMethod)newInstr.Operand);
                    }

                    else if (newInstr.Operand is IField)
                    {
                        newInstr.Operand = ctx.Importer.Import((IField)newInstr.Operand);
                    }

                    newMethodDef.Body.Instructions.Add(newInstr);
                    bodyMap[instr] = newInstr;
                }

                foreach (Instruction instr in newMethodDef.Body.Instructions)
                {
                    if (instr.Operand != null && bodyMap.ContainsKey(instr.Operand))
                    {
                        instr.Operand = bodyMap[instr.Operand];
                    }

                    else if (instr.Operand is Instruction[])
                    {
                        instr.Operand = ((Instruction[])instr.Operand).Select(target => (Instruction)bodyMap[target]).ToArray();
                    }
                }

                foreach (ExceptionHandler eh in methodDef.Body.ExceptionHandlers)
                {
                    newMethodDef.Body.ExceptionHandlers.Add(new ExceptionHandler(eh.HandlerType)
                    {
                        CatchType    = eh.CatchType == null ? null : (ITypeDefOrRef)ctx.Importer.Import(eh.CatchType),
                        TryStart     = (Instruction)bodyMap[eh.TryStart],
                        TryEnd       = (Instruction)bodyMap[eh.TryEnd],
                        HandlerStart = (Instruction)bodyMap[eh.HandlerStart],
                        HandlerEnd   = (Instruction)bodyMap[eh.HandlerEnd],
                        FilterStart  = eh.FilterStart == null ? null : (Instruction)bodyMap[eh.FilterStart]
                    });
                }

                newMethodDef.Body.SimplifyMacros(newMethodDef.Parameters);
            }
        }
示例#7
0
        void CreateSections(ModuleWriterBase writer)
        {
            var nameBuffer = new byte[8];

            nameBuffer[0] = (byte)(name1 >> 0);
            nameBuffer[1] = (byte)(name1 >> 8);
            nameBuffer[2] = (byte)(name1 >> 16);
            nameBuffer[3] = (byte)(name1 >> 24);
            nameBuffer[4] = (byte)(name2 >> 0);
            nameBuffer[5] = (byte)(name2 >> 8);
            nameBuffer[6] = (byte)(name2 >> 16);
            nameBuffer[7] = (byte)(name2 >> 24);
            var newSection = new PESection(Encoding.ASCII.GetString(nameBuffer), 0xE0000040);

            writer.Sections.Insert(0, newSection); // insert first to ensure proper RVA

            uint alignment;

            alignment = writer.TextSection.Remove(writer.MetaData).Value;
            writer.TextSection.Add(writer.MetaData, alignment);

            alignment = writer.TextSection.Remove(writer.NetResources).Value;
            writer.TextSection.Add(writer.NetResources, alignment);

            alignment = writer.TextSection.Remove(writer.Constants).Value;
            newSection.Add(writer.Constants, alignment);

            // move some PE parts to separate section to prevent it from being hashed
            var  peSection = new PESection("", 0x60000020);
            bool moved     = false;

            if (writer.StrongNameSignature != null)
            {
                alignment = writer.TextSection.Remove(writer.StrongNameSignature).Value;
                peSection.Add(writer.StrongNameSignature, alignment);
                moved = true;
            }
            var managedWriter = writer as ModuleWriter;

            if (managedWriter != null)
            {
                if (managedWriter.ImportAddressTable != null)
                {
                    alignment = writer.TextSection.Remove(managedWriter.ImportAddressTable).Value;
                    peSection.Add(managedWriter.ImportAddressTable, alignment);
                    moved = true;
                }
                if (managedWriter.StartupStub != null)
                {
                    alignment = writer.TextSection.Remove(managedWriter.StartupStub).Value;
                    peSection.Add(managedWriter.StartupStub, alignment);
                    moved = true;
                }
            }
            if (moved)
            {
                writer.Sections.Add(peSection);
            }

            // move encrypted methods
            var encryptedChunk = new MethodBodyChunks(writer.TheOptions.ShareMethodBodies);

            newSection.Add(encryptedChunk, 4);
            foreach (MethodDef method in methods)
            {
                if (!method.HasBody)
                {
                    continue;
                }
                MethodBody body = writer.MetaData.GetMethodBody(method);
                bool       ok   = writer.MethodBodies.Remove(body);
                encryptedChunk.Add(body);
            }

            // padding to prevent bad size due to shift division
            newSection.Add(new ByteArrayChunk(new byte[4]), 4);
        }
示例#8
0
			void InjectNativeCode(object sender, ModuleWriterListenerEventArgs e) {
				var writer = (ModuleWriterBase)sender;
				if (e.WriterEvent == ModuleWriterEvent.MDEndWriteMethodBodies) {
					codeChunk = writer.MethodBodies.Add(new MethodBody(code));
				}
				else if (e.WriterEvent == ModuleWriterEvent.EndCalculateRvasAndFileOffsets) {
					uint rid = writer.MetaData.GetRid(native);
					writer.MetaData.TablesHeap.MethodTable[rid].RVA = (uint)codeChunk.RVA;
				}
			}
示例#9
0
 /// <summary>
 /// Adds a <see cref="MethodBody"/> and returns the one that has been cached
 /// </summary>
 /// <param name="methodBody">The method body</param>
 /// <returns>The cached method body</returns>
 public MethodBody Add(MethodBody methodBody) => Add(methodBody, 0, 0);
示例#10
0
 public ReusedMethodInfo(MethodBody methodBody, RVA rva)
 {
     MethodBody = methodBody;
     RVA        = rva;
 }