Skip to content

Commit be9f500

Browse files
authored
decryption utilities
1 parent f26733a commit be9f500

1 file changed

Lines changed: 352 additions & 0 deletions

File tree

‎src-tauri/src/secret/decrypt.rs‎

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
use sha2::{Sha256, Digest};
2+
3+
pub fn decrypt_all_layers(data: &[u8], keys: &[[u8; 32]]) -> Vec<u8> {
4+
assert!(keys.len() >= 20, "Need at least 20 keys");
5+
6+
let mut buf = data.to_vec();
7+
8+
buf = layer_20_integrity_check(&buf);
9+
buf = layer_19_timing_check(&buf);
10+
buf = layer_18_unmangle(&buf);
11+
buf = layer_17_unstring_encrypt(&buf);
12+
buf = layer_16_defingerprint(&buf);
13+
buf = layer_15_deconstruct_key(&buf, &keys[14]);
14+
buf = layer_14_remove_fake(&buf);
15+
buf = layer_13_deobfuscate_flow(&buf);
16+
buf = layer_12_unpolymorphic(&buf, &keys[11]);
17+
buf = layer_11_remove_padding(&buf);
18+
buf = layer_10_remove_dead_code(&buf);
19+
buf = layer_09_remove_antidebug(&buf);
20+
buf = layer_08_depolymorph(&buf, &keys[7]);
21+
buf = layer_07_verify_chain(&buf, &keys[6]);
22+
buf = layer_06_xor_decrypt(&buf, &keys[5]);
23+
buf = layer_05_aes_decrypt(&buf, &keys[4]);
24+
buf = layer_04_untranspose(&buf);
25+
buf = layer_03_xor_decrypt(&buf, &keys[2]);
26+
buf = layer_02_aes_decrypt(&buf, &keys[1]);
27+
buf = layer_01_xor_decrypt(&buf, &keys[0]);
28+
29+
buf
30+
}
31+
32+
fn layer_01_xor_decrypt(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
33+
let mask = derive_layer_mask(key, 0x01);
34+
data.iter()
35+
.enumerate()
36+
.map(|(i, &b)| b ^ mask[i % mask.len()])
37+
.collect()
38+
}
39+
40+
fn layer_02_aes_decrypt(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
41+
use aes_gcm::{Aes256Gcm, KeyInit, Nonce};
42+
use aes_gcm::aead::Aead;
43+
44+
if data.len() < 28 {
45+
return data.to_vec();
46+
}
47+
48+
let nonce_bytes = &data[..12];
49+
let ciphertext = &data[12..];
50+
let nonce = Nonce::from_slice(nonce_bytes);
51+
52+
match Aes256Gcm::new_from_slice(key) {
53+
Ok(cipher) => {
54+
match cipher.decrypt(nonce, ciphertext) {
55+
Ok(plaintext) => plaintext,
56+
Err(_) => data.to_vec(),
57+
}
58+
}
59+
Err(_) => data.to_vec(),
60+
}
61+
}
62+
63+
fn layer_03_xor_decrypt(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
64+
let mask = derive_layer_mask(key, 0x03);
65+
data.iter()
66+
.enumerate()
67+
.map(|(i, &b)| {
68+
let shift = (i % 8) as u32;
69+
b.wrapping_shr(shift) | b.wrapping_shl(8 - shift)
70+
})
71+
.zip(mask.iter().cycle())
72+
.map(|(b, &m)| b ^ m)
73+
.collect()
74+
}
75+
76+
fn layer_04_untranspose(data: &[u8]) -> Vec<u8> {
77+
if data.len() < 4 {
78+
return data.to_vec();
79+
}
80+
81+
let block_size = 4;
82+
let mut result = Vec::with_capacity(data.len());
83+
84+
for chunk in data.chunks(block_size) {
85+
let mut block = [0u8; 4];
86+
for (i, &b) in chunk.iter().enumerate() {
87+
if i < 4 {
88+
block[3 - i] = b;
89+
}
90+
}
91+
result.extend_from_slice(&block[..chunk.len()]);
92+
}
93+
94+
result
95+
}
96+
97+
fn layer_05_aes_decrypt(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
98+
use aes_gcm::{Aes256Gcm, KeyInit, Nonce};
99+
use aes_gcm::aead::Aead;
100+
101+
if data.len() < 28 {
102+
return data.to_vec();
103+
}
104+
105+
let nonce_bytes = &data[data.len() - 12..];
106+
let ciphertext = &data[..data.len() - 12];
107+
let nonce = Nonce::from_slice(nonce_bytes);
108+
109+
match Aes256Gcm::new_from_slice(key) {
110+
Ok(cipher) => {
111+
match cipher.decrypt(nonce, ciphertext) {
112+
Ok(plaintext) => plaintext,
113+
Err(_) => data.to_vec(),
114+
}
115+
}
116+
Err(_) => data.to_vec(),
117+
}
118+
}
119+
120+
fn layer_06_xor_decrypt(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
121+
let mut result = Vec::with_capacity(data.len());
122+
let mut prev = key[0];
123+
124+
for &b in data {
125+
let decrypted = b ^ prev ^ key[result.len() % 32];
126+
result.push(decrypted);
127+
prev = b;
128+
}
129+
130+
result
131+
}
132+
133+
fn layer_07_verify_chain(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
134+
if data.len() < 32 {
135+
return data.to_vec();
136+
}
137+
138+
let (payload, hash_bytes) = data.split_at(data.len() - 32);
139+
let mut hasher = Sha256::new();
140+
hasher.update(payload);
141+
hasher.update(key);
142+
let computed = hasher.finalize();
143+
144+
if computed.as_slice() == hash_bytes {
145+
payload.to_vec()
146+
} else {
147+
data.to_vec()
148+
}
149+
}
150+
151+
fn layer_08_depolymorph(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
152+
let seed = key.iter().fold(0u32, |acc, &b| acc.wrapping_add(b as u32));
153+
let mut result = data.to_vec();
154+
155+
let mut rng_state = seed;
156+
for i in (1..result.len()).rev() {
157+
rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345);
158+
let j = (rng_state as usize) % (i + 1);
159+
result.swap(i, j);
160+
}
161+
162+
result
163+
}
164+
165+
fn layer_09_remove_antidebug(data: &[u8]) -> Vec<u8> {
166+
let marker = b"DEBUG_MARKER_1234567890ABCDEF";
167+
if let Some(pos) = data.windows(marker.len()).position(|w| w == marker) {
168+
let mut result = data[..pos].to_vec();
169+
result.extend_from_slice(&data[pos + marker.len()..]);
170+
result
171+
} else {
172+
data.to_vec()
173+
}
174+
}
175+
176+
fn layer_10_remove_dead_code(data: &[u8]) -> Vec<u8> {
177+
let dead_pattern: &[u8] = &[0xDE, 0xAD, 0xCA, 0xFE, 0xBA, 0xBE];
178+
let mut result = Vec::new();
179+
let mut i = 0;
180+
181+
while i < data.len() {
182+
if i + dead_pattern.len() <= data.len() && &data[i..i + dead_pattern.len()] == dead_pattern {
183+
let skip_len = 32.min(data.len() - i);
184+
i += skip_len;
185+
} else {
186+
result.push(data[i]);
187+
i += 1;
188+
}
189+
}
190+
191+
result
192+
}
193+
194+
fn layer_11_remove_padding(data: &[u8]) -> Vec<u8> {
195+
if data.len() < 16 {
196+
return data.to_vec();
197+
}
198+
199+
let last_byte = *data.last().unwrap();
200+
if last_byte > 0 && last_byte <= 16 && (data.len() as u8) >= last_byte {
201+
let trim_len = data.len() - last_byte as usize;
202+
let potential_pad = &data[trim_len..];
203+
if potential_pad.iter().all(|&b| b == last_byte) {
204+
return data[..trim_len].to_vec();
205+
}
206+
}
207+
208+
data.to_vec()
209+
}
210+
211+
fn layer_12_unpolymorphic(data: &[u8], key: &[u8; 32]) -> Vec<u8> {
212+
data.iter()
213+
.enumerate()
214+
.map(|(i, &b)| {
215+
let key_byte = key[i % 32];
216+
let shift = key_byte % 8;
217+
b.wrapping_shl(shift as u32) | b.wrapping_shr((8 - shift) as u32)
218+
})
219+
.collect()
220+
}
221+
222+
fn layer_13_deobfuscate_flow(data: &[u8]) -> Vec<u8> {
223+
let mut result = data.to_vec();
224+
let mut i = 0;
225+
while i + 1 < result.len() {
226+
result.swap(i, i + 1);
227+
i += 2;
228+
}
229+
result
230+
}
231+
232+
fn layer_14_remove_fake(data: &[u8]) -> Vec<u8> {
233+
if data.len() < 32 {
234+
return data.to_vec();
235+
}
236+
237+
let checksum: u32 = data.iter().map(|&b| b as u32).sum();
238+
if checksum % 7 == 0 {
239+
data[..data.len().saturating_sub(32)].to_vec()
240+
} else {
241+
data.to_vec()
242+
}
243+
}
244+
245+
fn layer_15_deconstruct_key(data: &[u8], _key: &[u8; 32]) -> Vec<u8> {
246+
let magic = b"secret_key_construction_data_bloc";
247+
if data.len() >= magic.len() {
248+
let prefix = &data[..magic.len()];
249+
if prefix.iter().zip(magic.iter()).all(|(a, b)| a == b) {
250+
return data[magic.len()..].to_vec();
251+
}
252+
}
253+
data.to_vec()
254+
}
255+
256+
fn layer_16_defingerprint(data: &[u8]) -> Vec<u8> {
257+
data.iter()
258+
.enumerate()
259+
.map(|(i, &b)| b.wrapping_sub((i % 16) as u8))
260+
.collect()
261+
}
262+
263+
fn layer_17_unstring_encrypt(data: &[u8]) -> Vec<u8> {
264+
data.iter()
265+
.enumerate()
266+
.map(|(i, &b)| {
267+
match i % 4 {
268+
0 => b ^ 0x55,
269+
1 => b ^ 0xAA,
270+
2 => b ^ 0x33,
271+
_ => b ^ 0xCC,
272+
}
273+
})
274+
.collect()
275+
}
276+
277+
fn layer_18_unmangle(data: &[u8]) -> Vec<u8> {
278+
if data.len() < 2 {
279+
return data.to_vec();
280+
}
281+
282+
let mut result = Vec::with_capacity(data.len());
283+
let chunks: Vec<&[u8]> = data.chunks(2).collect();
284+
285+
for chunk in chunks.iter().rev() {
286+
result.extend_from_slice(chunk);
287+
}
288+
289+
result
290+
}
291+
292+
fn layer_19_timing_check(data: &[u8]) -> Vec<u8> {
293+
if data.len() < 8 {
294+
return data.to_vec();
295+
}
296+
297+
let verify = &data[data.len() - 8..];
298+
let payload = &data[..data.len() - 8];
299+
300+
let expected: Vec<u8> = verify.iter().enumerate().map(|(i, &b)| b.wrapping_add(i as u8)).collect();
301+
let actual: Vec<u8> = payload.iter().take(8).copied().collect();
302+
303+
if expected == actual {
304+
payload.to_vec()
305+
} else {
306+
data.to_vec()
307+
}
308+
}
309+
310+
fn layer_20_integrity_check(data: &[u8]) -> Vec<u8> {
311+
if data.len() < 64 {
312+
return data.to_vec();
313+
}
314+
315+
let payload = &data[..data.len() - 32];
316+
let stored_hash = &data[data.len() - 32..];
317+
318+
let mut hasher = Sha256::new();
319+
hasher.update(payload);
320+
let computed = hasher.finalize();
321+
322+
if computed.as_slice() == stored_hash {
323+
payload.to_vec()
324+
} else {
325+
data.to_vec()
326+
}
327+
}
328+
329+
pub fn derive_layer_mask(key: &[u8; 32], layer_id: u8) -> Vec<u8> {
330+
let mut hasher = Sha256::new();
331+
hasher.update(key);
332+
hasher.update([layer_id]);
333+
let hash = hasher.finalize();
334+
335+
let mut mask = Vec::with_capacity(32);
336+
for i in 0..32 {
337+
mask.push(hash[i ^ (layer_id as usize % 32)]);
338+
}
339+
mask
340+
}
341+
342+
pub fn hash_key(user_key: &str, index: usize) -> [u8; 32] {
343+
let mut hasher = Sha256::new();
344+
hasher.update(user_key.as_bytes());
345+
hasher.update(&(index as u64).to_le_bytes());
346+
hasher.update(b"LidBridge_Salt_v1");
347+
let hash = hasher.finalize();
348+
349+
let mut key = [0u8; 32];
350+
key.copy_from_slice(&hash);
351+
key
352+
}

0 commit comments

Comments
 (0)