private void CompileStub() { try { string resourceName = BytecodeApi.Create.AlphaNumericString(MathEx.Random.Next(20, 30)); uint stage2Key; uint stage2PaddingMask; int stage2PaddingByteCount; // Encrypt stage2 into [random name].resources using (ResourceWriter resourceWriter = new ResourceWriter(GetIntermediateSourcePath(@"Resources\" + StubResourcesFileName))) { string encryptedPath = GetIntermediateBinaryPath("stage2.exe_encrypted"); Helper.EncryptData ( GetIntermediateBinaryPath("stage2.exe"), encryptedPath, Project.Stub.Padding, out stage2Key, out stage2PaddingMask, out stage2PaddingByteCount ); resourceWriter.AddResource(resourceName, File.ReadAllBytes(encryptedPath)); } // Compile stub string[] stubLines = File.ReadAllLines(GetIntermediateSourcePath("Stub.cs")); using (CSharpStream assembly = new CSharpStream(GetIntermediateSourcePath("Stub.cs"))) { foreach (string line in stubLines) { if (line.Trim() == "//{STAGE2HEADER}") { assembly.Indent = 12; assembly.Emit("string resourceFileName = /**/\"" + StubResourcesFileName + "\";"); assembly.Emit("string resourceName = /**/\"" + resourceName + "\";"); assembly.Emit("const long stage2Size = " + new FileInfo(GetIntermediateBinaryPath("stage2.exe")).Length + ";"); assembly.Emit("uint key = 0x" + stage2Key.ToString("x8") + ";"); assembly.Emit("uint paddingMask = 0x" + stage2PaddingMask.ToString("x8") + ";"); assembly.Emit("int paddingByteCount = /**/" + stage2PaddingByteCount + ";"); } else { assembly.WriteLine(line); } } } // Add VersionInfo if (!Project.VersionInfo.IsEmpty) { using (CSharpStream versionInfo = new CSharpStream(GetIntermediateSourcePath("VersionInfo.cs"))) { versionInfo.Emit("using System.Reflection;"); versionInfo.WriteLine(); if (!Project.VersionInfo.FileDescription.IsNullOrEmpty()) { versionInfo.Emit("[assembly: AssemblyTitle(" + new QuotedString(Project.VersionInfo.FileDescription) + ")]"); } if (!Project.VersionInfo.ProductName.IsNullOrEmpty()) { versionInfo.Emit("[assembly: AssemblyProduct(" + new QuotedString(Project.VersionInfo.ProductName) + ")]"); } if (!Project.VersionInfo.FileVersion.IsNullOrEmpty()) { versionInfo.Emit("[assembly: AssemblyFileVersion(" + new QuotedString(Project.VersionInfo.FileVersion) + ")]"); } if (!Project.VersionInfo.ProductVersion.IsNullOrEmpty()) { versionInfo.Emit("[assembly: AssemblyInformationalVersion(" + new QuotedString(Project.VersionInfo.ProductVersion) + ")]"); } if (!Project.VersionInfo.Copyright.IsNullOrEmpty()) { versionInfo.Emit("[assembly: AssemblyCopyright(" + new QuotedString(Project.VersionInfo.Copyright) + ")]"); } } StubSourceCodeFiles.Add("VersionInfo.cs"); } // Obfuscate code Obfuscator.ObfuscateFile(GetIntermediateSourcePath("Stub.cs")); } catch (ErrorException ex) { Errors.Add(ErrorSource.Compiler, ErrorSeverity.Error, ex.Message, ex.Details); } catch (Exception ex) { Errors.Add(ErrorSource.Compiler, ErrorSeverity.Error, "Unhandled " + ex.GetType() + " while compiling stub.", ex.GetFullStackTrace()); } }
private void CompileStub() { try { // Encrypt stage2 into Stage2Shellcode.inc using (AssemblyStream assembly = new AssemblyStream(GetIntermediateSourcePath("Stage2Shellcode.inc"))) { Helper.EncryptData ( GetIntermediateBinaryPath("stage2.shellcode"), GetIntermediateBinaryPath("stage2.shellcode_encrypted"), Project.Stub.Padding, out uint key, out uint paddingMask, out int paddingByteCount ); assembly.EmitConstant("Stage2Size", new FileInfo(GetIntermediateBinaryPath("stage2.shellcode")).Length.ToString()); assembly.EmitConstant("Stage2Key", "0x" + key.ToString("x8")); assembly.EmitConstant("Stage2PaddingMask", "0x" + paddingMask.ToString("x8")); assembly.EmitConstant("Stage2PaddingByteCount", paddingByteCount.ToString()); assembly.EmitFileData("Stage2Shellcode", @"..\bin\stage2.shellcode_encrypted"); } // Compile stub string[] stubLines = File.ReadAllLines(GetIntermediateSourcePath("Stub.asm")); using (AssemblyStream assembly = new AssemblyStream(GetIntermediateSourcePath("Stub.asm"))) { foreach (string line in stubLines) { if (line.Trim() == ";{RSRC}") { assembly.Indent = 0; bool hasVersionInfo = !Project.VersionInfo.IsEmpty; bool hasManifest = Project.Manifest.Template != null || Project.Manifest.Path != null; bool hasIcon = Project.Stub.IconPath != null; List <string> directory = new List <string>(); if (hasVersionInfo) { directory.Add("RT_VERSION, VersionInfo"); } if (hasManifest) { directory.Add("RT_MANIFEST, Manifest"); } if (hasIcon) { directory.AddRange(new[] { "RT_ICON, Icons", "RT_GROUP_ICON, GroupIcon" }); } if (directory.Any()) { assembly.WriteLine("section '.rsrc' resource data readable"); assembly.Indent = 4; assembly.EmitDefinition("directory", directory); if (hasVersionInfo) { assembly.EmitDefinition("resource VersionInfo,", "1, LANG_NEUTRAL, VersionInfoData"); } if (hasManifest) { assembly.EmitDefinition("resource Manifest,", "1, LANG_NEUTRAL, ManifestData"); } if (hasIcon) { Icon[] icon = IconExtractor.FromFile(Project.Stub.IconPath)?.Split(); if (icon == null) { throw new ErrorException("Could not read icon from file '" + Path.GetFileName(Project.Stub.IconPath) + "'."); } for (int i = 0; i < icon.Length; i++) { icon[i].Save(GetIntermediateSourcePath(@"Resources\icon-" + (i + 1) + ".ico")); } assembly.EmitDefinition("resource Icons,", Enumerable.Range(1, icon.Length).Select(i => i + ", LANG_NEUTRAL, IconData" + i)); assembly.EmitDefinition("resource GroupIcon,", "1, LANG_NEUTRAL, GroupIconData"); assembly.EmitDefinition("icon GroupIconData,", Enumerable.Range(1, icon.Length).Select(i => "IconData" + i + @", 'Resources\icon-" + i + ".ico'")); } if (hasVersionInfo) { assembly.EmitDefinition ( "versioninfo VersionInfoData,", "VOS__WINDOWS32, VFT_APP, VFT2_UNKNOWN, LANG_ENGLISH+SUBLANG_DEFAULT, 0", "'FileDescription', '" + Helper.FasmEscapeDefinitionString(Project.VersionInfo.FileDescription) + "'", "'ProductName', '" + Helper.FasmEscapeDefinitionString(Project.VersionInfo.ProductName) + "'", "'FileVersion', '" + Helper.FasmEscapeDefinitionString(Project.VersionInfo.FileVersion) + "'", "'ProductVersion', '" + Helper.FasmEscapeDefinitionString(Project.VersionInfo.ProductVersion) + "'", "'LegalCopyright', '" + Helper.FasmEscapeDefinitionString(Project.VersionInfo.Copyright) + "'", "'OriginalFilename', '" + Helper.FasmEscapeDefinitionString(Project.VersionInfo.OriginalFilename) + "'" ); } if (hasManifest) { string manifestFileName; if (Project.Manifest.Template != null) { manifestFileName = Project.Manifest.Template.GetDescription(); } else if (Project.Manifest.Path != null) { manifestFileName = Path.GetFileNameWithoutExtension(Project.Manifest.Path); File.Copy(Project.Manifest.Path, GetIntermediateSourcePath(@"Resources\" + manifestFileName + ".manifest")); } else { throw new InvalidOperationException(); } assembly.WriteLine("\tresdata ManifestData"); assembly.WriteLine("\t\tfile 'Resources\\" + manifestFileName + ".manifest'"); assembly.WriteLine("\tendres"); } } } else { assembly.Indent = 0; assembly.WriteLine(line); } } } // Obfuscate code AssemblyObfuscator obfuscator = new AssemblyObfuscator(Path.Combine(IntermediateDirectorySource, "Obfuscator")); obfuscator.ObfuscateFile(GetIntermediateSourcePath("Stub.asm")); obfuscator.ObfuscateFile(GetIntermediateSourcePath("Emulator.asm")); } catch (ErrorException ex) { Errors.Add(ErrorSource.Compiler, ErrorSeverity.Error, ex.Message, ex.Details); } catch (Exception ex) { Errors.Add(ErrorSource.Compiler, ErrorSeverity.Error, "Unhandled " + ex.GetType() + " while compiling stub.", ex.GetFullStackTrace()); } }