closed source

David Bolen db3l at fitlinxx.com
Thu Oct 23 17:59:48 EDT 2003


Milos Prudek <milos.prudek at tiscali.cz> writes:

> This will not protect against illegal copying, however. Let's say that
> I need to create a program that could be downloaded as a demo, with
> activation code sent to people who purchase the software. This code
> could be generated by a small C program that creates a hash of the
> purchaser's hardware config. Inside the main Python program there
> would be an extension written in C that would check the activation
> code against the purchaser's hardware.
> 
> The idea here is that C is much harder to decompile than Python.

Definitely true - I think anything that does a native compilation is
much harder to decompile into usable information (but clearly not
impossible) simply because the compiled form is much further removed
from the original source.

But while your suggested approach would work in terms of making it
harder for the user to expose the actual authentication mechanism, it
might not make it much harder to avoid the authentication entirely.
Don't forget that it would only increase security to the extent of how
you use that module, since you basically just push the problem up a
level higher.  Given the above approach, if I wanted to crack it, I
would just decompile the main Python program, and remove the call to
the C extension module, replacing it instead with appropriate code to
make it seem like the extension module call succeeded.

So in the end, as long as there's any interpreted code that is in
control of the authentication, you might not be any better off, so why
expend the effort in the first place.  I think this is largely true
for any interpreted language.

I suppose you could choose to make your main entry point into C code,
only handing control to the Python interpreter after validation.  The
model could be close to how Python packaging tools such as Gordan
McMillan's installer works, since the main entry point is as an
executable, and it sets up things (including the installer's import
hooks) before handing control over to the interpreter.  But of course,
unless you obfuscate how the files are packaged together, access to
the original source would still be provided and someone ingenious
enough could just find a way to skip over the startup code.

Having thought about this myself in the past, if I absolutely had to
try to cover all but the most persistent folks, I'd probably try an
approach that encrypted my pyc files, and required a custom importer
to decrypt them on import.  I'd use something similar to your
extension module idea (agreeing that native code is a bit more
resistent to effective decompilation).  But the extension module would
do more than just validation.  That is, when supplied with an
appropriate message (perhaps encrypted with a public key to match a
compiled in private key or something), it wouldn't just say yes/no,
but would, if ok, also establish itself as an import hook in the
system.  When the application modules would get imported they would
automatically be decrypted.  Since all of the key management and
encryption/decryption was in the extension module it would be a little
more secure against tampering.  And since the extension module was
needed for imports but only provided an import hook when given a valid
key, it would be harder to work around by just manipulating the Python
code using the module.

I still have a feeling there would be a way to extract the modules in
an unencrypted form by someone with a working key (since once imported
the objects exist in memory, but I'm not sure how easy it would be to
regenerated marshalled bytecode files) but it should be limited to
someone starting with a working application, and then probably a
fairly persistent and knowledgeable person.  The only place the
original source would exist unencrypted would be in the running
application.

I suppose if I made the authentication/import hook module into the
application entry point I might help close that loophole a bit tighter
as well.  Might be an interesting experiment.

This would entail a reasonably amount of extra effort though, so I'd
probably look for other non-technical solutions first before falling back
on something like this.

-- David




More information about the Python-list mailing list