Hagen Fritsch

Dropbox Bytecode Decryption Tool

Dropbox is actually just a python application, so it is shipping the bytecode of its modules which one could theoretically use in other applications. Also building a more lightweight dropbox-client, that does not come with its own interpreter, might be a goal. Apparently though, dropbox does not want this and makes it slightly harder to get to the bytecode.
So here is a project I’ve been working on quite some time ago, which converts the encrypted python modules of dropbox to real python-2.5 modules usable in a normal interpreter. This works just fine, but as I don’t have the time to pursue this any further I’ll just provide the results (or the source) and hope that others use this as a base to continue.

The encryption scheme is actually quite simple. It uses the TEA cipher along with an RNG seeded by some values in the code object of each python module. They adjusted the interpreter accordingly so that it a) decrypts the modules and b) prevents access to the decrypted code-objects. This would have been the straightforward path just letting dropbox decrypt everything and dump the modules using the builtin marshaller.
Another trick used is the manual scrambling of the opcodes. Unfortunately this could only be fixed semiautomatically thus their monoalphabetic substitution cipher proved quite effective in terms of winning some time.

You’ll find the source at github/dropboxdec

Grab and unpack the prerequisites::

wget -nv https://github.com/rumpeltux/dropboxdec/tarball/master -O - | tar xzv
wget -nv http://dl-web.dropbox.com/u/17/dropbox-lnx.x86-1.1.45.tar.gz -O - | tar xzv
# use dropbox-lnx.x86_64-1.1.45.tar.gz if you're running a 64bit os
cd .dropbox-dist; unzip library.zip; chmod a+rw -R .; cd ..

Run the decryption tool::

python dropboxdec*/dec.py .dropbox-dist

From here
The decrypted modules are python-2.5 bytecode, thus will only work in a 2.5 bytecode interpreter. There are some decompilers for other python-versions which will need some adjustments to be able to decompile the code, if anyone wants to dive deeper into the protocol.
The decryption also only works for the 1.1.45 version of dropbox. In the 1.2 branch the simple RNG was exchanged to the Mersenne Twister, so the decryption program would need to be adjusted accordingly.

If you do anything cool with it, I’d very much appreciate if you’d drop me a line and let me know :) Other than that, have fun hacking!

15 Kommentare zu “Dropbox Bytecode Decryption Tool”

  1. Wangam 18.04.2012 um 6:04 pm

    You’re a braver man than I – shortly after Dropbox was released I also did the same, and then later updated the code so I could take a look at the new 1.3 versions, but declined to release anything in case I got sued. Good luck man!

  2. Hagen Fritscham 24.04.2012 um 7:17 am

    I’m quite positive, that this is not illegal. And it’s mainly to spare others from having to do the very same effort. If you have patches for the newer series, I’d love to integrate them to the source.
    Anonymous pastebins will also work 😉

  3. Donam 08.08.2012 um 1:21 pm

    Hi, can you explain in detail about how it prevent access to the code objects?

  4. Hagen Fritscham 08.08.2012 um 1:47 pm

    While I already forgot most of the details, this should help you: the dropbox binary is just a python interpreter. However, their own modified version of it. So normally, code-objects can be accessed from the interpreter. In the dropbox python interpreter binary, the co_code object is simply not exposed anymore.

  5. Donam 08.08.2012 um 3:07 pm

    i am already aware of that modification. but i don’t see any way to inhibit access to code objects. i read about python object(pyobject) docs, the flags seems to not include an access protection.

  6. Hagen Fritscham 08.08.2012 um 3:19 pm

    This can be done by removing the co_code line from code_memberlist in Objects/codeobject.c:165.

  7. joeam 17.10.2012 um 2:53 am

    How did you get the opcode remapping table? It says it was automatically generated for the most part and then manually generated for the rest.

  8. vatam 07.12.2012 um 5:51 am

    Hi Hagen,

    Is is possible to update your tool to work with Dropbox 1.6.x?

    Any hints / pointers (on how to do it) will be very helpful.


  9. Мішаam 06.01.2013 um 4:20 am

    While trying to decode dropbox-1.6.11, I get errors like:

    error bad marshal code: (234) ValueError(‘bad marshal code: \xea (234)’,)

    on EVERY FILE.

    In addition, the Python interpreter (tried using both 2.6 and 2.7) running dec.py attempts to use all available memory (reaching 12Gb before I kill it).

    Is this because of the new encryption/obfuscation method used by Dropbox? Would’ve been very nice to have a way to get the real python code out.

    Unlike on Linux, where this is just aesthetics and efficiency, dropboxd simply does not work on FreeBSD…

    The initial sign-up works fine using the “linuxulator”, but it does not sync any actual files — presumably, because the directory watching syscalls are completely different between the OSes and the linuxulator does not translate the inotify calls into BSD’s kqueue().

  10. Мішаam 06.01.2013 um 4:23 am

    Oh, and another obvious missing feature is the ability to give a list of files, rather than a single directory, to dec.py

    Thank you! :-)

  11. Hagen Fritscham 08.01.2013 um 8:20 am

    Hi there! Yes this software is written explicitly for Dropbox 1.1.45, so it totally won’t work with newer versions. I only know that the RNG was exchanged in the 1.2 version, but don’t know if any other modifications were made.
    I’m not currently looking into this (nor do I plan to do so in the near future). However, the code should give you or anyone interested a well enough starting point, as I don’t assume they changed much in more recent implementations.

  12. Мішаam 12.01.2013 um 8:28 am

    Have you tried this approach, perhaps:

    Replace one of the .so files, that come inside the tarball (such as zlib.so) with your own
    That version would — for each file — call into the PyMarshal_ReadObjectFromFile() — resolving that symbol from inside the executable itself. The returned object can then be dumped into a (separate) file and your patch function can be called to fix the op-codes.

    This method has the potential of being future-proof — even if Dropbox decide to change the obfuscation method once again, the hack is likely to continue working.

    I’d try it, but I am disadvantaged — I can run Linux binaries on my FreeBSD box, but I can not generate them (well, not easily)…

  13. Hagen Fritscham 12.01.2013 um 10:04 am

    That’s a great idea and I’ll give it a shot as soon as I got some spare time! Thanks.

  14. Andrewam 10.02.2013 um 9:33 am

    This is a great tool, I was able to fix the pyc files the decompile with uncompyler2. Now that I’ve decompiled everything, I’ve made a change I wanted to make and made it back into a pyc file with python (actually do I have to do that with 2.5?). Now I think I need to reverse this process to get dropbox to run my new code.

    Is there any information you can give me to help me reverse this process?

    Thanks for the tool!

  15. Мішаam 21.07.2013 um 4:40 pm

    Hi, there! Any updates on Dropbox-decompiling front?

Trackback URI | Kommentare als RSS

Einen Kommentar schreiben