use std::path::PathBuf;
use crate::compression::enums::{CompressionEngine, CompressionLevel};
use crate::prelude::{BuildOptions, BypassOptions, CryptoOptions, DebugOptions, DonutConfig, DotnetConfiguration, ExecutionOptions};
use crate::fs::file_info::FileInfo;
use crate::instance::{DonutEmbeddedInstance, DonutHttpInstance};
use crate::types::enums::{AmsiBypassTechnique, DonutCryptoProvider, EntropyLevel, EtwBypassTechnique, ExitMethod, InstanceType, OutputFormat};
impl DonutConfig {
#[inline]
pub fn new(input: impl Into<PathBuf>) -> Self {
Self {
input_file: input.into(),
..Default::default()
}
}
#[inline]
pub fn input(mut self, path: impl Into<PathBuf>) -> Self {
self.input_file = path.into();
self
}
#[inline]
pub fn output(mut self, path: Option<impl Into<PathBuf>>) -> Self {
self.output_file = path.map(|p| p.into());
self
}
#[inline]
pub fn instance_output(mut self, path: Option<impl Into<PathBuf>>) -> Self {
self.instance_output = path.map(|p| p.into());
self
}
#[inline]
pub fn http_output(mut self, path: Option<impl Into<PathBuf>>) -> Self {
self.http_output = path.map(|p| p.into());
self
}
#[inline]
pub fn http_options(mut self, opts: Option<DonutHttpInstance>) -> Self {
self.http_options = opts;
self
}
#[inline]
pub fn embedded_options(mut self, opts: DonutEmbeddedInstance) -> Self {
self.embedded_options = Some(opts);
self
}
#[inline]
pub fn file_info(mut self, opts: FileInfo) -> Self {
self.file_info = opts;
self
}
#[inline]
pub fn dotnet_options(mut self, opts: DotnetConfiguration) -> Self {
self.dotnet_options = Some(opts);
self
}
#[inline]
pub fn exec_options(mut self, opts: ExecutionOptions) -> Self {
self.exec_options = opts;
self
}
#[inline]
pub fn debug_options(mut self, opts: DebugOptions) -> Self {
self.debug_options = opts;
self
}
#[inline]
pub fn build_options(mut self, opts: BuildOptions) -> Self {
self.build_options = opts;
self
}
#[inline]
pub fn crypto_options(mut self, opts: CryptoOptions) -> Self {
self.crypto_options = Some(opts);
self
}
#[inline]
pub fn bypass_options(mut self, opts: BypassOptions) -> Self {
self.bypass_options = opts;
self
}
#[inline]
pub fn with_exec(mut self, f: impl FnOnce(&mut ExecutionOptions)) -> Self {
f(&mut self.exec_options);
self
}
#[inline]
pub fn with_debug(mut self, f: impl FnOnce(&mut DebugOptions)) -> Self {
f(&mut self.debug_options);
self
}
#[inline]
pub fn with_build(mut self, f: impl FnOnce(&mut BuildOptions)) -> Self {
f(&mut self.build_options);
self
}
#[inline]
pub fn with_crypto(mut self, f: impl FnOnce(&mut Option<CryptoOptions>)) -> Self {
f(&mut self.crypto_options);
self
}
#[inline]
pub fn with_bypass(mut self, f: impl FnOnce(&mut BypassOptions)) -> Self {
f(&mut self.bypass_options);
self
}
#[inline]
pub fn with_dotnet(mut self, f: impl FnOnce(&mut DotnetConfiguration)) -> Self {
if self.dotnet_options.is_none() {
self.dotnet_options = Some(DotnetConfiguration::default());
}
f(self.dotnet_options.as_mut().unwrap());
self
}
#[inline]
pub fn with_http(mut self, f: impl FnOnce(&mut DonutHttpInstance)) -> Self {
if self.http_options.is_none() {
self.http_options = Some(DonutHttpInstance::default());
}
f(self.http_options.as_mut().unwrap());
self
}
#[inline]
pub fn with_embedded(mut self, f: impl FnOnce(&mut DonutEmbeddedInstance)) -> Self {
if self.embedded_options.is_none() {
self.embedded_options = Some(DonutEmbeddedInstance::default());
}
f(self.embedded_options.as_mut().unwrap());
self
}
}
impl ExecutionOptions {
#[inline] pub fn new() -> Self { Self::default() }
#[inline] pub fn thread_on_enter(mut self, v: bool) -> Self { self.thread_on_enter = v; self }
#[inline] pub fn decoy_path(mut self, s: Option<impl Into<String>>) -> Self { self.decoy_path = s.map(|s| s.into()); self }
#[inline] pub fn decoy_args(mut self, s: Option<impl Into<String>>) -> Self { self.decoy_args = s.map(|s| s.into()); self }
#[inline] pub fn args(mut self, s: Option<impl Into<String>>) -> Self { self.args = s.map(|s| s.into()); self}
#[inline] pub fn exit_method(mut self, m: Option<ExitMethod>) -> Self { self.exit_method = m; self }
#[inline] pub fn args_str(mut self, s: Option<impl Into<String>>) -> Self { self.args = s.map(|s| s.into()); self }
#[inline] pub fn function(mut self, s: Option<impl Into<String>>) -> Self { self.function = s.map(|s| s.into()); self }
}
impl DebugOptions {
#[inline] pub fn new() -> Self { Self::default() }
#[inline] pub fn prepend_debug_flag(mut self, v: bool) -> Self { self.prepend_debug_flag = v; self }
#[inline] pub fn version(mut self, v: Option<u32>) -> Self { self.version = v; self }
#[inline] pub fn instance_seed(mut self, v: Option<u32>) -> Self { self.instance_seed = v; self }
#[inline] pub fn clean_output_dir(mut self, v: bool) -> Self { self.clean_output_dir = v; self }
}
impl BuildOptions {
#[inline] pub fn new() -> Self { Self::default() }
#[inline] pub fn assert_module_integrity(mut self, v: bool) -> Self { self.assert_module_integrity = v; self }
#[inline] pub fn emit_metadata(mut self, v: bool) -> Self { self.emit_metadata = v; self }
#[inline] pub fn metadata_output(mut self, p: Option<impl Into<PathBuf>>) -> Self { self.metadata_output = p.map(|p| p.into()); self }
#[inline] pub fn instance_type(mut self, t: InstanceType) -> Self { self.instance_type = t; self }
#[inline] pub fn compression_level(mut self, l: CompressionLevel) -> Self { self.compression_level = l; self }
#[inline] pub fn compression_engine(mut self, e: CompressionEngine) -> Self { self.compression_engine = e; self }
#[inline] pub fn output_format(mut self, f: OutputFormat) -> Self { self.output_format = f; self }
}
impl CryptoOptions {
#[inline] pub fn new() -> Self { Self::default() }
#[inline] pub fn key(mut self, k: Vec<u8>) -> Self { self.key = k; self }
#[inline] pub fn iv(mut self, iv: Vec<u8>) -> Self { self.iv = iv; self }
#[inline] pub fn provider(mut self, p: DonutCryptoProvider) -> Self { self.provider = p; self }
}
impl BypassOptions {
#[inline] pub fn new() -> Self { Self::default() }
#[inline] pub fn disable_wdac(mut self, v: bool) -> Self { self.disable_wdac = v; self }
#[inline] pub fn patch_syscall_gate(mut self, v: bool) -> Self { self.patch_syscall_gate = v; self }
#[inline] pub fn amsi_bypass_technique(mut self, t: Option<AmsiBypassTechnique>) -> Self { self.amsi_bypass_technique = t; self }
#[inline] pub fn etw_bypass_technique(mut self, t: Option<EtwBypassTechnique>) -> Self { self.etw_bypass_technique = t; self }
#[inline] pub fn entropy_level(mut self, e: EntropyLevel) -> Self { self.entropy_level = e; self }
}
impl DotnetConfiguration {
#[inline] pub fn new() -> Self { Self::default() }
#[inline] pub fn runtime(mut self, s: Option<impl Into<String>>) -> Self { self.runtime = s.map(|s|s.into()); self }
#[inline] pub fn domain(mut self, s: Option<impl Into<String>>) -> Self { self.domain = s.map(|s|s.into()); self }
#[inline] pub fn class(mut self, s: Option<impl Into<String>>) -> Self { self.class = s.map(|s|s.into()); self }
#[inline] pub fn method(mut self, s: Option<impl Into<String>>) -> Self { self.method = s.map(|s|s.into()); self }
#[inline] pub fn version(mut self, s: Option<impl Into<String>>) -> Self { self.version = s.map(|s|s.into()); self }
#[inline] pub fn args_vec(mut self, v: Vec<String>) -> Self { self.args = Some(v); self }
#[inline]
pub fn arg(mut self, s: impl Into<String>) -> Self {
match &mut self.args {
Some(v) => v.push(s.into()),
None => self.args = Some(vec![s.into()]),
}
self
}
#[inline]
pub fn args(mut self, s: Option<impl Into<Vec<String>>>) -> Self {
self.args = s.map(|s|s.into());
self
}
}