SuperAPI AI Directory

re-keygen

General & other

View repository

Updated 10-15 21:34

About this skill

Keygen algorithm reconstruction (keygen)

When to use / when not to use

  • Boundaries (inherited from [[re-cracking]]): limited to own software / authorized testing / CTF·research environments; unauthorized software unlocking and commercial software bypass are prohibited; keygen outputs must not be spread or distributed
  • Use: the verification algorithm has already been obtained from [[re-license]], and the algorithm is reversible (comparison / transformation / table lookup can be reversed into generation steps)
  • Use: need to generate valid serial numbers for arbitrary input (username / machine code) (distribution, testing, verification scenarios)
  • Use: a distribution scheme that does not modify the target file (cleaner than [[re-patching]], does not trigger self-check / signature issues)
  • Do not use: the check point / verification algorithm has not yet been located (do [[re-license]] first)
  • Do not use: the algorithm contains irreversible parts (hash / asymmetric signature verification) — forward generation is impossible, switch to [[re-patching]] (see pitfall 1)
  • Do not use: the serial number is a random value generated and issued by the server (the generation logic is on the server side, and locally there is only verification)
  • Do not use: the program also has server-side secondary verification of the serial number (even if the generation logic is reversible, it is useless; first confirm the full list of check points)
  • Note: the generated serial number must be verified inside a sandbox ([[re-sandbox]], [[re-analyze/platform-tips]] highest principle); verify against a legitimate serial number (see pitfall 4)

Tool preparation

Decompilation output (raw material for algorithm reconstruction)

  • [[re-ghidra]] / [[re-ida]] / [[re-radare2]] decompiled pseudocode of the verification function (from [[re-license]] step 3); export function-level pseudocode and the comparison chain (pdf @ sym.check_license , etc.), as a reference for line-by-line translation (see pitfall 4)
  • Verification: the decompiled view can fully display the comparison / transformation statements of the verification function

python3 (keygen implementation)

  • Linux: apt install python3(most come with it); macOS: brew install python;Windows: choco install python / official installer
  • Verification: python3 --version
  • the python standard library is sufficient (argparse/struct/hashlib/re); for bit-width operations pay attention to masks (& 0xFFFFFFFF simulates 32-bit unsigned overflow)

z3-solver (optional, constraint solving)

  • pip install z3-solver
  • Verification: python3 -c "import z3; print(z3.get_version_string())"
  • Applicable: the verification is a "comparison chain / mathematical relation" (e.g. the serial number satisfies multiple equations); when direct reverse derivation is cumbersome, model and solve it (for modeling ideas see [[re-z3]])
  • Note: z3 only models the reversible parts; pure hash / signature parts have no solution (see pitfall 1)

Debugger (optional, intermediate value comparison)

  • [[re-x64dbg]] (Windows) / [[re-gdb]] (Linux / Wine) / [[re-lldb]] (macOS) — break at the comparison instruction to see the program's internal intermediate values, and compare them one by one with the script's intermediate values (the method in pitfall 4)

Operation steps

Execute in order, recording the result of each step (algorithm pseudocode / generation script / verification result; for evidence paths see [[re-triage]]).Input/output list first: input (username / machine code / fixed constants), output (serial number format), comparison method (digit-by-digit equality / check digit).

  1. The verification algorithm obtained from [[re-license]]:

    • Take the algorithm pseudocode from the check point list: input source (read registry / user input / machine code), transformation steps (each arithmetic / XOR / table lookup), final comparison method (strcmp / check digit / signature verification)
    • List each constraint that "a valid serial number must satisfy" (format length, character set, check digit, relationship to input) and write them into the algorithm document
  2. Serial number format analysis (before the algorithm):

    • Length / character set (digits / uppercase / mixed) / separators (XXXX-XXXX-XXXX) / case sensitivity / check digit position (trailing / fixed position)
    • Example:ABCD-1234-EFGH-5678 may be 4 groups × 4 characters + check group—the format constraints determine the generator's output framework; generate candidates according to the format first and then fill in the algorithm result, which is less error-prone than doing the algorithm first and then applying the format
    • Format and algorithm are coupled: whether separators participate in verification (two common types: compare digits only / compare the full string) must be confirmed; whether they participate changes the generator's segmentation logic
  3. Algorithm classification and reversibility determination:

    • Equality comparison type(serial == f(name)): directly serial = f(name)—just reverse the comparison direction
    • Transform type(arithmetic / XOR / shift): XOR is symmetric and directly invertible; modular arithmetic uses the modular inverse (pow(a, -1, m), requires gcd(a,m)=1); LCG back-derivation (state = a^{-1}(state' - c) mod m)
    • Lookup table type: invert the mapping table (input→output becomes output→input); when the table is not bijective, list all candidates
    • Check digit type(Luhn / CRC16/32 / mod 97 / mod 11): compute the data bits first and then append the check digit; CRC is a GF(2) linear operation and can be reverse-solved for the suffix bytes that "make the CRC equal the target value"
    • Encryption/decryption type(XOR / base64 / custom symmetric transform): using the decryptor in reverse makes the generator (the idea of [[re-crypto-id]] / [[re-crypto-decrypt]])
    • One-way type(hash / RSA / ECC signature verification): irreversible—report this part truthfully and switch to [[re-patching]] (see pitfall 1)
    • Write each type's conclusion into the algorithm document: type determination + basis for back-derivation (which step is reversible, which step is irreversible)
    • Mixed types are common: transform + check digit stacking (data bits undergo a transform, then the whole is given a check)—back-derive layer by layer as "transform layer → check layer", verifying each layer separately
  4. Back-derive the generation algorithm (forward derivation / constraint solving):

    • Forward derivation: reverse the verification direction—change the comparison expression into a generation expression (if (x == f(name)) ok → serial = f(name)); XOR is symmetric and can be directly reversed; for lookup tables, derive the inverse mapping table; modular arithmetic uses the modular inverse (pow(a, -1, m))
    • Constraint solving: model comparison chains / mathematical relations with z3, and after symbolic variables + constraints (length / character set / bit width), solve for any valid input:
      from z3 import *
      s = Solver()
      c = BitVec('c', 32)                      # 序列号的 32 位部分
      s.add(c ^ 0xDEADBEEF == c * 3 + 0x55)    # 来自反编译的约束
      s.add(c & 0xFF == 0x5A)                  # 校验位约束
      print(s.check(), s.model() if s.check() == sat else '')
      
    • Align bit width and byte order with decompilation semantics (unsigned / signed, little-endian / big-endian, see pitfall 4)
    • When constraints are incomplete, add constraints first: length / character set / bit width are each a pruning of the solution space—when z3 has no solution, relax them one by one to locate the contradictory constraint (for modeling details see [[re-z3]])
  5. Implement the keygen in python:

    • Write keygen.py:argparse to take input (username / machine code), internally generate the serial number according to the back-derivation steps, and output it in the format (with / without separators)
    • Compare line by line with the decompiled pseudocode (each line of transformation corresponds to a section of implementation, add comments); do not "rewrite by feel"
    • Built-in unit test: generate → recompute with the verification algorithm, which must pass (also write the verification logic into the script as a self-check function)
  6. Boundary (check code / check digit) handling:

    • Common check digits: Luhn (bank card type), CRC16 / CRC32, mod 97 / mod 11, length bits, delimiter format (XXXX-XXXX-XXXX); first compute the data bits → then append the check digits
    • Character set: uppercase / digits / remove easily confused characters (0-O, 1-I); output length must strictly match the program's requirements
    • Normalization: before generation, first apply the program's preprocessing to the input (remove spaces, toUpper, zero-pad), to ensure consistency with the verification side (see pitfall 3)
  7. Multi-platform output (CLI script):

    • Pure python3 standard library (argparse is enough, avoiding platform differences); works on Linux / macOS / Windows python3 keygen.py --name Alice
    • Optional output formats: with / without delimiters, batch generation (for multiple test sets)
    • Script includes a verification mode:--verify Run the verification logic in reverse on the input serial number; output only if it passes (self-check closed loop)

Verification: inside the sandbox ([[re-sandbox]]) run the target program with the generated serial number—it must pass all checkpoints in the [[re-license]] checklistallcheckpoints (startup + feature points); then use a serial number known to be valid by the program to cross-check the script output (see pitfall 4). File the conclusion and algorithm documentation under [[re-analyze/analysis-contract]].

Black-box regression: batch-generate and batch-verify with multiple different inputs (long username / all digits / empty string / boundary characters)—cover normalization and boundary branches, avoiding passing on only a single input.

Cross-domain combination

  • [[re-cracking]]: this gateway is step 5 (keygen) of the re-cracking workflow; step 6 is unified verification
  • [[re-license]]: upstream—the verification algorithm and input sources (machine-code binding is in its step 5) come from this skill's caller; this skill's output can also be used to verify that re-license's algorithm restoration is correct
  • [[re-patching]]: substitute relationship—for irreversible algorithms / quick bypass, use patches; checkpoints that this skill cannot cover (irreversible parts) are handed over to patching
  • [[re-binary-core]]: decompilation workbench ([[re-ghidra]] / [[re-ida]] / [[re-radare2]])
  • [[re-crypto-id]] / [[re-crypto-decrypt]]: ideas for identifying and restoring the serial-number encryption/decryption stage (XOR / table lookup / custom transformation)
  • [[re-sandbox]]: generate a serial number to verify the sandbox ([[re-analyze/platform-tips]] highest principle)
  • [[re-ioc]]: keygen features / serial-number generation algorithm fingerprints can serve as detection features

Common pitfalls and traps

  • The algorithm contains irreversible parts (hash / asymmetric): Symptom—the verification algorithm contains SHA1 / MD5 / RSA signature verification, and a keygen cannot generate by forward computation; Cause—one-way functions are irreversible, and the serial number is obtained irreversibly from a private key / hash; Countermeasure—report honestly: change that part to [[re-patching]] (skip signature verification / alter branches); z3 models only the reversible parts, so do not force irreversible segments into constraints
  • Username binding → generation logic must include the input: Symptom—the generated serial number is valid on one machine / one username, but invalid with a different input; Cause—the algorithm input includes a machine code / username (machine-code binding in [[re-license]] step 5); Countermeasure—the keygen must parameterize the input: the CLI requires a username / machine code to be provided, and the generation logic derives from the input (reserve in the template --name / --machine parameters)
  • Case / format verification: Symptom — the algorithm is correctly restored but the generated serial number is rejected by the program; Cause — the program performs normalization before comparison (tolower / removing separators / zero-padding / specified length), or requires a specific character set; Countermeasure — restore the program's normalization steps into the generation logic (normalize the input first, then generate), and confirm word by word against the comparison code in [[re-license]] step 3; verify multiple formats (with / without separators) separately
  • Algorithm restoration is off by one bit (overflow / carry / byte order): Symptom — the handwritten implementation always differs from the program output by one bit, or is occasionally wrong in a paired way; Cause — unsigned / signed overflow, carry, endianness differences (especially 32-bit multiplication / shifts); Countermeasure — compare line by line against the decompiled pseudocode (step 5 annotation comparison method); use a known valid serial number as a test vector: in the sandbox, have the debugger break on the verification function, feed in a set of inputs and record the program's internal computed values, then compare them one by one with the script's intermediate values to locate the discrepancy
  • Missed second-layer verification: Symptom — startup verification passes, but specific functions are still rejected; Cause — there are multiple verification points (besides format verification, there are also feature points / activation count / validity period); Countermeasure — verify point by point against the full verification point checklist in [[re-license]], don't verify only the startup path
  • Check digit order / radix confusion: Symptom — the check digit algorithm is correct but it is always off by one digit; Cause — incorrect judgment of the order in which the check digit participates (data first then check vs the check digit also counted into the next round), or the radix (decimal vs hexadecimal vs base36); Countermeasure — use a known valid serial number to reverse-engineer the verification process digit by digit, determine the participation order and radix, then implement

For the in-depth methodology (algorithm classification tree / evidence grading / pitfall boundaries), see [[decision-tree]] and [[gotchas]]