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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#![forbid(anonymous_parameters)]
#![warn(clippy::pedantic)]
#![deny(
clippy::all,
variant_size_differences,
unused_results,
unused_qualifications,
unused_import_braces,
unsafe_code,
trivial_numeric_casts,
trivial_casts,
missing_docs,
unused_extern_crates,
missing_debug_implementations,
missing_copy_implementations,
rust_2018_idioms
)]
use std::{
collections::BTreeMap,
io::{self, Write},
thread::sleep,
time::{Duration, Instant},
};
use colored::Colorize;
use failure::{Error, ResultExt};
use log::{error, log_enabled, Level};
use super_analyzer_core::{
analyze_package, cli, initialize_config, initialize_logger, Benchmark, ErrorKind, BANNER,
};
fn main() {
if let Err(e) = run() {
error!("{}", e);
for e in e.iter_causes() {
println!("\t{}{}", "Caused by: ".bold(), e);
}
if !log_enabled!(Level::Debug) {
println!(
"If you need more information, try to run the program again with the {} flag.",
"-v".bold()
);
}
::std::process::exit(1);
}
}
fn run() -> Result<(), Error> {
let cli = cli::generate().get_matches();
let verbose = cli.is_present("verbose");
initialize_logger(verbose).context("could not initialize the logger")?;
let mut config = initialize_config(&cli)?;
if !config.check() {
let mut error_string = String::from("configuration errors were found:\n");
for error in config.errors() {
error_string.push_str(&error);
error_string.push('\n');
}
error_string.push_str(
"the configuration was loaded, in order, from the following files: \
\n\t- Default built-in configuration\n",
);
for file in config.loaded_config_files() {
error_string.push_str(&format!("\t- {}\n", file.display()));
}
return Err(ErrorKind::Config {
message: error_string,
}
.into());
}
if config.is_verbose() {
for c in BANNER.chars() {
print!("{}", c);
io::stdout().flush().expect("error flushing stdout");
sleep(Duration::from_millis(3));
}
println!(
"Welcome to the SUPER Android Analyzer. We will now try to audit the given application."
);
println!(
"You activated the verbose mode. {}",
"May Tux be with you!".bold()
);
println!();
sleep(Duration::from_millis(1250));
}
let mut benchmarks = BTreeMap::new();
let total_start = Instant::now();
for package in config.app_packages() {
config.reset_force();
analyze_package(package, &mut config, &mut benchmarks)
.context("application analysis failed")?;
}
if config.is_bench() {
let total_time = Benchmark::new("Total time", total_start.elapsed());
println!();
println!("{}", "Benchmarks:".bold());
for (package_name, benchmarks) in benchmarks {
println!("{}:", package_name.italic());
for bench in benchmarks {
println!("{}", bench);
}
println!();
}
println!("{}", total_time);
}
Ok(())
}