diff --git a/README.md b/README.md index aed4863..98707e6 100644 --- a/README.md +++ b/README.md @@ -22,4 +22,8 @@ anyexec2c -e -x executable > source.c anyexec2c -b source.d > source.c # (D lang with DMD compiler) anyexec2c -b source.go > source.c # (Go) anyexec2c -b src/main.rs > source.c # (Rust using cargo - necessary to call from projects main dir) + +# we can also generate C# programs for cases when C/C++ is not an allowed language (using --target or -t switch) +# this packs our memory test tool into a C# environement +anyexec2c -b tools/memtest.c -t C# > memtest.cs ``` diff --git a/src/csharp_code.rs b/src/csharp_code.rs new file mode 100755 index 0000000..87cd25f --- /dev/null +++ b/src/csharp_code.rs @@ -0,0 +1,42 @@ +pub const PART1: &str = " +using System; +using System.IO; +using System.Runtime.InteropServices; + + +namespace mujprogram { + class Proram { + const string binaryName = \"myBinaryPayload\"; + + static void extract(string payload, string filename) { + int len = 0; + byte[] binary = Convert.FromBase64String(payload); + File.WriteAllBytes(filename, binary); + // does not hurt if everything has all permissions allowed + chmod(filename, 511); + } + + const string executable = \"%%EXECUTABLE%%\"; +"; +pub const MAIN: &str = " + public static int Main(string[] args) { + extract(executable, binaryName); + + %%ASSETS%% + + var args2 = new string[args.Length + 1]; + args2[0] = binaryName; + Array.Copy(args, 0, args2, 1, args.Length); + execv(binaryName, args2); + return 2; + } + + [DllImport(\"libc.so.6\")] + + public static extern int chmod(string message, int a); + + [DllImport(\"libc.so.6\")] + public static extern int execv(string binary, string[] args); + } +} +"; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index fdb5c07..a9de857 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,16 +8,25 @@ use std::path::Path; use std::env; mod c_code; +mod csharp_code; use c_code::*; +// use csharp_code; use argparse::{ArgumentParser, StoreTrue, List, StoreOption}; +enum OutputLanguage { + C, + CSharp +} + + struct CmdArgs { comment_files: Vec, build_file: Option, asset_files: Vec, exec_file: Option, enable_error_checks: bool, + target: OutputLanguage, } fn parse_args() -> CmdArgs { @@ -27,8 +36,10 @@ fn parse_args() -> CmdArgs { build_file: None, asset_files: Vec::new(), exec_file: None, + target: OutputLanguage::C }; + let mut target = "c".to_owned(); { let mut ap = ArgumentParser::new(); ap.set_description("Generate C source code with binary payload."); @@ -55,13 +66,28 @@ fn parse_args() -> CmdArgs { ap.refer(&mut args.exec_file).add_option( &["-x", "--exec"], StoreOption, - "Deliver and execute this file. Can't be used together with --build", + "Deliver anlis file. Can't be used together with --build", + ); + ap.refer(&mut target).add_option( + &["-t", "--target"], + argparse::Store, + "Output Language" ); ap.parse_args_or_exit(); + } + args.target = + match target.to_lowercase().as_str() { + "c" => OutputLanguage::C, + "csharp" | "c#" => OutputLanguage::CSharp, + _ => { + eprintln!("Unsupported target type '{}'.", target); + exit(1); + } + }; - // check if exec and build correctlly set + // check if exec and build correctly set if args.build_file.is_some() == args.exec_file.is_some() { if args.build_file.is_some() { println!("Can't have build and exec together."); @@ -129,13 +155,19 @@ fn main() { "go" => { compile(&format!("go build -o a.out {}", build_file), "a.out") } + "c" => { + compile(&format!("gcc -o a.out {} -O3 -Wall", build_file), "a.out") + } + "cpp" => { + compile(&format!("g++ -o a.out {} -O3 -std=c++17 -Wall", build_file), "a.out") + } "rs" => { let program_name = bash_command("cat Cargo.toml | grep \"name\" | sed 's/.*\"\\(.*\\)\"/\\1/'"); let pn = program_name.trim(); compile(&format!("cargo build -Z unstable-options --release --target x86_64-unknown-linux-musl --out-dir ."), pn) } - _ => { - eprintln!("File extension not recognized! Can't build!"); + extension => { + eprintln!("File extension '{}' not recognized! Can't build!", extension); exit(1); } }; @@ -147,14 +179,27 @@ fn main() { let mut executable = Vec::new(); f.read_to_end(&mut executable).unwrap(); - // insert libs and the main executable - print!("{}", str::replace(C_LIBS_AND_EXECUTABLE, "%%EXECUTABLE%%", &base64::encode(&executable))); + let part1 = + match args.target { + OutputLanguage::C => C_LIBS_AND_EXECUTABLE, + OutputLanguage::CSharp => + csharp_code::PART1 + }; - let main = if args.enable_error_checks { - C_MAIN_WITH_CHECKS - } else { - C_MAIN_SIMPLE - }; + // insert libs and the main executable + print!("{}", str::replace(part1, "%%EXECUTABLE%%", &base64::encode(&executable))); + + let main = + match args.target { + OutputLanguage::C => + if args.enable_error_checks { + C_MAIN_WITH_CHECKS + } else { + C_MAIN_SIMPLE + }, + OutputLanguage::CSharp => + csharp_code::MAIN + }; // insert main and assets