Created
September 21, 2026 06:11
-
-
Save WitherOrNot/e1e1b0fb662fbbfabe99d4c71d8c5cb2 to your computer and use it in GitHub Desktop.
drm for stolen games.... really?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from Crypto.Cipher import PKCS1_OAEP | |
| from Crypto.PublicKey import RSA | |
| from Crypto.Cipher import AES | |
| from Crypto.Hash import SHA256, CMAC | |
| from json import loads | |
| from urllib.parse import urlparse | |
| from random import randbytes | |
| from sys import argv | |
| import requests | |
| import zlib | |
| import zstandard as zstd | |
| PRIVKEY = """-----BEGIN RSA PRIVATE KEY----- | |
| MIIEogIBAAKCAQEAvPdrJigQ0rZAy+jla7hSjwen8gkF0gjtl+lZGY59KatNd9Kj | |
| 2gfY7dTMM+5M2tU4Wr3nk8KWr5qKm3hzo/2CGbc55im3tlRl6yuFxWQ+c/I2SM5L | |
| 3xp6eiLUcumMsEo0B7ELmtnHTGCCNAIzTFzV4XcWGVbkZj83rTFxpLsa1oArTdcz | |
| 5CG6qgyVe7KbPsft76DAEkV8KaWgnQiG0DpsINFy4vISmf6L1TgAryJ8l2K4y8Qb | |
| ymyLeMsABdlEI3yRHAm78PSezU57XtQpHW5Iaupup8Es6bcDZQKkRsbOeR9T74tk | |
| j+k44QrjZo8xpX9tlJAKEEmwDlyAg0O5CLX3CQIDAQABAoIBAASuEs/Gzz/aUEZP | |
| ws4FQ+1gUN1ly5vOwv+i2yUoY8FfIwbtxxQUlkYYCDF2Qred7z+qecYT9cJsm+eY | |
| A8xfo22HanfHHoWPMPHL/QvZ9ms0G2CrOn+dVF1naAaRvsonVE/0DdsGCL5DmtK2 | |
| uTy4OEdvH4BKKCCMit1cHtOBgZUm9XqDvREtKrykAlZYg1MVwkuYpJ+xnQFE7r3O | |
| k4u4+LvmxDsz6yCQ80LKzVyRujWUO17Ek1OLhcy+b+9sGu7vMUHAGFLDhVpEkY2R | |
| 7Dyp75jZgiZzNh/w7awc6q/kFSrH4pZRRZMvws+2xsBa2dpzz5xfzJZuLmBHTmV2 | |
| cUrrHlkCgYEAwHUPEpiZdl562g+BE9To2TzIPKHLIYq40MyBq9YNY0TfCGaO4wo+ | |
| 01p3ir4Flo9gyJSOauOcM/gIdsKws3vrnW3ruw18Ktj3hCRY7R27DMWJ3r8rSrQd | |
| AkOXTE1YnkUJITV4wu+pawL/XbsAhyhhGdPvXJ9+oAhJkxmg8tffJg0CgYEA+1tP | |
| fZ+oA6i+o6kxWCj8oB3u/FwUGjmtQ3dtI2NTtxF+Z9dKg2C8Ow00DB1C4bFhMfhp | |
| vZBDePIL4W+RHFv3MHGrbAU7ZVXXNPiKkF3tlLLYir3lXTmVZZPlc+Pb0/0Ypd04 | |
| S/km5mm58ASLTiAtkak4UXvGkQQO0JX3Mcukce0CgYBngc2Uc8v9dHzgMHx8XQLK | |
| az1KFr44EPKrIYIQF/RlUlIdo4Lvqr/1Te+DCAXbXstvtS4PYNDOxnRO4xDDxz8G | |
| EWs509vW84/TWvUUueuyx78JtIklCU+cuxtxJxwlKv3pBWgod1sHubn8ACodhuMK | |
| UAipKQKiMTLY0WzVjrJuNQKBgBGfllQ1hH81LqCk9Tu8K/JCBwaUoigwkRBg6DsJ | |
| 9M2qIVXAh43sk2YEh/iteIoAeNMbGrbazZBGUETvIJp/bDZuUdmSCFcTjLI/FuAG | |
| Zej+HSalJ9bAedQUaYsVl80mOrsuZosVHgAbu5iziNzibq9+0N8NsZ9rTGqdiSZp | |
| o88FAoGAdWxxEoJGahPiLQQV06Ls5UH9wmVTwiGHwK8D6yH43FmEEcuPaCLI14tA | |
| Cywq7RqLvpxJLURwVGaf8F9gQXUQx6uShZqWqZtShtCA5tao+T7sbiaQvuz8K5PP | |
| qhrSJu45HFc7BYcbbD4j9F6jZtowBVDMC3bT4xf+0GHesfmKh3E= | |
| -----END RSA PRIVATE KEY-----""" | |
| def unwrap_key(key): | |
| privateKey = RSA.importKey(PRIVKEY) | |
| cipher = PKCS1_OAEP.new(privateKey, hashAlgo=SHA256, label=b'') | |
| buf = cipher.decrypt(key) | |
| return buf | |
| def hauth_transform(url: str): | |
| parsed = urlparse(url) | |
| return f"{parsed.scheme}://{parsed.hostname.lower()}" | |
| def decrypt_index(data): | |
| if data[0:7] != b'TINFOIL': | |
| return data | |
| flags = data[7] & 0x0F | |
| data = data[8:] | |
| encAesKey = data[0:256] | |
| if encAesKey != b"\x00" * 256: | |
| aesKey = unwrap_key(encAesKey) | |
| data = data[256:] | |
| len = int.from_bytes(data[0:8], byteorder='little') | |
| cipher = AES.new(aesKey, AES.MODE_ECB) | |
| data = cipher.decrypt(data[8:]) | |
| else: | |
| data = data[256:] | |
| len = int.from_bytes(data[0:8], byteorder='little') | |
| data = data[8:] | |
| if flags == 0x0E: #zlib | |
| data = zlib.decompress(data[0:len]) | |
| elif flags == 0x0D: #zstd | |
| dctx = zstd.ZstdDecompressor() | |
| data = dctx.decompress(data[0:len]) | |
| elif flags == 0x00: #plaintext | |
| data = data[0:len] | |
| else: | |
| raise IOError('invalid flag') | |
| return data | |
| def auth(data): | |
| cmac = CMAC.new(bytes.fromhex("19766ed6ccb2f4a32778eed80d1928d2"), ciphermod=AES) | |
| cmac.update(data) | |
| return cmac.hexdigest().upper() | |
| def hauth(url): | |
| return auth(hauth_transform(url).encode() + b"\x00") | |
| def uauth(url): | |
| return auth(url.encode() + b"\x00") | |
| def get_index(url): | |
| s = requests.session() | |
| s.keep_alive = False | |
| resp = s.get(url, headers={ | |
| "User-Agent": "@@@SKIP_HEADER@@@", | |
| "Theme": "0000000000000000000000000000000000000000000000000000000000000000", | |
| "Accept-Encoding": "@@@SKIP_HEADER@@@", | |
| "Version": "20.0", | |
| "Revision": "2", | |
| "Language": "en", | |
| "HAUTH": hauth(url), | |
| "UAUTH": uauth(url), | |
| "UID": randbytes(32).hex().upper() | |
| }, verify=False) | |
| return decrypt_index(resp.content) | |
| if __name__ == "__main__": | |
| url = argv[1] | |
| with open("index.json", "wb") as f: | |
| f.write(get_index(url)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment