void Finalize(ModuleDefinition[] mods, byte[][] pes) { Packer packer = (Packer)(assemblies[0] as IAnnotationProvider).Annotations["Packer"]; if (assemblies[0].MainModule.Kind == ModuleKind.Dll || assemblies[0].MainModule.Kind == ModuleKind.NetModule) { param.Logger.Log("Warning: Cannot pack a library or net module!"); packer = null; } if (packer != null) { if (!Directory.Exists(param.DestinationPath)) { Directory.CreateDirectory(param.DestinationPath); } param.Logger.Log("Packing output assemblies..."); packer.Confuser = this; PackerParameter pParam = new PackerParameter(); pParam.Modules = mods; pParam.PEs = pes; pParam.Parameters = (NameValueCollection)(assemblies[0] as IAnnotationProvider).Annotations["PackerParams"]; string[] final = packer.Pack(param, pParam); for (int i = 0; i < final.Length; i++) { File.Move(final[i], Path.Combine(param.DestinationPath, Path.GetFileName(final[i]))); } } else { param.Logger.Log("Writing outputs..."); for (int i = 0; i < pes.Length; i++) { string dest = param.Marker.GetDestinationPath(mods[i], param.DestinationPath); if (!Directory.Exists(Path.GetDirectoryName(dest))) { Directory.CreateDirectory(Path.GetDirectoryName(dest)); } Stream dstStream = new FileStream(dest, FileMode.Create, FileAccess.Write); try { dstStream.Write(pes[i], 0, pes[i].Length); } finally { dstStream.Dispose(); } } } }
protected abstract void PackCore(out AssemblyDefinition asm, PackerParameter parameter);
protected override void PackCore(out AssemblyDefinition asm, PackerParameter parameter) { ModuleDefinition originMain = parameter.Modules[0]; asm = AssemblyDefinition.CreateAssembly(originMain.Assembly.Name, originMain.Name, new ModuleParameters() { Architecture = originMain.Architecture, Kind = originMain.Kind, Runtime = originMain.Runtime }); ModuleDefinition mod = asm.MainModule; Random rand = new Random(); int key0 = rand.Next(0, 0xff); int key1 = rand.Next(0, 0xff); EmbeddedResource res = new EmbeddedResource(Encoding.UTF8.GetString(Guid.NewGuid().ToByteArray()), ManifestResourceAttributes.Private, Encrypt(parameter.PEs[0], key0)); mod.Resources.Add(res); for (int i = 1; i < parameter.Modules.Length; i++) { if (parameter.Modules[i].IsMain) { mod.Resources.Add(new EmbeddedResource(GetNewName(parameter.Modules[i].Assembly.Name.FullName, key1), ManifestResourceAttributes.Private, Encrypt(parameter.PEs[i], key0))); } else { mod.Resources.Add(new EmbeddedResource(GetNewName(parameter.Modules[i].Name, key1), ManifestResourceAttributes.Private, Encrypt(parameter.PEs[i], key0))); //TODO: Support for multi-module asssembly } } AssemblyDefinition ldrC = AssemblyDefinition.ReadAssembly(typeof(Iid).Assembly.Location); TypeDefinition t = CecilHelper.Inject(mod, ldrC.MainModule.GetType("CompressShell")); foreach (Instruction inst in t.GetStaticConstructor().Body.Instructions) { if (inst.Operand is string) { inst.Operand = res.Name; } } foreach (Instruction inst in t.Methods.FirstOrDefault(mtd => mtd.Name == "Decrypt").Body.Instructions) { if (inst.Operand is int && (int)inst.Operand == 0x12345678) { inst.Operand = key0; } } foreach (Instruction inst in t.Methods.FirstOrDefault(mtd => mtd.Name == "DecryptAsm").Body.Instructions) { if (inst.Operand is int && (int)inst.Operand == 0x12345678) { inst.Operand = key1; } } t.Namespace = ""; t.DeclaringType = null; t.IsNestedPrivate = false; t.IsNotPublic = true; mod.Types.Add(t); MethodDefinition cctor = new MethodDefinition(".cctor", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Static, mod.TypeSystem.Void); mod.GetType("<Module>").Methods.Add(cctor); MethodBody bdy = cctor.Body = new MethodBody(cctor); ILProcessor psr = bdy.GetILProcessor(); psr.Emit(OpCodes.Call, mod.Import(typeof(AppDomain).GetProperty("CurrentDomain").GetGetMethod())); psr.Emit(OpCodes.Ldnull); psr.Emit(OpCodes.Ldftn, t.Methods.FirstOrDefault(mtd => mtd.Name == "DecryptAsm")); psr.Emit(OpCodes.Newobj, mod.Import(typeof(ResolveEventHandler).GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }))); psr.Emit(OpCodes.Callvirt, mod.Import(typeof(AppDomain).GetEvent("AssemblyResolve").GetAddMethod())); psr.Emit(OpCodes.Ret); MethodDefinition main = t.Methods.FirstOrDefault(mtd => mtd.Name == "Main"); mod.EntryPoint = main; }
public string[] Pack(ConfuserParameter crParam, PackerParameter param) { AssemblyDefinition asm; PackCore(out asm, param); string tmp = Path.GetTempPath() + "\\" + Path.GetRandomFileName() + "\\"; Directory.CreateDirectory(tmp); MetadataProcessor psr = new MetadataProcessor(); Section oldRsrc = null; foreach (Section s in param.Modules[0].GetSections()) { if (s.Name == ".rsrc") { oldRsrc = s; break; } } if (oldRsrc != null) { psr.ProcessImage += accessor => { Section sect = null; foreach (Section s in accessor.Sections) { if (s.Name == ".rsrc") { sect = s; break; } } if (sect == null) { sect = new Section() { Name = ".rsrc", Characteristics = 0x40000040 }; foreach (Section s in accessor.Sections) { if (s.Name == ".text") { accessor.Sections.Insert(accessor.Sections.IndexOf(s) + 1, sect); break; } } } sect.VirtualSize = oldRsrc.VirtualSize; sect.SizeOfRawData = oldRsrc.PointerToRawData; int idx = accessor.Sections.IndexOf(sect); sect.VirtualAddress = accessor.Sections[idx - 1].VirtualAddress + ((accessor.Sections[idx - 1].VirtualSize + 0x2000U - 1) & ~(0x2000U - 1)); sect.PointerToRawData = accessor.Sections[idx - 1].PointerToRawData + accessor.Sections[idx - 1].SizeOfRawData; for (int i = idx + 1; i < accessor.Sections.Count; i++) { accessor.Sections[i].VirtualAddress = accessor.Sections[i - 1].VirtualAddress + ((accessor.Sections[i - 1].VirtualSize + 0x2000U - 1) & ~(0x2000U - 1)); accessor.Sections[i].PointerToRawData = accessor.Sections[i - 1].PointerToRawData + accessor.Sections[i - 1].SizeOfRawData; } ByteBuffer buff = new ByteBuffer(oldRsrc.Data); PatchResourceDirectoryTable(buff, oldRsrc, sect); sect.Data = buff.GetBuffer(); }; } psr.Process(asm.MainModule, tmp + asm.MainModule.Name); Confuser cr = new Confuser(); ConfuserParameter par = new ConfuserParameter(); par.SourceAssembly = tmp + asm.MainModule.Name; par.ReferencesPath = tmp; tmp = Path.GetTempPath() + "\\" + Path.GetRandomFileName() + "\\"; par.DestinationPath = tmp; par.Confusions = crParam.Confusions; par.DefaultPreset = crParam.DefaultPreset; par.StrongNameKeyPath = crParam.StrongNameKeyPath; par.Marker = new PackerMarker(param.Modules[0]); cr.Confuse(par); return(Directory.GetFiles(tmp)); }