AssemblyRef CreateCorLibAssemblyRef() => module.UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20());
AssemblyRef ReadAssemblyRef() { var asmRef = new AssemblyRefUser(); if (ownerModule != null) { ownerModule.UpdateRowId(asmRef); } asmRef.Name = ReadAssemblyNameId(); SkipWhite(); if (PeekChar() != ',') { return(asmRef); } ReadChar(); while (true) { SkipWhite(); int c = PeekChar(); if (c == -1 || c == ']') { break; } if (c == ',') { ReadChar(); continue; } string key = ReadId(); SkipWhite(); if (PeekChar() != '=') { continue; } ReadChar(); string value = ReadId(); switch (key.ToUpperInvariant()) { case "VERSION": asmRef.Version = Utils.ParseVersion(value); break; case "CONTENTTYPE": if (value.Equals("WindowsRuntime", StringComparison.OrdinalIgnoreCase)) { asmRef.ContentType = AssemblyAttributes.ContentType_WindowsRuntime; } else { asmRef.ContentType = AssemblyAttributes.ContentType_Default; } break; case "RETARGETABLE": if (value.Equals("Yes", StringComparison.OrdinalIgnoreCase)) { asmRef.IsRetargetable = true; } else { asmRef.IsRetargetable = false; } break; case "PUBLICKEY": if (value.Equals("null", StringComparison.OrdinalIgnoreCase) || value.Equals("neutral", StringComparison.OrdinalIgnoreCase)) { asmRef.PublicKeyOrToken = new PublicKey(); } else { asmRef.PublicKeyOrToken = PublicKeyBase.CreatePublicKey(Utils.ParseBytes(value)); } break; case "PUBLICKEYTOKEN": if (value.Equals("null", StringComparison.OrdinalIgnoreCase) || value.Equals("neutral", StringComparison.OrdinalIgnoreCase)) { asmRef.PublicKeyOrToken = new PublicKeyToken(); } else { asmRef.PublicKeyOrToken = PublicKeyBase.CreatePublicKeyToken(Utils.ParseBytes(value)); } break; case "CULTURE": case "LANGUAGE": if (value.Equals("neutral", StringComparison.OrdinalIgnoreCase)) { asmRef.Culture = UTF8String.Empty; } else { asmRef.Culture = value; } break; } } return(asmRef); }
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); } }
void OnWriterEvent(object sender, ModuleWriterListenerEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.WriterEvent == 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.StrongNameKey != null) { pubKey = PublicKeyBase.CreatePublicKey(writer.TheOptions.StrongNameKey.PublicKey); } var module = new ModuleDefUser(asmName + ".dll", Guid.NewGuid(), ctx.Module.CorLibTypes.AssemblyRef); module.Kind = ModuleKind.Dll; var assembly = new AssemblyDefUser(asmName, new Version(1, 0), pubKey); assembly.Modules.Add(module); module.Characteristics = ctx.Module.Characteristics; module.Cor20HeaderFlags = ctx.Module.Cor20HeaderFlags; module.Cor20HeaderRuntimeVersion = ctx.Module.Cor20HeaderRuntimeVersion; module.DllCharacteristics = ctx.Module.DllCharacteristics; module.EncBaseId = ctx.Module.EncBaseId; module.EncId = ctx.Module.EncId; module.Generation = ctx.Module.Generation; module.Machine = ctx.Module.Machine; module.RuntimeVersion = ctx.Module.RuntimeVersion; module.TablesHeaderVersion = ctx.Module.TablesHeaderVersion; module.RuntimeVersion = ctx.Module.RuntimeVersion; var asmRef = new AssemblyRefUser(module.Assembly); if (pubKey == null) { asmRef.Attributes &= ~AssemblyAttributes.PublicKey; // ssdi: fix incorrect flags set in dnlib, "CS0009 .... -- Invalid public key." into VS2015, VS2017 msBuild } if (!hasPacker) { foreach (var 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()) { module.Write(ms, new ModuleWriterOptions(ctx.Module) { StrongNameKey = writer.TheOptions.StrongNameKey }); 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; tblHeap.ClassLayoutTable[writer.MetaData.GetClassLayoutRid(ctx.DataType)].ClassSize = size; tblHeap.FieldTable[writer.MetaData.GetRid(ctx.DataField)].Flags |= (ushort)FieldAttributes.HasFieldRVA; 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.WriterEvent == ModuleWriterEvent.EndCalculateRvasAndFileOffsets) { TablesHeap tblHeap = writer.MetaData.TablesHeap; tblHeap.FieldRVATable[writer.MetaData.GetFieldRVARid(ctx.DataField)].RVA = (uint)encryptedResource.RVA; } }
private AssemblyRef CreateCorLibAssemblyRef() { return(module.UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20())); }