1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
pub mod argparser;
mod bytetools;
mod configuration;
mod fileio;
mod stegimage;
use std::fs::metadata;
use std::ops::Add;
use error_chain::{error_chain, bail};
use pyo3::prelude::*;
use pyo3::{wrap_pyfunction, PyErr, exceptions};
use crate::configuration::Configuration;
use crate::fileio::{FileContent, ContentReader, FileWriter};
use crate::stegimage::ContainerImage;
error_chain!{}
pub fn _run(config: &Configuration) -> Result<()> {
if config.extract {
extract_from_image(&config.hidden_file, &config.host_file)
} else {
hide_into_image(&config.hidden_file, &config.host_file)
}
}
pub fn _create_configuration(hidden_file: &str, host_file: &str, extract: bool) -> Configuration {
Configuration::new(hidden_file, host_file, extract)
}
pub fn extract_from_image(hidden_file: &str, host_file: &str)-> Result<()> {
let mut host_image = ContainerImage::new(host_file)?;
host_image.setup_hidden_data_extraction();
let mut extracted_file = FileWriter::new(hidden_file)
.chain_err(||"Error creating destination file to store extracted data")?;
for chunk in host_image {
extracted_file.write(&chunk)?;
}
Ok(())
}
#[pyfunction]
fn unhide_from_image(hidden_file: &str, host_file: &str)-> PyResult<()> {
match extract_from_image(hidden_file, host_file) {
Ok(())=> Ok(()),
Err(ref errors)=> {
let mut message = String::new();
for (index, error) in errors.iter().enumerate() {
message = message.add(format!("\t {} --> {}", index, error).as_str());
}
Err(PyErr::new::<exceptions::IOError, _>(message))
},
}
}
pub fn hide_into_image(file_to_hide: &str, host_file: &str)-> Result<()> {
let file_to_hide_content = FileContent::new(file_to_hide)
.chain_err(||"Error creating file to hide content handle.")?;
let file_to_hide_size = metadata(file_to_hide)
.chain_err(||"Error accessing file to hide metadata.")?
.len();
if file_to_hide_size > std::u32::MAX as u64 {
bail!("File to hide is too big. Maximum size is {}", std::u32::MAX);
} else {
let mut host_image = ContainerImage::new(host_file)?;
let chunk_size = host_image.setup_hiding(file_to_hide_size as u32);
let file_to_hide_reader = ContentReader::new(&file_to_hide_content, chunk_size);
for chunk in file_to_hide_reader {
host_image.hide_data(&chunk);
}
}
Ok(())
}
#[pyfunction]
fn hide_inside_image(file_to_hide: &str, host_file: &str)-> PyResult<()> {
match hide_into_image(file_to_hide, host_file) {
Ok(())=> Ok(()),
Err(ref errors)=> {
let mut message = String::new();
for (index, error) in errors.iter().enumerate() {
message = message.add(format!("\t {} --> {}", index, error).as_str());
}
Err(PyErr::new::<exceptions::IOError, _>(message))
},
}
}
#[pymodule]
fn steganer(_py: Python, m: &PyModule)-> PyResult<()>{
m.add_wrapped(wrap_pyfunction!(unhide_from_image))?;
m.add_wrapped(wrap_pyfunction!(hide_inside_image))?;
Ok(())
}