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
extern crate byteorder;
use std::num::Wrapping;
use byteorder::LittleEndian;
use byteorder::ByteOrder;
use byteorder::WriteBytesExt;
static STATIC_KEY: Wrapping<u64> = Wrapping(0x8FEB2A6740A6920E);
pub fn decrypt_table(ciphertext: &Vec<u8>, verbose: bool) -> Vec<u8> {
let mut plaintext = Vec::with_capacity(ciphertext.len());
let mut edi: u32 = 0;
let mut esi = 0;
let mut eax;
let mut edx;
for _ in 0..ciphertext.len()/8 {
let prod = (STATIC_KEY * Wrapping((!edi) as u64)).0;
if verbose {
println!("prod: {:X}", prod);
}
eax = prod as u32;
edx = (prod >> 32) as u32;
if verbose {
println!("eax: {:X}", eax);
println!("edx: {:X}", edx);
}
eax ^= LittleEndian::read_u32(&ciphertext[esi..esi + 4]);
if verbose {
println!("eax: {:X}", eax);
}
edi += 8;
let _edx = LittleEndian::read_u32(&ciphertext[esi + 4..esi + 8]);
if verbose {
println!("_edx {:X}", _edx);
}
edx ^= _edx;
if verbose {
println!("edx {:X}", edx);
}
plaintext.write_u32::<LittleEndian>(eax).unwrap();
if verbose {
println!("{:X}", edx);
}
plaintext.write_u32::<LittleEndian>(edx).unwrap();
esi += 8;
}
plaintext
}