Work on custom binaries

This commit is contained in:
Michael Mikovsky
2026-01-30 14:05:07 -07:00
parent b2fe85a698
commit 82d8e1ba10
21 changed files with 217 additions and 278 deletions
Generated
+20 -5
View File
@@ -3267,6 +3267,13 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "server2"
version = "0.0.0"
dependencies = [
"unshell",
]
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.6" version = "0.10.6"
@@ -3933,7 +3940,7 @@ dependencies = [
[[package]] [[package]]
name = "unshell-crypt" name = "unshell-crypt"
version = "0.0.0" version = "0.1.0"
dependencies = [ dependencies = [
"aes", "aes",
"block-padding 0.4.2", "block-padding 0.4.2",
@@ -3947,7 +3954,7 @@ dependencies = [
[[package]] [[package]]
name = "unshell-gui" name = "unshell-gui"
version = "0.0.0" version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"eframe", "eframe",
@@ -3967,7 +3974,7 @@ dependencies = [
[[package]] [[package]]
name = "unshell-manager" name = "unshell-manager"
version = "0.0.0" version = "0.1.0"
dependencies = [ dependencies = [
"bincode", "bincode",
"libc", "libc",
@@ -3978,7 +3985,7 @@ dependencies = [
[[package]] [[package]]
name = "unshell-obfuscate" name = "unshell-obfuscate"
version = "0.0.0" version = "0.1.0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3989,8 +3996,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "unshell-server" name = "unshell-payload"
version = "0.0.0" version = "0.0.0"
dependencies = [
"server2",
"unshell",
]
[[package]]
name = "unshell-server"
version = "0.1.0"
dependencies = [ dependencies = [
"axum", "axum",
"axum-extra", "axum-extra",
+16 -10
View File
@@ -1,4 +1,4 @@
cargo-features = ["trim-paths"] cargo-features = ["trim-paths", "panic-immediate-abort"]
[package] [package]
name = "unshell" name = "unshell"
@@ -14,11 +14,14 @@ include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"]
[workspace] [workspace]
members = [ members = [
# Binaries # Binaries
"unshell-gui", "unshell-server", "unshell-gui",
# UnShell Binaries
"unshell-server", "unshell-payload",
# Libraries # Libraries
"unshell-manager", "unshell-obfuscate", "unshell-crypt" "unshell-manager", "unshell-obfuscate", "unshell-crypt"
] , "core-modules/server2"]
[features] [features]
default = [] default = []
@@ -51,18 +54,21 @@ toml = "0.9.9"
[profile.release] [profile.release]
opt-level = 2 opt-level = 2
# strip = true # Strip symbols from the binary
# opt-level = "z" # Optimize for size
# lto = true # Link tree optimization
# codegen-units = 1
# panic = "abort"
# debug = false # Remove debug
# trim-paths="all"
# Optimize all dependencies even in debug builds: # Optimize all dependencies even in debug builds:
[profile.dev.package."*"] [profile.dev.package."*"]
opt-level = 2 opt-level = 2
[profile.minimize]
inherits = "release"
strip = true # Strip symbols from the binary
opt-level = "z" # Optimize for size
lto = true # Link tree optimization
codegen-units = 1
panic = "immediate-abort"
debug = false # Remove debug
trim-paths="all"
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
# Lints: # Lints:
Executable
+56
View File
@@ -0,0 +1,56 @@
# # -Cpanic=immediate-abort
# RUSTFLAGS="-Zunstable-options -Zlocation-detail=none -Zfmt-debug=none" \
# cargo +nightly build \
# -Z build-std=std,panic_abort \
# -Z build-std-features= \
# --profile minimize -p unshell-payload -- $@
cargo build --profile minimize -p unshell-payload
export BINARY=./target/minimize/unshell-payload
declare -a headers=(
".gnu_debuglink" # - Debug information link
".comment" #- Compiler version info
".shstrtab" #- Section header string table (only needed by tools like readelf)
".note.gnu.bu" ".note.gnu.build-id" # - Build ID note
".eh_frame" ".eh_frame_hdr" # Exception handling info (can break C++ exceptions if removed)
#".gnu.version" ".gnu.version_r" # Symbol versioning (may be needed for some shared libraries)
".gnu.hash" # Hash table for symbol lookup optimization
# .shstrtab
# .interp
# .note.ABI-tag
# .dynsym
# .dynstr
# .rela.dyn
# .rodata
# .text
# .init
# .fini
# .tbss
# .fini_array
# .init_array
# .data.rel.ro
# .dynamic
# .got
# .got.plt
# .relro_padding
# .tm_clone_table
# .data
# .bss
)
# TODO: Implement FAKE section header comments and information
# Shuffle order of headers??
for section in "${headers[@]}"
do
strip --remove-section="$section" $BINARY
echo "Removed section header $section"
done
@@ -1,11 +0,0 @@
name="Client"
version="0.1"
description="Test Client module"
authors=["astatin3"]
[config]
header1 = { Header = "Header123" }
integer1 = { Integer = {}}
[build_config]
@@ -1,9 +0,0 @@
name="Server"
version="0.1"
description="Test server module for unshell"
authors=["astatin3"]
[config]
header1 = { Header = "Header123" }
integer1 = { Integer = {}}
+16
View File
@@ -0,0 +1,16 @@
[package]
name = "server2"
edition = "2024"
[features]
log = ["unshell/log"]
log_debug = ["unshell/log_debug"]
# [lib]
# crate-type = ["cdylib"]
[dependencies]
unshell.path = "../../"
[lints]
workspace = true
+5
View File
@@ -0,0 +1,5 @@
use unshell::info;
pub fn log_test_fn() {
info!("Testttttttt");
}
-9
View File
@@ -1,9 +0,0 @@
name="UnShell Core"
version="0.1"
description="Core components for UnShell"
authors=["astatin3"]
child_components = [
"client/unshell_component.toml",
"server/unshell_component.toml"
]
+1 -1
View File
@@ -1,5 +1,5 @@
pub mod config_struct; pub mod config_struct;
pub mod config_struct_list; // pub mod config_struct_list;
mod tree; mod tree;
pub use tree::{InterfaceData, InterfaceStruct, Tree, TreeMessage}; pub use tree::{InterfaceData, InterfaceStruct, Tree, TreeMessage};
+4 -1
View File
@@ -1,6 +1,9 @@
[package] [package]
name = "unshell-crypt" name = "unshell-crypt"
edition = "2024" version.workspace = true
edition.workspace = true
authors.workspace = true
include.workspace = true
[dependencies] [dependencies]
aes = "0.8.4" aes = "0.8.4"
+4 -1
View File
@@ -1,6 +1,9 @@
[package] [package]
name = "unshell-gui" name = "unshell-gui"
edition = "2024" version.workspace = true
edition.workspace = true
authors.workspace = true
include.workspace = true
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]
+4 -1
View File
@@ -1,6 +1,9 @@
[package] [package]
name = "unshell-manager" name = "unshell-manager"
edition = "2024" version.workspace = true
edition.workspace = true
authors.workspace = true
include.workspace = true
[features] [features]
log = ["unshell/log"] log = ["unshell/log"]
+4 -1
View File
@@ -1,6 +1,9 @@
[package] [package]
name = "unshell-obfuscate" name = "unshell-obfuscate"
edition = "2024" version.workspace = true
edition.workspace = true
authors.workspace = true
include.workspace = true
[features] [features]
obfuscate = [] obfuscate = []
+13 -14
View File
@@ -1,8 +1,18 @@
cargo-features = ["trim-paths"]
[package] [package]
name = "unshell-payload" name = "unshell-payload"
edition = "2024" edition = "2024"
# [features] # [lib]
# crate-type = ["cdylib"]
[features]
default = ["log"]
log = ["unshell/log", "server2/log"]
log_debug = ["unshell/log_debug", "server2/log_debug"]
# obfuscate = ["unshell-obfuscate/obfuscate"] # obfuscate = ["unshell-obfuscate/obfuscate"]
# log = ["unshell-lib/log"] # log = ["unshell-lib/log"]
# log_debug = ["unshell-lib/log_debug"] # log_debug = ["unshell-lib/log_debug"]
@@ -13,17 +23,6 @@ edition = "2024"
[dependencies] [dependencies]
# lazy_static = "1.5.0"
static_init = "1.0.4"
# unshell-lib = {path = "../unshell-lib", default-features = false} unshell.path = "../"
unshell-obfuscate = {path = "../unshell-obfuscate"} server2.path = "../core-modules/server2"
[profile.release]
# strip = true # Strip symbols from the binary
# opt-level = "z" # Optimize for size
# lto = true # Link tree optimization
# codegen-units = 1
# panic = "abort"
# debug = false # Remove debug
# trim-paths="all"
+69 -59
View File
@@ -1,76 +1,86 @@
use std::{any::Any, collections::HashMap, fs::File, io::Read}; use unshell::info;
use static_init::dynamic; // use std::dyn
use unshell_lib::{
ModuleError,
config::{PayloadConfig, RuntimeConfig},
module::{Manager, Module},
};
use unshell_obfuscate::{obs, symbol};
#[macro_use]
extern crate unshell_lib;
// The main and initial 'configuration' for a payload
#[dynamic]
static PAYLOAD_CONFIG: PayloadConfig = PayloadConfig {
id: symbol!("Test ID"),
components: Vec::new(),
runtime_config: vec![RuntimeConfig {
parent_component: symbol!("client").to_string(),
name: symbol!("client runtime").to_string(),
config: HashMap::from([
(symbol!("host").to_string(), obs!("localhost:1234")),
(symbol!("retry").to_string(), obs!("1000")),
]),
}],
};
fn main() { fn main() {
// Init the logger // Init the logger
#[cfg(not(feature = "obfuscate"))] // #[cfg(not(feature = "obfuscate"))]
unshell_lib::logger::PrettyLogger::init(); unshell::logger::PrettyLogger::init();
debug!("Initialized"); server2::log_test_fn();
// info!("This is a string!");
match run() {
Ok(_) => {}
Err(e) => {
error!("ERROR! '{:?}'", e);
}
}
} }
fn run() -> Result<(), Box<dyn std::error::Error>> { // use std::{any::Any, collections::HashMap, fs::File, io::Read};
let args = std::env::args();
// TEMPORARY, load the module paths from command line args. // use static_init::dynamic;
let mut modules = Vec::new(); // use unshell_lib::{
for arg in args.skip(1) { // ModuleError,
// debug!("Loading module: {}", arg); // config::{PayloadConfig, RuntimeConfig},
// module::{Manager, Module},
// };
// use unshell_obfuscate::{obs, symbol};
// let mut file = File::open(arg).map_err(|e| ModuleError::Error(e.to_string().into()))?; // #[macro_use]
// let mut buffer = Vec::new(); // extern crate unshell_lib;
// file.read_to_end(&mut buffer)
// .map_err(|e| ModuleError::Error(e.to_string().into()))?;
debug!("Initializing module: {}", arg); // // The main and initial 'configuration' for a payload
let module = Module::new(&arg)?;
modules.push(module); // #[dynamic]
// static PAYLOAD_CONFIG: PayloadConfig = PayloadConfig {
// id: symbol!("Test ID"),
// components: Vec::new(),
// runtime_config: vec![RuntimeConfig {
// parent_component: symbol!("client").to_string(),
// name: symbol!("client runtime").to_string(),
// config: HashMap::from([
// (symbol!("host").to_string(), obs!("localhost:1234")),
// (symbol!("retry").to_string(), obs!("1000")),
// ]),
// }],
// };
// modules.push(Module::new(&arg)?) // fn main() {
}
// let modules = vec // debug!("Initialized");
debug!("Starting manager..."); // match run() {
// Ok(_) => {}
// Err(e) => {
// error!("ERROR! '{:?}'", e);
// }
// }
// }
// Run the manager, this is blocking. // fn run() -> Result<(), Box<dyn std::error::Error>> {
let manager = Manager::start(&PAYLOAD_CONFIG, modules); // let args = std::env::args();
Manager::join(manager); // // TEMPORARY, load the module paths from command line args.
// let mut modules = Vec::new();
// for arg in args.skip(1) {
// // debug!("Loading module: {}", arg);
Ok(()) // // let mut file = File::open(arg).map_err(|e| ModuleError::Error(e.to_string().into()))?;
} // // let mut buffer = Vec::new();
// // file.read_to_end(&mut buffer)
// // .map_err(|e| ModuleError::Error(e.to_string().into()))?;
// debug!("Initializing module: {}", arg);
// let module = Module::new(&arg)?;
// modules.push(module);
// // modules.push(Module::new(&arg)?)
// }
// // let modules = vec
// debug!("Starting manager...");
// // Run the manager, this is blocking.
// let manager = Manager::start(&PAYLOAD_CONFIG, modules);
// Manager::join(manager);
// Ok(())
// }
+4 -1
View File
@@ -1,6 +1,9 @@
[package] [package]
name = "unshell-server" name = "unshell-server"
edition = "2024" version.workspace = true
edition.workspace = true
authors.workspace = true
include.workspace = true
[features] [features]
default = ["log_debug"] default = ["log_debug"]
-14
View File
@@ -1,14 +0,0 @@
use std::collections::HashMap;
use unshell::config::ConfigStructField;
// use crate::config::ConfigStructField;
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub struct Blob {
name: String,
parent_component: String,
// parent_runtime: String,
config: HashMap<String, ConfigStructField>,
}
-49
View File
@@ -1,49 +0,0 @@
use std::collections::HashMap;
use serde_json::Value;
use crate::config::ConfigStructField;
#[derive(Clone, serde::Deserialize, serde::Serialize)]
pub enum Interface {
Sub(HashMap<String, InterfaceWrapper>),
Struct {
fields: HashMap<String, ConfigStructField>,
value: HashMap<String, Value>,
},
}
#[derive(Clone, serde::Deserialize, serde::Serialize)]
pub struct InterfaceWrapper {
pub name: String,
pub interface: Interface,
}
impl InterfaceWrapper {
pub fn get_path(&self, elements: &Vec<&str>, depth: usize) -> Result<InterfaceWrapper, String> {
if depth == elements.len() {
return Ok(self.clone());
}
let element = elements[depth];
match &self.interface {
Interface::Sub(interface_wrappers) => {
if let Some(interface) = interface_wrappers.get(element) {
interface.get_path(elements, depth)
} else {
Err("Invalid Path".into())
}
}
_ => Err("Invalid Path".into()),
}
}
}
pub fn get_test_interface() -> InterfaceWrapper {
InterfaceWrapper {
name: "Root Interface".into(),
interface: Interface::Sub(HashMap::new()),
}
}
-91
View File
@@ -1,91 +0,0 @@
mod blob;
use std::{
collections::HashMap,
fs,
path::{Path, PathBuf},
};
use unshell::{ModuleError, Result, debug, info};
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
struct ComponentMetadata {
name: String,
description: Option<String>,
version: Option<String>,
authors: Option<Vec<String>>,
// Struct to contain build information
#[serde(default)]
build_config: BuildConfig,
// Other components that can be pointed to by this component
#[serde(default)]
child_components: Vec<PathBuf>,
}
#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)]
struct BuildConfig {
// Cargo feature list of a component
// (Name, Description)
#[serde(default)]
features: HashMap<String, String>,
}
#[derive(Clone, Debug)]
pub struct ComponentState {
metadata: ComponentMetadata,
path: PathBuf,
}
pub fn load_config(path: &PathBuf) -> Result<Vec<ComponentState>> {
let path_absolute =
fs::canonicalize(path.clone()).map_err(|e| ModuleError::Error(e.to_string()))?;
debug!("Loading data from path: `{:?}`", path_absolute);
// Read string as path
let config_str =
fs::read_to_string(path.clone()).map_err(|e| ModuleError::Error(e.to_string()))?;
// Load config from String
let config = toml::from_str::<ComponentMetadata>(&config_str)
.map_err(|e| ModuleError::Error(e.to_string()))?;
info!("Loaded component `{}`", config.name);
let parent_path = path_absolute.parent().expect("Path must have parent");
if config.child_components.is_empty() {
Ok(vec![ComponentState {
metadata: config,
path: PathBuf::from(parent_path),
}])
} else {
let mut config_vec = vec![];
// Load each child component
for component_path in &config.child_components {
let path = Path::join(parent_path, component_path);
let mut config = load_config(&path)?;
config_vec.append(&mut config);
}
config_vec.insert(
0,
ComponentState {
metadata: config,
path: PathBuf::from(parent_path),
},
);
Ok(config_vec)
}
}
// pub fn parse_toml() -> ComponentMetadata {
// let data = include_str!("../../test.toml");
// let config = toml::from_str(data).unwrap();
// config
// }
+1 -1
View File
@@ -1,6 +1,6 @@
mod api; mod api;
mod auth; mod auth;
mod config; // mod config;
pub mod logger; pub mod logger;
mod server; mod server;