In Windows the Dropbox client uses python25.dll and the MS C runtime libraries (msvcp71.dll, etc). On OS X the Python code is compiled bytecode (pyc).
My guess is they are using a common library they have written then just have to use different hooks for the different platforms.
What method of development is this? It clearly isn't IronPython or PyObjC. This paradigm is so appealing to me, but my CS foo and Google foo are failing me.
Dropbox uses a combination of wxPython and PyObjC on the Mac (less wxPython in the 0.8 series). It looks like they've built a bit of a UI abstraction layer but nothing overwhelming—i.e., they're doing their cross-platform app the right way.
They include their own Python mainly because the versions of Python included on the Mac vary by OS version (and Dropbox supports back to 10.4 IIRC); also, they've customized the Python interpreter a bit to improve threading and I/O behavior.
(I do not work for Dropbox or have any inside knowledge; all I did was read their forums and examine the filenames in site-packages.zip in the Dropbox app bundle.)
For WINDOWS, Dropbox have employed a module similar to py2exe to package all their .py scripts, required libraries, resources etc into the distribution that you have mentioned above (.exe, library.zip, MS C runtime library and python25.dll) so that they can be run without requiring Python installation. Here's a sample code of how you can achieve this with py2exe.
from distutils.core import setup
import py2exe
options = {'py2exe': {
'compressed':1,
'bundle_files': 2,
'dll_excludes': ['w9xpopen.exe']
}}
setup(console=['myapp.py'],options=options)
Please see the tutorial here for more explanation.
PS: the number of files in the distribution can be controlled using the options parameter as shown in the above example.
These guys reverse engineered Dropbox client code
http://www.openwall.com/presentations/WOOT13-Security-Analysis-of-Dropbox/
https://github.com/kholia/dedrop
Indeed they do bundle their own Python 2.5.4 interpreter found at /Applications/Dropbox.app/Contents/MacOS/python. Poking around in /Applications/Dropbox.app/Contents/Resources/lib/python2.5/lib-dynload it looks to be bundled by PyObjC.
I'm no authority on this, but it seems it is exactly as you suggest in the OP:
My guess is they are using a common
library they have written then just
have to use different hooks for the
different platforms
Python25.dll is probably not their application code, it is a dll containing a copy of the python interpreter which can be called from within a windows application. Those pyc files are probably there in some form on windows, but they might be in an archive or obfuscated.
Python is included in OS/X, so it would be possible for them to execute those pyc file without shipping a python, but would not be surprised if they have there own python version lurking in the app bundle.
I don't know how dropbox builds there distributions, but there are several tools to bundle python apps into executable packages. Take a look at py2exe, py2app, and or cx_freeze.
Recently I published an article on reversing the dropbox client on windows. It is available on slideshare.
In short,
On Windows dropbox uses py2exe. py2exe embeds the python dll as a resource within the executable. The compiled python source files aka pyc files are stored as a zip archive appended to the end of the executable (which is called an overlay).
Extracting the zip archive will give you the pyc files, but that is not the end of the story.
The pyc files are encrypted and not decompilable. They are decrypted only when they are loaded by the embedded python interpreter.
However there is a way to not bother too much about the encryption algorithm used. We can
directly grab decrypted code objects from memory letting dropbox do the decryption for us.
Related
I have an application written in python, compiled to .exe with pyinstller that I would like to distribute with the installer NSIS.
Currently the installer unpacks to Program Files (x86) and creates desktop shortcuts, however does not write to registery. Having read some tutorials I see installers generally write a reference to the installed software to the windows registery, but it is not clear if this is always done. Is this really necessary? My app is standalone and I would like to avoid writing to registery if I can.
Any references for futher reading would be much appreciated as am having trouble finding much on this.
Writing to the registry is optional but if you are distributing your app in a installer instead of a zip file then it is pretty common to register your uninstaller so that it is displayed in the control panel.
The NSIS documentation tells you where and what to write.
I've successfully embedded Python in a multi-platform C++ project.
This required linking to a libpython, which needs to be provided for each platform I'm targeting. For OSX it was easy, I just pulled it out of some homebrew folder.
But I would like my Python scripts to use imports from the standard library (e.g. this one)
What is that going to involve?
Standard Library documentation for Python 3 says that the standard library is a mix of compiled units and .py files, so I'm expecting I will have to maybe link my project against a second library, and somehow inform the Python runtime of the location of the folder containing the standard library's .py files.
But is it really going to be this simple? Is this process documented anywhere?
Am I going to run into trouble on mobile platforms? It looks as though Kivy might be on their way towards solving this problem...
I'm trying to use Py2Exe to take a python program (using wxPython) to a Windows exe but there is an error regarding MSVCP90.dll . After reading py2exe fails to generate an executable on StackOverflow, it says I need to download this file. However, it also says all target users must download this file. This will be a huge inconvenience for my users (mostly corporate clients who will not know how to download the file), so is there a way to package the with the program?
Thanks!
What is MSVCP90.dll
MSVCP90.dll is Multithreaded, dynamic Visual Studio 2008 C Runtime Library. Generally your application should package MSVCP90.dll unless you are sure that the target machine have the matching CRT. You can use any of the packaging software to package the necessary DLLs and your software and distribute it.
Purpose of MSVCP90.dll
You may be wondering why you need this weird dll? Well CRT is nothing new to python. All application that is based on C heavily relies on C library functions. All the implementations of the standard C Library functions like (malloc, strcpy ..) to name a few is implemented in these libraries. There are different kinds and the specific MSDN website have more details on it.
Distributing MSVCP90.dll
When distributing CRT, you should understand that depending upon what CRT you have used the version number which is suffixed with the name of the CRT varies. For example MSVCP90.DLL is the CRT from Visual Studio 2008. A single machine can contain multiple CRTs either in the system folder on in application installation path.
If you are planning to package your application, you need to re-verify, which CRT version your application uses. Packaging wrong CRT or using one can cause undesired and undefined effect. Generally speaking the CRT your Python Installation uses, should be the same CRT you should package.
Determining the correct MSVCRT
As there are different CRT builds with different versions, it is difficult to ascertain, which CRT should be packaged. If you have a running application (executable), you can use dependencywalker to determine the correct version. Right click on any of the DLLs and click on properties and it will show you the location from which this DLL is being picked.
Packaging your application.
You can try using PyInstaller to package your application. It would be a convenient way to get the DLL into the target machine.
You have to deliver your app with that dll in same folder as your exe file.
I have writing a program using Java Processing.org programming language and it uses some python scripts. Circumstances exist that I cannot change or re write these python scripts in processing.
My problem is I need to bundle this all together and create software bundle for Mac OS X for easy installation. I know there is option in Processing IDE to create software bundles but that will ignores the python files, even so client's machine could not have python installed.
I thought about creating python executable and putting it in to the bundle. Could anyone suggest me better options or software tools to do this.
Regards,
Waruna
Python is shipped with Mac OS X, so your clients should be able to run the scripts.
You do not need to create a "Python executable" as the Python interpreter can just run the .py files.
A Mac OS X application bundle (essentially being a folder) contains a folder Contents which in turn contains the binary application files, resources, etc. You can place your .py files within the .app bundle and call them from within your Java code.
The bundle documentation is available here http://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html
It sounds like you're trying to deliver some Python modules in a user friendly manner (i.e., without the end users having to know about easy_install or whatever).
I am no expert in this area, but it seems to me like you're trying to solve a similar problem that the Mercurial people solved, you may want to have a look at what they did. This is how Mercurial is delivered on the Mac - http://mercurial.berkwood.com/.
I'm writing a Cocoa application that uses Python to perform some calculations and data manipulation. I've got an Objective-C class that I'm using to run the Python scripts via the Python API. I can currently call Python with no problem using the API and linking to Python.framework.
I'm looking at how to package the code together now. My understanding is that the python code would be included as part of the .app bundle, possibly in the Resources folder. I've run into py2app being discussed many places, but it appears to be only used if your app is written wholly in Python; I don't think this is the solution to my problem. How do I properly package the code with my app? Can I send the .pyc instead of the .py file?
You can use py2app to compile an NSBundle which can be loaded at runtime (you could add this loadable bundle to your app bundle's PlugIns/ folder). However, while initially quite easy to get working, there appears to be a bug in PyObjC or py2app that leads to significant memory leaks depending on the API of your plugin (see http://sourceforge.net/tracker/?func=detail&aid=1982104&group_id=14534&atid=114534).
The harder but safer approach is to link against the Python.framework. You can then keep your .py files in the app bundle's Resources/ directory and load them via the standard CPython embedding API.
Don't include only the .pyc files. The pyc format is an implementation detail that you shouldn't rely upon for future Python versions.