private static void InsertVmBody(object sender, ModuleWriterEventArgs e) { var mainSection = new PESection(".Nasha0", 0x60000020); var references = new PESection(".Nasha1", 0x60000020); var opcodesList = new PESection(".Nasha2", 0x60000020); var writer = (ModuleWriterBase)sender; TokenGetter.Writer = writer; if (e.Event != ModuleWriterEvent.MDMemberDefRidsAllocated) { return; } var translated = Settings.Translated; var bufferedLength = 0; var nasha0 = new byte[0]; for (int i = 0; i < translated.Count; ++i) { var methodBytes = Settings.Serialize(translated[i]); Array.Resize(ref nasha0, nasha0.Length + methodBytes.Count); methodBytes.CopyTo(nasha0, bufferedLength); Settings.Translated[i].Method.Body.Instructions.Last(x => x.OpCode == OpCodes.Ldc_I4).Operand = bufferedLength; bufferedLength += methodBytes.Count; } mainSection.Add(new ByteArrayChunk(Compress(nasha0)), 1); references.Add(new ByteArrayChunk(Compress(Settings.TranslateReference().ToArray())), 1); opcodesList.Add(new ByteArrayChunk(NashaSettings.TranslateOpcodes().ToArray()), 1); NashaSections.Add(mainSection); NashaSections.Add(references); NashaSections.Add(opcodesList); }
private static void OptionsOnWriterEvent(object sender, ModuleWriterEventArgs e) { switch (e.Event) { case ModuleWriterEvent.ChunksAddedToSections: { var writerNativeEntryPoint = ((ModuleWriter)e.Writer).NativeEntryPoint; if (_nativeEntryPoint != null) { writerNativeEntryPoint.Enable = true; writerNativeEntryPoint.ManagedEntryPoint = _nativeEntryPoint; } else { writerNativeEntryPoint.Enable = false; } return; } case ModuleWriterEvent.EndCalculateRvasAndFileOffsets: if (_nativeEntryPoint != null) { ((ModuleWriter)e.Writer).Metadata.module.NativeEntryPoint = ((ModuleWriter)e.Writer).NativeEntryPoint.RVA; } break; } }
void OnWriterEvent(object sender, ModuleWriterEventArgs e) { ThrowIfCanceled(); ((ModuleFileProgress)fileProgress).CurrentEventIndex = e.Event - ModuleWriterEvent.Begin; Debug.Assert(((ModuleFileProgress)fileProgress).CurrentEventIndex >= 0); NotifyProgressUpdated(); }
private static void InsertVMBodies(object sender, ModuleWriterEventArgs e) { var MainSection = new PESection(".Nasha0", 0x60000020); var Referencies = new PESection(".Nasha1", 0x60000020); var writer = (ModuleWriterBase)sender; if (e.Event != ModuleWriterEvent.MDMemberDefRidsAllocated) { return; } var translateds = settings.Translated; var buferedLength = 0; var nasha0 = new byte[0]; foreach (var translated in translateds) { var methodBytes = settings.Serialize(translated); Array.Resize(ref nasha0, nasha0.Length + methodBytes.Count); methodBytes.CopyTo(nasha0, buferedLength); buferedLength += methodBytes.Count; } MainSection.Add(new ByteArrayChunk(Compress(nasha0)), 1); Referencies.Add(new ByteArrayChunk(new byte[1]), 1); NashaSections.Add(MainSection); NashaSections.Add(Referencies); }
private static void OnWriterEvent(object sender, ModuleWriterEventArgs e) { if (e.Event == ModuleWriterEvent.ChunksCreated) { var moduleWriter = (ModuleWriter)e.Writer; moduleWriter.ImportDirectory.DllToImport = "ijwhost.dll"; } }
private static void InsertSections(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDMemberDefRidsAllocated + 1) { NashaSections.ForEach(x => writer.AddSection(x)); } }
void EncodeField(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDMemberDefRidsAllocated && keyAttrs != null) { Dictionary <TypeDef, Func <int, int> > keyFuncs = keyAttrs .Where(entry => entry != null) .ToDictionary(entry => entry.Item1, entry => entry.Item2); foreach (FieldDesc desc in fieldDescs) { uint token = writer.Metadata.GetToken(desc.Method).Raw; uint key = encodeCtx.Random.NextUInt32() | 1; // CA CustomAttribute ca = desc.Field.CustomAttributes[0]; int encodedKey = keyFuncs[(TypeDef)ca.AttributeType]((int)MathsUtils.modInv(key)); ca.ConstructorArguments.Add(new CAArgument(encodeCtx.Module.CorLibTypes.Int32, encodedKey)); token *= key; // Encoding token = (uint)desc.InitDesc.Encoding.Encode(desc.InitDesc.Method, encodeCtx, (int)token); // Field name var name = new char[5]; name[desc.InitDesc.OpCodeIndex] = (char)((byte)desc.OpCode ^ desc.OpKey); byte[] nameKey = encodeCtx.Random.NextBytes(4); uint encodedNameKey = 0; for (int i = 0; i < 4; i++) { // No zero bytes while (nameKey[i] == 0) { nameKey[i] = encodeCtx.Random.NextByte(); } name[desc.InitDesc.TokenNameOrder[i]] = (char)nameKey[i]; encodedNameKey |= (uint)nameKey[i] << desc.InitDesc.TokenByteOrder[i]; } desc.Field.Name = new string(name); // Field sig FieldSig sig = desc.Field.FieldSig; uint encodedToken = (token - writer.Metadata.GetToken(((CModOptSig)sig.Type).Modifier).Raw) ^ encodedNameKey; var extra = new byte[8]; extra[0] = 0xc0; extra[3] = (byte)(encodedToken >> desc.InitDesc.TokenByteOrder[3]); extra[4] = 0xc0; extra[5] = (byte)(encodedToken >> desc.InitDesc.TokenByteOrder[2]); extra[6] = (byte)(encodedToken >> desc.InitDesc.TokenByteOrder[1]); extra[7] = (byte)(encodedToken >> desc.InitDesc.TokenByteOrder[0]); sig.ExtraData = extra; } } }
void WriterEvent(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDEndCreateTables) { CreateSections(writer); } else if (e.Event == ModuleWriterEvent.BeginStrongNameSign) { EncryptSection(writer); } }
void WriterEvent(object sender, ModuleWriterEventArgs e) { switch (e.Event) { case ModuleWriterEvent.MDEndCreateTables: CreateSections(e.Writer); break; case ModuleWriterEvent.BeginStrongNameSign: EncryptSection(e.Writer); break; } }
void OnWriterEvent(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDBeginWriteMethodBodies) { context.Logger.Debug("Extracting method bodies..."); CreateSection(writer); } else if (e.Event == ModuleWriterEvent.BeginStrongNameSign) { context.Logger.Debug("Encrypting method section..."); EncryptSection(writer); } }
private static void InsertVMBodies(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event != ModuleWriterEvent.MDMemberDefRidsAllocated) { return; } TokenGetter.Writer = writer; var body = Context.Bodies[writer.Module]; var data = body.Serialize(); writer.Module.Resources.Add(new EmbeddedResource(" ", Compress(data))); }
private static void OnWriterEvent(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.PESectionsCreated) { var section = new PESection(".origami", 0xC0000080 /*0x40000080*/); writer.AddSection(section); Console.WriteLine($"Created new pe section {section.Name} with characteristics {section.Characteristics:X}"); section.Add(new ByteArrayChunk(_payload.Compress()), 4); Console.WriteLine($"Wrote {_payload.Length.ToString()} bytes to section {section.Name}"); } }
private static void OnWriterEvent(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.PESectionsCreated) { var section = new PESection(".origami", 0x40000080); writer.AddSection(section); Console.WriteLine("Created new pe section {0} with characteristics {1}", section.Name, section.Characteristics.ToString("x8")); section.Add(new ByteArrayChunk(Compress(payload)), 4); Console.WriteLine("Wrote {0} bytes to section {1}", payload.Length.ToString(), section.Name); } }
public void WriterEvent(object sender, ModuleWriterEventArgs e) { if (e.Event == ModuleWriterEvent.MDEndAddResources) { var writer = e.Writer; ctx.ManifestResources = new List <(uint, uint, UTF8String)>(); foreach (var resource in writer.Module.Resources) { var rid = writer.Metadata.GetManifestResourceRid(resource); if (rid != 0) { // The resource has a RID assigned. So it is part of the written module. var resourceRow = writer.Metadata.TablesHeap.ManifestResourceTable[rid]; Debug.Assert(resourceRow.Name == writer.Metadata.StringsHeap.Add(resource.Name), "Resource with RID has different name in StringHeap?!"); ctx.ManifestResources.Add((resourceRow.Offset, resourceRow.Flags, resource.Name)); } } ctx.EntryPointToken = writer.Metadata.GetToken(ctx.EntryPoint).Raw; } }
void InjectNativeCode(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDEndWriteMethodBodies) { for (int n = 0; n < nativeCodes.Count; n++) nativeCodes[n] = new Tuple<MethodDef, byte[], MethodBody>( nativeCodes[n].Item1, nativeCodes[n].Item2, writer.MethodBodies.Add(new MethodBody(nativeCodes[n].Item2))); } else if (e.Event == ModuleWriterEvent.EndCalculateRvasAndFileOffsets) { foreach (var native in nativeCodes) { uint rid = writer.Metadata.GetRid(native.Item1); RawMethodRow methodRow = writer.Metadata.TablesHeap.MethodTable[rid]; writer.Metadata.TablesHeap.MethodTable[rid] = new RawMethodRow( (uint)native.Item3.RVA, methodRow.ImplFlags, methodRow.Flags, methodRow.Name, methodRow.Signature, methodRow.ParamList); } } }
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; } }
void OnWriterEvent(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDEndCreateTables) { // These hurts reflection /* * uint methodLen = (uint)writer.MetaData.TablesHeap.MethodTable.Rows + 1; * uint fieldLen = (uint)writer.MetaData.TablesHeap.FieldTable.Rows + 1; * * var root = writer.MetaData.TablesHeap.TypeDefTable.Add(new RawTypeDefRow( * 0, 0x7fff7fff, 0, 0x3FFFD, fieldLen, methodLen)); * writer.MetaData.TablesHeap.NestedClassTable.Add(new RawNestedClassRow(root, root)); * * var namespaces = writer.MetaData.TablesHeap.TypeDefTable * .Select(row => row.Namespace) * .Distinct() * .ToList(); * foreach (var ns in namespaces) * { * if (ns == 0) continue; * var type = writer.MetaData.TablesHeap.TypeDefTable.Add(new RawTypeDefRow( * 0, 0, ns, 0x3FFFD, fieldLen, methodLen)); * writer.MetaData.TablesHeap.NestedClassTable.Add(new RawNestedClassRow(root, type)); * } * * foreach (var row in writer.MetaData.TablesHeap.ParamTable) * row.Name = 0x7fff7fff; */ writer.Metadata.TablesHeap.ModuleTable.Add(new RawModuleRow(0, 0x7fff7fff, 0, 0, 0)); writer.Metadata.TablesHeap.AssemblyTable.Add(new RawAssemblyRow(0, 0, 0, 0, 0, 0, 0, 0x7fff7fff, 0)); int r = random.NextInt32(8, 16); for (int i = 0; i < r; i++) { writer.Metadata.TablesHeap.ENCLogTable.Add(new RawENCLogRow(random.NextUInt32(), random.NextUInt32())); } r = random.NextInt32(8, 16); for (int i = 0; i < r; i++) { writer.Metadata.TablesHeap.ENCMapTable.Add(new RawENCMapRow(random.NextUInt32())); } //Randomize(writer.MetaData.TablesHeap.NestedClassTable); Randomize(writer.Metadata.TablesHeap.ManifestResourceTable); //Randomize(writer.MetaData.TablesHeap.GenericParamConstraintTable); writer.TheOptions.MetadataOptions.TablesHeapOptions.ExtraData = random.NextUInt32(); writer.TheOptions.MetadataOptions.TablesHeapOptions.UseENC = false; writer.TheOptions.MetadataOptions.MetadataHeaderOptions.VersionString += "\0\0\0\0"; /* * We are going to create a new specific '#GUID' Heap to avoid UnConfuserEX to work. * <sarcasm>UnConfuserEX is so well coded, it relies on static cmp between values</sarcasm> * If you deobfuscate this tool, you can see that it check for #GUID size and compare it to * '16', so we have to create a new array of byte wich size is exactly 16 and put it into * our brand new Heap */ // writer.TheOptions.MetadataOptions.CustomHeaps.Add(new RawHeap("#GUID", Guid.NewGuid().ToByteArray())); // writer.TheOptions.MetadataOptions.CustomHeaps.Add(new RawHeap("#Strings", new byte[1])); writer.TheOptions.MetadataOptions.CustomHeaps.Add(new RawHeap("#Blob", new byte[1])); writer.TheOptions.MetadataOptions.CustomHeaps.Add(new RawHeap("#Schema", new byte[1])); } else if (e.Event == ModuleWriterEvent.MDOnAllTablesSorted) { writer.Metadata.TablesHeap.DeclSecurityTable.Add(new RawDeclSecurityRow( unchecked (0x7fff), 0xffff7fff, 0xffff7fff)); /* * writer.MetaData.TablesHeap.ManifestResourceTable.Add(new RawManifestResourceRow( * 0x7fff7fff, (uint)ManifestResourceAttributes.Private, 0x7fff7fff, 2)); */ } }
void OnWriterEvent(object sender, ModuleWriterEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.Event == ModuleWriterEvent.MDBeginAddResources) { ctx.Context.CheckCancellation(); ctx.Context.Logger.Debug("Encrypting resources..."); bool hasPacker = ctx.Context.Packer != null; List <EmbeddedResource> resources = ctx.Module.Resources.OfType <EmbeddedResource>().ToList(); if (!hasPacker) { ctx.Module.Resources.RemoveWhere(res => res is EmbeddedResource); } // move resources string asmName = ctx.Name.RandomName(RenameMode.Letters); PublicKey pubKey = null; if (writer.TheOptions.StrongNamePublicKey != null) { pubKey = PublicKeyBase.CreatePublicKey(writer.TheOptions.StrongNamePublicKey.CreatePublicKey()); } else if (writer.TheOptions.StrongNameKey != null) { pubKey = PublicKeyBase.CreatePublicKey(writer.TheOptions.StrongNameKey.PublicKey); } var assembly = new AssemblyDefUser(asmName, new Version(0, 0), pubKey); assembly.Modules.Add(new ModuleDefUser(asmName + ".dll")); ModuleDef module = assembly.ManifestModule; assembly.ManifestModule.Kind = ModuleKind.Dll; var asmRef = new AssemblyRefUser(module.Assembly); if (!hasPacker) { foreach (EmbeddedResource res in resources) { res.Attributes = ManifestResourceAttributes.Public; module.Resources.Add(res); ctx.Module.Resources.Add(new AssemblyLinkedResource(res.Name, asmRef, res.Attributes)); } } byte[] moduleBuff; using (var ms = new MemoryStream()) { var options = new ModuleWriterOptions(module) { StrongNameKey = writer.TheOptions.StrongNameKey, StrongNamePublicKey = writer.TheOptions.StrongNamePublicKey, DelaySign = writer.TheOptions.DelaySign }; module.Write(ms, options); moduleBuff = ms.ToArray(); } // compress moduleBuff = ctx.Context.Registry.GetService <ICompressionService>().Compress( moduleBuff, progress => ctx.Context.Logger.Progress((int)(progress * 10000), 10000)); ctx.Context.Logger.EndProgress(); ctx.Context.CheckCancellation(); uint compressedLen = (uint)(moduleBuff.Length + 3) / 4; compressedLen = (compressedLen + 0xfu) & ~0xfu; var compressedBuff = new uint[compressedLen]; Buffer.BlockCopy(moduleBuff, 0, compressedBuff, 0, moduleBuff.Length); Debug.Assert(compressedLen % 0x10 == 0); // encrypt uint keySeed = ctx.Random.NextUInt32() | 0x10; var key = new uint[0x10]; uint state = keySeed; for (int i = 0; i < 0x10; i++) { state ^= state >> 13; state ^= state << 25; state ^= state >> 27; key[i] = state; } var encryptedBuffer = new byte[compressedBuff.Length * 4]; int buffIndex = 0; while (buffIndex < compressedBuff.Length) { uint[] enc = ctx.ModeHandler.Encrypt(compressedBuff, buffIndex, key); for (int j = 0; j < 0x10; j++) { key[j] ^= compressedBuff[buffIndex + j]; } Buffer.BlockCopy(enc, 0, encryptedBuffer, buffIndex * 4, 0x40); buffIndex += 0x10; } Debug.Assert(buffIndex == compressedBuff.Length); var size = (uint)encryptedBuffer.Length; TablesHeap tblHeap = writer.Metadata.TablesHeap; uint classLayoutRid = writer.Metadata.GetClassLayoutRid(ctx.DataType); RawClassLayoutRow classLayout = tblHeap.ClassLayoutTable[classLayoutRid]; tblHeap.ClassLayoutTable[classLayoutRid] = new RawClassLayoutRow(classLayout.PackingSize, size, classLayout.Parent); uint dataFieldRid = writer.Metadata.GetRid(ctx.DataField); RawFieldRow dataField = tblHeap.FieldTable[dataFieldRid]; tblHeap.FieldTable[dataFieldRid] = new RawFieldRow((ushort)(dataField.Flags | (ushort)FieldAttributes.HasFieldRVA), dataField.Name, dataField.Signature); encryptedResource = writer.Constants.Add(new ByteArrayChunk(encryptedBuffer), 8); // inject key values MutationHelper.InjectKeys(ctx.InitMethod, new[] { 0, 1 }, new[] { (int)(size / 4), (int)(keySeed) }); } else if (e.Event == ModuleWriterEvent.EndCalculateRvasAndFileOffsets) { TablesHeap tblHeap = writer.Metadata.TablesHeap; uint fieldRvaRid = writer.Metadata.GetFieldRVARid(ctx.DataField); RawFieldRVARow fieldRva = tblHeap.FieldRVATable[fieldRvaRid]; tblHeap.FieldRVATable[fieldRvaRid] = new RawFieldRVARow((uint)encryptedResource.RVA, fieldRva.Field); } }
public void WriterEvent(object sender, ModuleWriterEventArgs args) { OnWriterEvent(args.Writer, args.Event); }