dlc decrypter/decoder

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
elbarto132
User
Beiträge: 6
Registriert: Donnerstag 28. Mai 2009, 14:45

ich hatte schon länger mal vor einen dlc decrypter/decoder zu schreiben, war aber immer zu faul mich durch das mistige java zu wühlen :roll:
heute nachmittag wars dann aber soweit
so wie es jetzt hier gepostet ist wird es nur eine begrenzte zeit funktionieren, kommt darauf an wie schnell die jdownloader programmierer im umändern sind
wenn es geändert wird:
werte b, p und v bekommt man mit wireshark falls dort eine änderung notwendig sein sollte
die methode zum erstellen des jdownloader keys müssen sie natürlich auch ändern, da muss man sich dann wohl wieder den quelltext vom jdownloader angucken um das anzupassen
den rest werden sie eher nicht ändern, weil ansonsten eine anpassung aller programme die dlc dateien öffnen können nötig wäre

Code: Alles auswählen

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import re
import urllib2
import base64
import hashlib
from Crypto.Cipher import AES

dlcfile = "c:\\bla.dlc"
jdhashlist = "C:\\JDownloader\\tmp\\hashlist.lst"

b = "last09"
p = "2009"
v = "9.581"

jdkey = []
for x in re.findall("=(.*?);", open(jdhashlist,"r").read()):
    jdkey.append(x[0])
jdkey.reverse()
jdkey = hashlib.md5("".join(jdkey)).digest()

file = open(dlcfile).read()

data = "destType=jdtc5&b=" + b + "&p=" + p + "&srcType=dlc&data=" + file[-88:] + "&v=" + v
header = {'User-agent' : 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10', 'rev': v}
req = urllib2.Request('http://service.jdownloader.org/dlcrypt/service.php', data, header)
h = urllib2.urlopen(req)

key2 = re.search("<rc>(.*?)</rc>", h.read()).group(1)
key2 = base64.b64decode(key2)

decryptor = AES.new(jdkey, AES.MODE_ECB)
key3 = base64.b64decode(decryptor.decrypt(key2))

decryptor2 = AES.new(key3, AES.MODE_CBC, key3)
f = decryptor2.decrypt(base64.b64decode(file[:-88]))
content = base64.b64decode(f)

for x in re.findall("<file>.*?<url>(.*?)</url>", content, re.DOTALL):
    print base64.b64decode(x)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Für die Unwissenden: Was genau ist ein dlc decoder?

Was mir so aufgefallen ist:

- Nur Code auf Modulebene; für ein Showcase-"Projekt" ein wenig mager imho ;-) Aufgrund der Länge hätte ich es auch eher zu den Snippets gepackt.

- Wieso werden da Pfade hart codiert? Das würde man doch per ``sys.argv`` besser lösen können (oder eben ``argpasre`` / ``optparse``) Außerdem sollte man bei Pfaden Raw-Strings nutzen, das erspart einem das Escapen von Backslashen)

Code: Alles auswählen

dlcfile = r"c:\bla.dlc"
- ``dlcfile`` ist vom Namen suboptimal, da es sich nur um den Dateinamen (bzw. sogar den kompletten Pfad) handelt und nicht um ein file-Object. Analoges gilt auch für ``jdhashlist``, was ja auch keine Liste repräsentiert.

- Sind ``b``, ``p`` und ``v`` Standardnamen in diesem Kontext? Wenn ja ok, ansonsten sollten die wohl auch aussagekräftiger sein.

- Das Einlesen von Dateien würde ich denn doch mit ``with`` lösen; alleine schon, weil dann die Datei auch wieder geschlossen wird.

- ``file`` ist auch kein guter Name, da es ein Built-in überschreibt.

- Für das Zusammenbauen von ``data``würde ich mit ``urllib.urlencode`` erledigen.

- ``key2`` und ``key3`` sind auch unschöne Namen; bei Nummerierungen erwartet man eher eine Liste oder ein Tupel. (Wieso eigentlich gibt es dann keinen ``key1`` ;-) )

- Wie oben schon angedeutet würde ich das in eine Funktion verpacken. Damit kann man das Modul auch in anderen Programmen benutzen. In eine ``main()``-Funktion würde ich einen Aufruf mit Datein aus der Kommandozeile verfügbar machen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
elbarto132
User
Beiträge: 6
Registriert: Donnerstag 28. Mai 2009, 14:45

das ist dlc: http://de.wikipedia.org/wiki/JDownloade ... _Container
das programm holt dementsprechend die links aus dem container

es ging mir auch nicht darum schönen code zu schreiben, dass es schöner geht ist mir durchaus klar ;)
es geht hier um die funktionalität, denn mir ist kein anderer öffentlich zugänglicher quellcode bekannt (in keiner sprache) der diese funktion bietet
um das ernsthaft zu benutzen muss man dort nun noch irgendwas drum herum bauen, aber so wirklich brauchen tue ich es auch eigentlich nicht :D

hier noch ein click'n'decrypt:

Code: Alles auswählen

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import base64
from Crypto.Cipher import AES
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
import cgi
import PyV8

class GetHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        v = """jdownloader=true;
var version='9.581';"""
        if self.path.strip("/").lower()=="crossdomain.xml":
            v = """<?xml version=\"1.0\"?>
<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">
<cross-domain-policy>
<allow-access-from domain=\"*\" />
</cross-domain-policy>"""

        self.send_response(200)
        self.send_header("Content-Length", len(v))
        self.send_header("Content-Language", "de")
        self.send_header("Vary", "Accept-Language, Cookie")
        self.send_header("Cache-Control", "no-cache, must-revalidate")
        self.send_header("Content-type", "text/html")
        self.end_headers()
        
        self.wfile.write(v)
        
    def do_POST(self):
        form = cgi.FieldStorage(
            fp=self.rfile,
            headers=self.headers,
            environ={'REQUEST_METHOD':'POST',
                     'CONTENT_TYPE':self.headers['Content-Type'],
                     })
                    
        with PyV8.JSContext() as ctxt:
            ctxt.enter()
            s = ctxt.eval(form.getfirst("jk")+" f()")

        c = base64.b16decode(s.upper())
        decryptor = AES.new(c, AES.MODE_CBC, c)
        f = decryptor.decrypt(base64.b64decode(form.getfirst("crypted")))
        
        print f.replace("\x00", "")
        print "pw:", form.getfirst("passwords")
        
server = HTTPServer(('localhost', 9666), GetHandler)
server.serve_forever()
wie man schon erahnen kann gibt es die links aus wenn man auf einen click'n'load knopf drückt ;)
benötigt das: http://code.google.com/p/pyv8/
Antworten