Андрей Светлов
Под сложностью понимаю то, что нужно будет изрядно потрудиться (создавая свой пропатченый pythonXX.dll, как в вашем варианте). Возня немалая, и, будете смеяться, большинству программистов такое будет либо не по силам, либо просто лень (лень чаще, конечго же).
Я - не профессионал, но это заняло у меня 14 минут (включая чтение кода, правку и компиляцию):
michael@michael:~/work/patches/python-2.5.1$ cat a.py
def foo():
print ‘hello, world!’
michael@michael:~/work/patches/python-2.5.1$ hexdump -C a.pyc
00000000 6d f2 0d 0a 6e fa c2 46 63 00 00 00 00 00 00 00 |m…n..Fc…….|
00000010 00 01 00 00 00 40 00 00 00 73 0d 00 00 00 64 00 |…..@…s….d.|
00000020 00 84 00 00 5a 00 00 64 01 00 53 28 02 00 00 00 |….Z..d..S(….|
00000030 63 00 00 00 00 00 00 00 00 01 00 00 00 43 00 00 |c…………C..|
00000040 00 73 09 00 00 00 64 01 00 47 48 64 00 00 53 28 |.s….d..GHd..S(|
00000050 02 00 00 00 4e 73 0d 00 00 00 68 65 6c 6c 6f 2c |….Ns….hello,|
00000060 20 77 6f 72 6c 64 21 28 00 00 00 00 28 00 00 00 | world!(….(…|
00000070 00 28 00 00 00 00 28 00 00 00 00 74 04 00 00 00 |.(….(….t….|
00000080 61 2e 70 79 74 03 00 00 00 66 6f 6f 01 00 00 00 |a.pyt….foo….|
00000090 73 02 00 00 00 00 01 4e 28 01 00 00 00 52 01 00 |s……N(….R..|
000000a0 00 00 28 01 00 00 00 52 01 00 00 00 28 00 00 00 |..(….R….(…|
000000b0 00 28 00 00 00 00 52 00 00 00 00 74 01 00 00 00 |.(….R….t….|
000000c0 3f 01 00 00 00 73 00 00 00 00 |?….s….|
Теперь пакуем все в ZIP для py2exe, далее zipimporter будет инициализировать модули, а мы уже вставили fprintf()ы в marshal.c. результат для ZIP с вызовом “import a”:
PyMarshal_ReadObjectFromString: len = 200
0000 | 63 00 00 00 00 00 00 00 00 01 00 00 00 40 00 00
0010 | 00 73 0d 00 00 00 64 00 00 7c 00 00 5a 00 00 64
0020 | 01 00 53 28 02 00 00 00 63 00 00 00 00 00 00 00
0030 | 00 01 00 00 00 43 00 00 00 73 09 00 00 00 64 01
0040 | 00 47 48 64 00 00 53 28 02 00 00 00 4e 73 0d 00
0050 | 00 00 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 28
0060 | 00 00 00 00 28 00 00 00 00 28 00 00 00 00 28 00
0070 | 00 00 00 73 04 00 00 00 61 2e 70 79 74 03 00 00
0080 | 00 66 6f 6f 01 00 00 00 73 02 00 00 00 00 01 4e
0090 | 28 01 00 00 00 52 00 00 00 00 28 00 00 00 00 28
00a0 | 00 00 00 00 28 00 00 00 00 73 04 00 00 00 61 2e
00b0 | 70 79 73 08 00 00 00 3c 6d 6f 64 75 6c 65 3e 01
00c0 | 00 00 00 73 00 00 00 00
Как видим, это и есть тот самый a.pyc без заголовка (8 bytes). Вот и все.
Андрей Светлов
Дальше. Питоновский код после дизассемблера не очень-то похож на исходники. Читать его не очень легко. Но - можно. Можно в результате кропотливого труда и все исходники воспроизвести.
Тут слегка патченый decompyle (a вообще-то, если лень возиться, платная служба есть в сети - всё сделают за вас)
michael@michael:~/work/patches/tmp$ decompyle a.pyc
Wed Aug 15 21:09:01 2007
# emacs-mode: -*- python-*-
def foo():
print ‘hello, world!’
# local variables:
# tab-width: 4
+++ okay decompyling a.pyc 7
decompyled 1 files: 1 okay, 0 failed, 0 verify failed
Wed Aug 15 21:09:01 2007
Совсем как настоящий :) Я уже попробовал и на более серьезных проектах - все работает.
Так что по поводу “изрядно потрудиться” и “кропотливого труда”, как то не согласуется с четвертью часа. Согласитесь?
Я ведь почему начал интересоваться и нашел ваш сайт через googlе: хочется попробовать перевести один небольшой коммерческий проект на python, чтобы оценить плюсы и минусы (и немножко отдохнуть от C++ :) ). Может быть посоветуете какой-нибудь более надежный метод защиты исходного текста (кроме перехода на open-source, лицензионных ограничений и т.п.)?