|  | #!/usr/bin/env python3 | 
        
          |  |  | 
        
          |  | """ | 
        
          |  | Script was made by @alula on GitHub | 
        
          |  |  | 
        
          |  | I made some improvements and modified it to be more user-friendly. | 
        
          |  | """ | 
        
          |  |  | 
        
          |  | import json | 
        
          |  | import hashlib | 
        
          |  | from datetime import datetime | 
        
          |  |  | 
        
          |  |  | 
        
          |  | TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S' | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def license_structure(name: str, email: str, license_key: str) -> dict: | 
        
          |  | now = datetime.now() | 
        
          |  | ten_years_later = now.replace(year=now.year + 10) | 
        
          |  |  | 
        
          |  | ts_start = now.strftime(TIMESTAMP_FORMAT) | 
        
          |  | ts_end = ten_years_later.strftime(TIMESTAMP_FORMAT) | 
        
          |  |  | 
        
          |  | base = { | 
        
          |  | "header": {"version": 1}, | 
        
          |  | "payload": { | 
        
          |  | "name": name, | 
        
          |  | "email": email, | 
        
          |  | "licenses": [ | 
        
          |  | { | 
        
          |  | "id": license_key, | 
        
          |  | "license_type": "named", | 
        
          |  | "product": "IDA", | 
        
          |  | "seats": 1, | 
        
          |  | "start_date": ts_start, | 
        
          |  | "end_date": ts_end,  # This can't be more than 10 years! | 
        
          |  | "issued_on": ts_start, | 
        
          |  | "owner": name, | 
        
          |  | "add_ons": [], | 
        
          |  | "features": [], | 
        
          |  | } | 
        
          |  | ], | 
        
          |  | }, | 
        
          |  | } | 
        
          |  |  | 
        
          |  | addons = [ | 
        
          |  | "HEXX86", | 
        
          |  | "HEXX64", | 
        
          |  | "HEXARM", | 
        
          |  | "HEXARM64", | 
        
          |  | "HEXMIPS", | 
        
          |  | "HEXMIPS64", | 
        
          |  | "HEXPPC", | 
        
          |  | "HEXPPC64", | 
        
          |  | "HEXRV64", | 
        
          |  | "HEXARC", | 
        
          |  | "HEXARC64", | 
        
          |  | # Probably cloud? | 
        
          |  | # "HEXCX86", | 
        
          |  | # "HEXCX64", | 
        
          |  | # "HEXCARM", | 
        
          |  | # "HEXCARM64", | 
        
          |  | # "HEXCMIPS", | 
        
          |  | # "HEXCMIPS64", | 
        
          |  | # "HEXCPPC", | 
        
          |  | # "HEXCPPC64", | 
        
          |  | # "HEXCRV", | 
        
          |  | # "HEXCRV64", | 
        
          |  | # "HEXCARC", | 
        
          |  | # "HEXCARC64", | 
        
          |  | ] | 
        
          |  |  | 
        
          |  | for i, addon in enumerate(addons): | 
        
          |  | base["payload"]["licenses"][0]["add_ons"].append( | 
        
          |  | { | 
        
          |  | "id": f"48-1337-DEAD-{i:02}", | 
        
          |  | "code": addon, | 
        
          |  | "owner": base["payload"]["licenses"][0]["id"], | 
        
          |  | "start_date": ts_start, | 
        
          |  | "end_date": ts_end, | 
        
          |  | } | 
        
          |  | ) | 
        
          |  |  | 
        
          |  | return base | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def json_stringify_alphabetical(obj: dict) -> str: | 
        
          |  | return json.dumps(obj, sort_keys=True, separators=(",", ":")) | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def buf_to_bigint(buf: bytes) -> int: | 
        
          |  | return int.from_bytes(buf, byteorder="little") | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def bigint_to_buf(i: int) -> bytes: | 
        
          |  | return i.to_bytes((i.bit_length() + 7) // 8, byteorder="little") | 
        
          |  |  | 
        
          |  |  | 
        
          |  | # Yup, you only have to patch 5c -> cb in libida64.so | 
        
          |  | pub_modulus_hexrays: int = buf_to_bigint( | 
        
          |  | bytes.fromhex( | 
        
          |  | "edfd425cf978546e8911225884436c57140525650bcf6ebfe80edbc5fb1de68f4c66c29cb22eb668788afcb0abbb718044584b810f8970cddf227385f75d5dddd91d4f18937a08aa83b28c49d12dc92e7505bb38809e91bd0fbd2f2e6ab1d2e33c0c55d5bddd478ee8bf845fcef3c82b9d2929ecb71f4d1b3db96e3a8e7aaf93" | 
        
          |  | ) | 
        
          |  | ) | 
        
          |  | pub_modulus_patched: int = buf_to_bigint( | 
        
          |  | bytes.fromhex( | 
        
          |  | "edfd42cbf978546e8911225884436c57140525650bcf6ebfe80edbc5fb1de68f4c66c29cb22eb668788afcb0abbb718044584b810f8970cddf227385f75d5dddd91d4f18937a08aa83b28c49d12dc92e7505bb38809e91bd0fbd2f2e6ab1d2e33c0c55d5bddd478ee8bf845fcef3c82b9d2929ecb71f4d1b3db96e3a8e7aaf93" | 
        
          |  | ) | 
        
          |  | ) | 
        
          |  |  | 
        
          |  | private_key: int = buf_to_bigint( | 
        
          |  | bytes.fromhex( | 
        
          |  | "77c86abbb7f3bb134436797b68ff47beb1a5457816608dbfb72641814dd464dd640d711d5732d3017a1c4e63d835822f00a4eab619a2c4791cf33f9f57f9c2ae4d9eed9981e79ac9b8f8a411f68f25b9f0c05d04d11e22a3a0d8d4672b56a61f1532282ff4e4e74759e832b70e98b9d102d07e9fb9ba8d15810b144970029874" | 
        
          |  | ) | 
        
          |  | ) | 
        
          |  |  | 
        
          |  | example_real_sig_bytes: bytes = bytes.fromhex("8C601843D20AF0997C175723F49D6C6CE77A039F3FFCEC95B89FD99611C0EDDE0B9762A977C408D25662C06B2424B83EDDFBE30177C1A99A881ED1B695F2AD38E4119058463B0CA1BEA651CFCAFBD60E68A407FD76D519063CFB6EF35FFE7C1A375388BC5EB5565C29AFAB06BF0031A7A2AA7433CBD929FD8D12E160981D0812") | 
        
          |  | example_real_sig_bigint: int = buf_to_bigint(example_real_sig_bytes) | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def decrypt(message: bytes, use_patched: bool = True) -> bytes: | 
        
          |  | mod: int = pub_modulus_patched if use_patched else pub_modulus_hexrays | 
        
          |  | decrypted_bigint: int = pow(buf_to_bigint(message), exponent, mod) | 
        
          |  | decrypted_bytes: bytes = bigint_to_buf(decrypted_bigint) | 
        
          |  | rev_decrypted_bytes = decrypted_bytes[::-1] | 
        
          |  | print(f"decrypt: msg: {message.hex().upper()} decryped_bytes: {decrypted_bytes.hex().upper()} rev_decrypted_bytes: {rev_decrypted_bytes.hex().upper()}") | 
        
          |  | return rev_decrypted_bytes | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def encrypt(message: bytes, use_patched: bool = True) -> bytes: | 
        
          |  | mod: int = pub_modulus_patched if use_patched else pub_modulus_hexrays | 
        
          |  | encrypted_bigint: int = pow(buf_to_bigint(message[::-1]), private_key, mod) | 
        
          |  | encrypted: bytes = bigint_to_buf(encrypted_bigint) | 
        
          |  | print(f"encrypt: msg: {message.hex().upper()} encrypted: {encrypted.hex().upper()}") | 
        
          |  | return encrypted | 
        
          |  |  | 
        
          |  |  | 
        
          |  | exponent = 0x13 | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def sign_hexlic(payload: dict) -> str: | 
        
          |  | data = {"payload": payload} | 
        
          |  | data_str = json_stringify_alphabetical(data) | 
        
          |  |  | 
        
          |  | buffer = bytearray(128) | 
        
          |  | # first 33 bytes are random | 
        
          |  | for i in range(33): | 
        
          |  | buffer[i] = 0x42 | 
        
          |  |  | 
        
          |  | # compute sha256 of the data | 
        
          |  | sha256 = hashlib.sha256() | 
        
          |  | sha256.update(data_str.encode()) | 
        
          |  | digest = sha256.digest() | 
        
          |  | print(f"sha-256 digest: {digest.hex().upper()}") | 
        
          |  |  | 
        
          |  | # copy the sha256 digest to the buffer | 
        
          |  | for i in range(len(digest)): | 
        
          |  | buffer[33 + i] = digest[i] | 
        
          |  |  | 
        
          |  | print(f"pre-encrypted buffer: {buffer.hex().upper()}") | 
        
          |  | # encrypt the buffer | 
        
          |  | encrypted = encrypt(buffer) | 
        
          |  | print(f"post-encrypted buffer: {encrypted.hex().upper()}") | 
        
          |  | decrypted_sanity = decrypt(encrypted) | 
        
          |  | print(f"decrypted encrypted buffer: {decrypted_sanity.hex().upper()}") | 
        
          |  |  | 
        
          |  | return encrypted.hex().upper() | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def main(): | 
        
          |  | print("IDA Pro 9.0 BETA Keygen") | 
        
          |  | print("(!) DISCLAIMER: This is for educational purposes only. (!)") | 
        
          |  | print("(!) Please note that you must patch the public modulus inside of the ida and ida64 dynamic libraries. (!)") | 
        
          |  | print("  ↳ For more information about this process: https://gist.github.com/AngeloD2022/e949c1c7c2a51513c620ac5dd5212b94\n\n") | 
        
          |  |  | 
        
          |  | lic_name = input("Enter desired license name (can be fake): ") | 
        
          |  | lic_email = input("Enter license email address (can be fake): ") | 
        
          |  |  | 
        
          |  | print("Generating license base...") | 
        
          |  | lic_base = license_structure(lic_name, lic_email, "48-2437-ACBD-29") | 
        
          |  |  | 
        
          |  | print("Signing...") | 
        
          |  | lic_base["signature"] = sign_hexlic(lic_base["payload"]) | 
        
          |  |  | 
        
          |  | print("Generating ida.hexlic...") | 
        
          |  | serialized = json_stringify_alphabetical(lic_base) | 
        
          |  |  | 
        
          |  | with open("ida.hexlic", "w") as file: | 
        
          |  | file.write(serialized) | 
        
          |  |  | 
        
          |  | print("Finished.") | 
        
          |  |  | 
        
          |  |  | 
        
          |  | if __name__ == '__main__': | 
        
          |  | main() |