Skip to content

Commit

Permalink
Upload
Browse files Browse the repository at this point in the history
  • Loading branch information
LeagueRaINi committed Feb 9, 2020
0 parents commit 2612dc3
Show file tree
Hide file tree
Showing 9 changed files with 952 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/mac.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: MacOS

on:
push:
paths:
- 'src/**'

jobs:
build:

runs-on: macos-latest

steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
18 changes: 18 additions & 0 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Ubuntu

on:
push:
paths:
- 'src/**'

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
18 changes: 18 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Windows

on:
push:
paths:
- 'src/**'

jobs:
build:

runs-on: windows-latest

steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Generated by Cargo
# will have compiled files and executables
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk
.vscode
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "aida64_keygen"
version = "0.1.0"
authors = ["RaINi_"]
edition = "2018"

[dependencies]
rand = "0.7.3"
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
![MacOS](https://github.com/LeagueRaINi/Aida64-Keygen/workflows/MacOS/badge.svg)
![Ubuntu](https://github.com/LeagueRaINi/Aida64-Keygen/workflows/Ubuntu/badge.svg)
![Windows](https://github.com/LeagueRaINi/Aida64-Keygen/workflows/Windows/badge.svg)

# **This is for educational purposes only!**
- this project contains methods for generating and verifying aida64 keys

![preview](https://github.com/LeagueRaINi/Aida64-Keygen/blob/master/resources/preview.png)

**Thanks to:**
- approved for helping reverse some of this
- wildbook & veykril for helping me alot converting this to rust
- moonshadow565 for explaining and simplifying some of the methods
Binary file added resources/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
192 changes: 192 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
use crate::KeyEdition::{Business, Extreme, Engineer, NetworkAudit};
use core::convert::TryFrom;
use std::string::String;
use rand::{thread_rng, Rng};

#[derive(Debug, Copy, Clone)]
struct Date {
day: i32,
month: i32,
year: i32
}

impl Date {
fn enc(&mut self) -> i32 {
self.year = self.year.max(2003).min(2099) - 2003;
self.month = self.month.max(2).min(12);
self.day = self.day.max(1).min(31);
(self.year * 512) + (self.month * 32) + self.day
}

fn dec(val: i32) -> Date {
Date {
day: val & 31,
month: (val >> 5) & 15,
year: ((val >> 9) & 31) + 2003
}
}
}

#[derive(Debug, Copy, Clone)]
enum KeyEdition {
Business = 0,
Extreme = 1,
Engineer = 2,
NetworkAudit = 3
}

impl TryFrom<i32> for KeyEdition {
type Error = &'static str;

fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Business),
1 => Ok(Extreme),
2 => Ok(Engineer),
3 => Ok(NetworkAudit),
_ => Err("Unknown edition"),
}
}
}

impl TryFrom<&str> for KeyEdition {
type Error = &'static str;

fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"business" => Ok(Business),
"extreme" => Ok(Extreme),
"engineer" => Ok(Engineer),
"network" => Ok(NetworkAudit),
_ => Err("Unknown edition"),
}
}
}

const KEYS_SIZE: i32 = KEY_CHARS.len() as i32;
const KEY_CHARS: [u8; 34] = [
b'D', b'Y', b'1', b'4', b'U', b'F', b'3', b'R', b'H',
b'W', b'C', b'X', b'L', b'Q', b'B', b'6', b'I', b'K',
b'J', b'T', b'9', b'N', b'5', b'A', b'G', b'S', b'2',
b'P', b'M', b'8', b'V', b'Z', b'7', b'E'
];

fn get_checksum<T: AsRef<[u8]>>(key_part: T) -> u16 {
(key_part
.as_ref()
.iter()
.fold(0u32, |result, b| {
(0..8).fold(result ^ (*b as u32) << 8, |result, _| {
if result & 0x8000 == 0 {
result << 1
} else {
result << 1 ^ 0x8201
}
})
}) & 0xFFFF) as u16
}

fn dec_part<T: AsRef<[u8]>>(key_part: T) -> i32 {
key_part
.as_ref()
.iter()
.enumerate()
.fold(0i32, |result, (_, c1)| {
(result * 34) + KEY_CHARS
.iter()
.position(|&c2| c2 == *c1)
.unwrap_or(0) as i32
})
}

fn enc_part(mut val: i32, slice: &mut [u8]) {
slice
.iter_mut()
.rev()
.for_each(|x| {
*x = KEY_CHARS[(val % KEYS_SIZE) as usize];
val /= KEYS_SIZE;
})
}

fn gen_pair(slice: &mut [u8]) {
slice
.iter_mut()
.for_each(|x| *x = KEY_CHARS[thread_rng().gen_range(0, KEYS_SIZE) as usize])
}

fn verify_checksum<T: AsRef<[u8]>>(key: T) -> bool {
let key = key.as_ref();
key.len() == 25 && {
let mut enc_checksum: [u8; 3] = [0; 3];
enc_part(get_checksum(&key[0..24]) as i32, &mut enc_checksum);
enc_checksum[1] == key[24]
}
}

fn is_valid_key<T: AsRef<[u8]>>(key: T) -> bool {
let key = key.as_ref();
verify_checksum(key) && {
let key_parts: [i32; 9] = [
dec_part(&key[22..24]),
dec_part(&key[0..2]),
dec_part(&key[2..4]),
dec_part(&key[4..6]),
dec_part(&key[6..8]),
dec_part(&key[8..12]),
dec_part(&key[12..16]),
dec_part(&key[16..19]),
dec_part(&key[19..22]),
];

let edition = KeyEdition::try_from(((key_parts[0] & 0xFF) ^ key_parts[1] ^ 0xBF) - 1);
let unk1 = (key_parts[0] & 0xFF) ^ key_parts[2] ^ 0xED;
let unk2 = (key_parts[0] & 0xFF) ^ (key_parts[3] & 0xFFFF) ^ 0x77;
let unk3 = (key_parts[0] & 0xFF) ^ (key_parts[4] & 0xFFFF) ^ 0xDF;
let license_count = key_parts[0] ^ key_parts[5] ^ 0x4755;
let purchase_date = key_parts[0] ^ key_parts[6] ^ 0x7CC1;
let expire_val1 = (key_parts[0] & 0xFF) ^ key_parts[7] ^ 0x3FD;
let expire_val2 = (key_parts[0] & 0xFF) ^ key_parts[7] ^ 0x935;

edition.is_ok() &&
unk1 < 990 && unk2 <= 100 && unk3 <= 100 &&
license_count > 0 && license_count < 798 &&
expire_val1 <= 3660 && expire_val2 > 0 && expire_val2 <= 3660 && (expire_val1 != 3660 || expire_val2 != 1830) &&
purchase_date >= 577 && purchase_date <= 49567
}
}

fn generate_key(edition: KeyEdition, license_count: i32, purchase_val: i32, expire1_val: i32, expire2_val: i32) -> String {
let mut rng = thread_rng();
let unk1 = rng.gen_range(100, 989);
let unk2 = rng.gen_range(0, 100) & 0xFFFF;
let unk3 = rng.gen_range(0, 100) & 0xFFFF;

let mut enc_key: [u8; 25] = [0; 25];
gen_pair(&mut enc_key[22..24]);

let base_val = dec_part(&mut enc_key[22..24]);
enc_part((base_val & 0xFF) ^ (edition as i32 + 1) ^ 0xBF, &mut enc_key[0..2]);
enc_part((base_val & 0xFF) ^ unk1 ^ 0xED, &mut enc_key[2..4]);
enc_part((base_val & 0xFF) ^ unk2 ^ 0x77, &mut enc_key[4..6]);
enc_part((base_val & 0xFF) ^ unk3 ^ 0xDF, &mut enc_key[6..8]);
enc_part((base_val & 0xFFFFFF) ^ license_count ^ 0x4755, &mut enc_key[8..12]);
enc_part((base_val & 0xFFFFFF) ^ purchase_val ^ 0x7CC1, &mut enc_key[12..16]);
enc_part((base_val & 0xFF) ^ expire1_val ^ 0x3FD, &mut enc_key[16..19]);
enc_part((base_val & 0xFF) ^ expire2_val ^ 0x935, &mut enc_key[19..22]);

let mut enc_checksum: [u8; 3] = [0; 3];
enc_part(get_checksum(&mut enc_key[0..24]) as i32, &mut enc_checksum);
enc_key[24] = enc_checksum[1];

String::from_utf8(enc_key.to_vec()).unwrap()
}

fn main() {
for i in 0..4 {
let edition = KeyEdition::try_from(i).unwrap();
let new_key = generate_key(edition, 1, Date {day: 1, month: 1, year: 2020}.enc(), 0, 3660);
println!(" generated key {} for edition {:?}", new_key, edition);
println!(" └ is valid: {}", is_valid_key(new_key));
}
}

0 comments on commit 2612dc3

Please sign in to comment.