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; } }
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; } }
/// <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; }
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; } }
/// <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); } }
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); }
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; } }
/// <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);
public ReusedMethodInfo(MethodBody methodBody, RVA rva) { MethodBody = methodBody; RVA = rva; }