commit adeee9fd3dc23099da70b9997cbbac3cb09a7a75 Author: Alexey Zinchenko Date: Thu Jul 22 17:09:15 2021 +0300 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89c0fff --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +.idea +*.iml diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..117eba1 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,185 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "crackme-homework-generator" +version = "0.1.0" +dependencies = [ + "clap", + "rand", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..03ece17 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "crackme-homework-generator" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = "2.33.3" +rand = "0.8.4" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..78cc20c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,218 @@ +use rand::Rng; + +const CHARSET: &[u8] = b"0123456789"; + +trait Generator { + fn generate() -> String; +} + +struct DumpGenerator; + +impl Generator for DumpGenerator { + fn generate() -> String { + let mut rng = rand::thread_rng(); + loop { + let mut key: String = (0..16).map(|_| { + let idx = rng.gen_range(0..CHARSET.len()); + CHARSET[idx] as char + }).collect(); + key.insert(4, '-'); + key.insert(9, '-'); + key.insert(14, '-'); + + if is_valid_wrapper(&key) { + return key; + } + } + } +} + +pub fn generate_number() -> String { + DumpGenerator::generate() +} + +pub fn is_valid_wrapper(string: &str) -> bool { + return fun_140001000(string, string.len() as u8) != 0 +} + +// param_1 - string to check +// param_2 - number of chars +fn fun_140001000(param_1: &str, param_2: u8) -> u8 { + // if length is not 19 + if param_2 != 0x13 { + return 0; + } + + // check for hyphens every 5 symbols + for i in (4..param_2).step_by(5) { + if param_1.chars().nth(i as usize).unwrap() != '-' { + return 0; + } + } + + let mut sections = [['0'; 4]; 4]; + let mut section_number = 0; + let mut section_position = 0; + // converting input string into vector of sections + for symbol in param_1.chars() { + if symbol == '-' { + continue; + } + sections[section_number][section_position] = symbol; + if section_position == 3 { + section_number += 1; + section_position = 0; + } else { + section_position += 1; + } + } + + let mut sections_sum = [0; 4]; + let mut total_sum = 0; + + // check that every symbol in sections is a digit + for (index, section) in sections.iter().enumerate() { + let mut current_section_sum = 0; + for section_symbol in section { + if !section_symbol.is_numeric() { + return 0; + } + current_section_sum += *section_symbol as i32 - 0x30; + } + + // also calculating sums per section and total sum + total_sum += current_section_sum; + sections_sum[index] = current_section_sum; + } + + // check that sum for every section equals to "total sum >> 2" + for section_sum in sections_sum { + if section_sum != total_sum >> 2 { + return 0; + } + } + + // check that there is no the same symbol in neighbor sections + for i in 0..4 { + if (sections[0][i] != sections[1][i] && (sections[1][i] != sections[2][i])) && + (sections[2][i] != sections[3][i]) { + continue; + } else { + return 0; + } + } + + // serial number is valid + return 1; +} + +/* + +undefined8 FUN_140001000(char *param_1,int param_2) + +{ + int iVar1; + char *pcVar2; + uint *puVar3; + ulonglong uVar4; + uint uVar5; + ulonglong uVar7; + uint uVar8; + uint *puVar9; + char *pcVar10; + uint uVar11; + uint uVar12; + uint local_18 [4]; + ulonglong uVar6; + + puVar9 = local_18; + puVar3 = local_18; + if (param_2 != 0x13) { + return 0; + } + uVar8 = 0; + uVar4 = 0; + pcVar2 = param_1 + 4; + uVar6 = uVar4; + do { + if (*pcVar2 != '-') { + return 0; + } + uVar5 = (int)uVar6 + 1; + uVar6 = (ulonglong)uVar5; + pcVar2 = pcVar2 + 5; + uVar7 = uVar4; + uVar12 = uVar8; + uVar11 = uVar8; + pcVar10 = param_1; + } while (uVar5 < 3); + do { + do { + if (9 < (int)pcVar10[uVar7] - 0x30U) { + return 0; + } + uVar7 = uVar7 + 1; + } while ((longlong)uVar7 < 4); + uVar12 = uVar12 + 1; + iVar1 = (int)pcVar10[3] + (int)pcVar10[2] + (int)pcVar10[1] + -0xc0 + (int)*pcVar10; + *puVar9 = iVar1; + uVar11 = uVar11 + iVar1; + uVar7 = uVar4; + pcVar10 = pcVar10 + 5; + puVar9 = (uint *)((int *)puVar9 + 1); + } while (uVar12 < 4); + do { + if (*puVar3 != uVar11 >> 2) { + return 0; + } + uVar8 = uVar8 + 1; + puVar3 = puVar3 + 1; + uVar6 = uVar4; + } while (uVar8 < 4); + while (((param_1[uVar4] != param_1[uVar4 + 5] && (param_1[uVar4 + 5] != param_1[uVar4 + 10])) && + (param_1[uVar4 + 10] != param_1[uVar4 + 0xf]))) { + uVar8 = (int)uVar6 + 1; + uVar4 = uVar4 + 1; + uVar6 = (ulonglong)uVar8; + if (3 < uVar8) { + return 1; + } + } + return 0; +} + + +undefined8 FUN_140001110(HWND param_1,int param_2,short param_3,HINSTANCE param_4) + +{ + UINT UVar1; + undefined8 uVar2; + HICON lParam; + CHAR local_58 [80]; + + if (param_2 == 0x10) { + EndDialog(param_1,0); + return 1; + } + if (param_2 != 0x110) { + if ((param_2 == 0x111) && (param_3 == 0x3e9)) { + UVar1 = GetDlgItemTextA(param_1,0x3ea,local_58,0x40); + uVar2 = FUN_140001000(local_58,UVar1); + if ((int)uVar2 != 0) { + MessageBoxA(param_1,"Good work, Serial is valid !!!","Well done...",0x40); + return 1; + } + MessageBoxA(param_1,"Fail, Serial is invalid !!!","Try again...",0x10); + return 1; + } + return 0; + } + lParam = LoadIconA(param_4,(LPCSTR)0x65); + SendMessageA(param_1,0x80,1,(LPARAM)lParam); + SendMessageA(param_1,0x80,0,(LPARAM)lParam); + SendMessageA(param_1,0xc,0,(LPARAM)"CrackMe #01"); + return 1; +} + + */ + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..1d6e792 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,32 @@ +use crackme_homework_generator::{is_valid_wrapper, generate_number}; + +extern crate clap; +use clap::{Arg, App}; +use std::str::FromStr; + + +fn main() { + let matches = App::new("Crackme-homework serial number generator") + .version("1.0") + .arg(Arg::with_name("keys_number") + .short("n") + .value_name("NUMBER") + .help("Sets a number of keys to generate for output") + .required(true) + .takes_value(true)) + .get_matches(); + + match u8::from_str(matches.value_of("keys_number").unwrap()) { + Ok(number) => { + for _ in 0..number { + let generated_serial = generate_number(); + if is_valid_wrapper(&generated_serial) { + println!("{}", generated_serial); + } else { + panic!("Generated key is not valid. Please, contact the programmer.") + } + } + } + Err(_) => {} + } +}