diff --git a/.gitignore b/.gitignore index 5684153..3533c43 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,7 @@ nosetests.xml # Mr Developer .mr.developer.cfg .project -.pydevproject \ No newline at end of file +.pydevproject + +# Ask me for the key ;) +dlc2txt_KEY.py diff --git a/README.md b/README.md index 95b3c76..f18fe2b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ DLCDecrypt ========== +This little tool can decrypt DLC Files. +Many thanks goes out to the folks of PyLoad. This code is mostly a ripoff of their DLC code modified to run alone. +Checkout pyload at: http://pyload.org/ +### Usage: +``` +./dlc2txt dlcFile.dlc +``` + +This produces a file named after the given name in the DLC. diff --git a/dlc2txt.py b/dlc2txt.py new file mode 100755 index 0000000..6a6f3f0 --- /dev/null +++ b/dlc2txt.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import urllib +import re +import requests +import base64 +import xml.dom.minidom +from Crypto.Cipher import AES + +def decrypt(fs_filename): + KEY = "" + IV = "" + API_URL = "http://service.jdownloader.org/dlcrypt/service.php?srcType=dlc&destType=pylo&data=%s" + + with open(fs_filename) as dlc: + data = dlc.read().strip() + data += '=' * (-len(data) % 4) + dlc_key = data[-88:] + dlc_data = base64.b64decode(data[:-88]) + dlc_content = load(API_URL % dlc_key) + print(dlc_content) + + try: + rc = base64.b64decode(re.search(r'(.+)', dlc_content, re.S).group(1)) + except AttributeError: + print("Error: invalid DLC") + + key = iv = (AES.new(KEY, AES.MODE_CBC, IV).decrypt(rc)).decode('utf-8') + data = base64.b64decode(AES.new(key, AES.MODE_CBC, iv).decrypt(dlc_data)).decode('utf-8', 'ignore') + plainData = get_packages(data)[0] + print('\n'.join(plainData[1])) + with open(plainData[0], mode='wt', encoding='utf-8') as rawLinkFile: + rawLinkFile.write('\n'.join(plainData[1])) + +def load(url): + r = requests.get(url) + return r.text + +def fixurl(url): + return urllib.unquote(url.decode('unicode-escape')).strip().rstrip('/') + +def get_packages(data): + root = xml.dom.minidom.parseString(data).documentElement + content = root.getElementsByTagName("content")[0] + return parse_packages(content) + +def parse_packages(startNode): + return [(decode(base64.b64decode(decode(node.getAttribute("name")))), parse_links(node)) for node in startNode.getElementsByTagName("package")] + +def parse_links(startNode): + return [decode(base64.b64decode(node.getElementsByTagName("url")[0].firstChild.data)) for node in startNode.getElementsByTagName("file")] + +def decode(string): + try: + return string.decode("utf8", "replace") + except: + return string + +decrypt(sys.argv[1])