Tutorial: Compile Python to EXE

Posted: Monday 15 September 2014

Click here to skip to the decompiling py2exe section
Click here to skip to the compiling Python to EXE section
Questions? Comment Section Link Here


So we all know Python. Its a fun extension to the C language (Read: a language built on top of C). But one question, is, why can't we compile Python into an exe file, just like with C?

Now Python is an interesting language, in that it is both compiled and interpreted. In fact, there are many different implementations of the language. We have PyPy, on one hand, which does both, IronPython, which is basically a .NET compiler for Python, but the main focus is on CPython - Or what we all know as "Python". CPython is the "main reference implementation" of Python, and is the "Python" that is downloaded at https://www.python.org/.

It's weird to think that "Python" is not just Python, but makes sense considering the fact that Python is open source. A similar comparison between PyPy/IronPython and CPython can be made with JavaScript (js), where js is implemented not as "JavaScript", but as V8, spidermonkey, rhino and much more. We've come a long way from the monopoly that Microsoft has from their own programming languages, C#, VB.net and VBScript.

Decompiling py2exe

Click here to skip to the compiling Python to EXE section

But. Lets get to the grit of the post. The target version of Python that this post will be covering is Python 2.7, and the platform is for Windows (as redistributing binaries for Windows is much simple then with other OSes [in my opinion]), so YMMV.

py2exe can convert Python files to exe.

And.. Well.. It works...


Here's the process of converting of converting another one of my projects Download From HAR into an exe with py2exe.

No issue?

Well, you get this as a result (notice all of the dependencies, in particular "python27.dll" and the .pyd files)...

And... uh...

Guess what I found?

And so we take this section of binary code straight from py2exe's output:

And get this wonder...

Add this magic to the top of the file: 03F30D0ACB51145463 (actually, this isn't the real magic, nor does the modification date match the file, but you get the idea)

And eventually, upon decompiling this binary, you'll get the source file of the executable (though several changes must be made in order to convert py2exe's pyc format to CPython's pyc format)...

Which, of course, is unacceptable... Since, well, the source code isn't compiled into an exe, but more like compiled into bytecode, which is then converted into an exe; basically, your python code from your distributions are in plain sight.

Compiling Python to EXE

We're not interested in "converting" Python code to EXE under the guise of compilation. Try true compilation...

True compilation is where things start to get more serious. So if you're not prepared, or don't know a bit of basic C compilation, then stick a little bit with py2exe...

Cython is an application that converts Python code (or to be more precise, CPython code) into C. And from that point on, well... You can just compile it. No - seriously....

So just install Cython and run the following command (where init.py is the name of your chosen Python file).

REM Contents of build.bat:

SET ProgFiles86Root=%ProgramFiles(x86)%
IF NOT "%ProgFiles86Root%"=="" GOTO win64
SET ProgFiles86Root=%ProgramFiles%
cython init.py --embed
cl.exe /MT /nologo /Ox /W3 /GS- /DNDEBUG -I "%ProgFiles86Root%\Python27\include" -I "%ProgFiles86Root%\Python27\PC" /Tc init.c /link /OUT:"init.exe" /SUBSYSTEM:CONSOLE /MACHINE:X86 /LIBPATH:"%ProgFiles86Root%\Python27\libs" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib" /LIBPATH:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib"

Note that you do need Microsoft Visual Studio (Express) 2013 (or newer, just change a few paths in the script above), and the Windows 7 SDK (or newer, again just change a few paths around).

And that's it!

You've successfully compiled Python to exe through the use of Cython, where the Python code first gets converted into C and from there, is actually compiled to the exe.

And again, to see a proof of concept of using Cython to convert from Python source code (.py), to a Windows executable (.exe) have a look at: Download From HAR

To summarize:

  • Q: Is it possible to decompile py2exe programs?
  • Yes
  • Q: Can someone else easily steal your py2exe (and other Python "freezed" applications) source code?
  • Yes
  • Q: Can someone remake your py2exe application?
  • Yes, absolutely, someone can decompile your source code, change the copyright and credit messages, refreeze the application and pass it off as their own creation...
  • Q: Is there a more secure alternative to py2exe?
  • Yes, have a look at Cython
  • Q: Can Python code be converted into something other then py2exe/bytecode?
  • Yes, Cython converts .py code to .c directly.
    Effectively, this technique is actually a Python to C conversion, not exclusively a "Python to EXE" conversion, so it may work with other Operating Systems as well.