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
extern crate proc_macro;
use TokenStream;
use quote;
use Rng;
use parse_macro_input;
/// Obfuscates a `str` at compile time.
///
/// Instead of a string literal being stored in your binary, it
/// is substituted for a `[u8; str_lit_size*2]` array literal of the original `str`.
/// The values are offset by a random value and recalculated on each call.
/// This means that it will won't show up when inspecting the binary
/// outright or through a debugger or hexeditor. The offset is stored
/// alongside the actual data, so any string literal will be guaranteed
/// to be double in size, and therefore take up twice as much memory.
///
/// This is especially useful if you're trying to protect the
/// more sensetive parts of your program to basic reverse engineering
/// techniques like string reference lookup.
///
/// # Intended Usage
/// Though it doesn't make it absolutely impossible, this macro
/// tries to make it **a lot** harder to look for string references
/// that would be physically near some sensetive functions that handle sensetive
/// things, like decrypting file indexies or handling security checks to name a few.
///
/// <br>
///
/// # Example
/// ```
/// use obfustring::obfustring;
///
/// let obfuscated_string = obfustring!("Hello obfustring!"); // <-- Won't show up in binaries or hex editors
/// let generic_string = String::from("Hello regular string!"); // <-- Will show up in binaries or hex editors
///
/// println!("obfuscated_string: {}", obfuscated_string);
/// println!("generic_string: {}", generic_string);
/// ```
///
/// <br>
///
/// # Expansion
/// `obfustring!("Hello obfustring!");` will expand into something like:
/// ```
/// || -> String {
/// let sec_slice = [
/// 151u8, 79u8, 149u8, 48u8, 168u8, 60u8, 139u8, 31u8, 163u8, 52u8, 63u8, 31u8, 153u8,
/// 42u8, 118u8, 20u8, 160u8, 58u8, 176u8, 59u8, 135u8, 20u8, 195u8, 79u8, 174u8, 60u8,
/// 181u8, 76u8, 179u8, 69u8, 119u8, 16u8, 103u8, 70u8,
/// ];
/// let mut str_vec: Vec<u8> = Vec::default();
/// let mut skip = false;
/// for (idx, val) in sec_slice.iter().enumerate() {
/// if skip {
/// skip = !skip;
/// continue;
/// }
/// str_vec.push(val - sec_slice[idx + 1]);
/// skip = !skip;
/// }
/// String::from_utf8_lossy(&str_vec).to_string()
/// }()
/// ```
///
/// <br>
///
/// # Disclaimer
/// Note that you should **never** have any encryption keys or
/// sensetive data hardcoded into your program. Though this macro
/// would make it harder, it wouldn't absolutely hide it from
/// someone looking hard enough.
///