Skip to content

Releases: 876N/KeyGen

Download

08 May 13:37
6945161

Choose a tag to compare

Source Code Documentation

Technical reference for the KeyGen codebase.

image

Architecture Overview

The project is a Rust workspace with three crates:

crates/
├── shared/    Library — crypto, license format, config structures
├── keygen/    Binary — CLI tool for protection and key generation
└── stub/      Binary — the protected loader that runs on end-user machines

Crate: kg_shared

Shared library used by both keygen and stub. Zero external dependencies for crypto.

Modules

Module Purpose
aes.rs AES-256-CBC encrypt/decrypt with PKCS7 padding and random IV
hash.rs SHA-1, MD5, HMAC-SHA1 implementations
kdf.rs PBKDF2-HMAC-SHA1 key derivation (1000 rounds)
license.rs License encoding/decoding, validation, expiration checks
random.rs Secure random via BCryptGenRandom (Windows) or /dev/urandom (Unix)
config.rs ConfigData struct layout — binary config embedded in the stub

Key Functions

  • aes256_cbc_encrypt(plaintext, key) — Encrypts with random 16-byte IV prepended
  • aes256_cbc_decrypt(ciphertext, key) — Reads IV from first 16 bytes, decrypts
  • generate_license(hwid, enc_map, info) — Creates an HWID-bound license key string
  • validate_license(key, hwid, enc_map) — Validates and decodes a license key
  • crc32(data) — Standard CRC32 for integrity checking
  • wipe(buf) — Volatile zero-fill to prevent optimizer from removing the wipe

Crate: keygen

The CLI tool that developers use to protect executables and generate license keys.

Modules

Module Purpose
main.rs Menu loop, build logic, license generation
console.rs Color output, input handling, progress bar
charmap.rs Character map editor for license key alphabet
pe.rs PE header parsing, .NET detection, architecture detection
icon.rs Icon resource extraction from PE files
ui.rs UI component helpers

Build Flow

  1. User selects target executable
  2. pe.rs detects architecture (32/64-bit) and type (.NET / Native)
  3. Correct stub DLL is selected (S32/S64/N32/N64 + UAC variants)
  4. Encryption key → PBKDF2 → 32-byte AES key
  5. Target PE is encrypted with AES-256-CBC
  6. ConfigData is populated (tool name, encryption key, flags)
  7. Stub DLL is copied as .exe, config bytes are patched in
  8. Original icon is extracted and applied to the output
  9. Encrypted payload is appended as an overlay

Crate: stub

The protected loader that ships with the protected executable. Runs on end-user machines.

Modules

Module Purpose
main.rs Entry point — license UI or direct run
cfg.rs Reads ConfigData from the binary's embedded config region
console.rs Console I/O for the license prompt
hwid.rs Hardware ID generation (CPUID + volume serial)
payload.rs Extracts encrypted overlay from the running executable
runner.rs Dispatches to native or .NET loader based on PE type
dotnet_loader.rs .NET in-memory loader via bootstrap process + pipe
antidebug.rs Encryption key transforms when debugger is detected

Execution Flow

main()
  ├── No License mode → run_program() silently
  └── License mode → show UI → validate → run_program()

run_program()
  ├── load_payload()        → extract encrypted PE from overlay
  ├── get_payload_key()     → read AES key from config
  ├── antidebug transform   → corrupt key if debugger present
  ├── verify_self_integrity → corrupt key if binary was tampered
  ├── aes256_cbc_decrypt()  → decrypt the PE
  ├── verify MZ header      → confirm valid PE
  ├── crc32 integrity check → confirm no corruption
  ├── is_dotnet_assembly()  → detect PE type
  └── run_payload()
        ├── .NET → dotnet_loader::run_dotnet_inmemory()
        └── Native → native_impl::run_native_inproc()

.NET In-Memory Loading

The .NET loader avoids writing the decrypted assembly to disk:

  1. A platform-matched bootstrap EXE (bootstrap_x86.exe / bootstrap_x64.exe) is embedded via include_bytes!
  2. Bootstrap is written to app directory with Hidden+System attributes
  3. A pipe is created; the read end is inheritable
  4. Bootstrap is spawned via CreateProcessW with CREATE_NO_WINDOW
  5. Decrypted assembly bytes are sent through the pipe
  6. Bootstrap reads from pipe, patches AMSI, calls Assembly.Load(byte[])
  7. Bootstrap invokes the assembly's entry point
  8. Parent waits for child to exit, then deletes the bootstrap file

Native PE Loading

Native executables are handled with a simpler disk-drop approach:

  1. Decrypted PE is written to app directory with Hidden+System attributes
  2. Executed via CreateProcessW
  3. Parent waits for child to exit, then deletes the dropped file

Features (Cargo)

Feature Effect
dotnet Includes .NET bootstrap binaries via include_bytes!
uac Embeds UAC manifest requesting admin elevation

Config Structure

ConfigData is a fixed-size binary struct embedded in the stub executable. The keygen patches this region after copying the stub.

Field Size Purpose
marker 19 bytes Magic bytes for locating config in binary
flags 1 byte Bit flags (no_license, etc.)
tool_name 32 bytes Application name (null-terminated)
orig_ext 16 bytes Original file extension
payload_key 32 bytes AES-256 encryption key
enc_map 32 bytes License encoding character map
integrity 4 bytes CRC32 of the decrypted payload
self_hash 20 bytes SHA-1 of the stub for tamper detection

License Format

Licenses are encoded as Base32-like strings using a customizable character map.

Encoding process:

  1. HWID is hashed to produce a binding value
  2. License metadata (type, expiry, value) is packed into bytes
  3. Binding + metadata are XOR'd with the encryption map
  4. Result is Base32-encoded with the character map
  5. Checksum is appended

Validation reverses this process and verifies the HWID binding matches.


Build Targets

Target Arch Output
x86_64-pc-windows-msvc 64-bit S64, N64, KeyGen
i686-pc-windows-msvc 32-bit S32, N32

Each target can be built with --features uac and/or --features dotnet.


Tests

Run tests with:

cargo test -p kg_shared

Tests cover: AES roundtrip, SHA-1/MD5 known vectors, CRC32, PBKDF2 determinism, license roundtrip for all types, HWID mismatch rejection, wrong-key rejection, expiration logic.


Made By ABOLHB