Jump to content
Korean Random

Как защитить *.pyc?


ggivi89

Recommended Posts

Начинаю тока вникать в питон! 
Задался вопросом как защитить файл скрипта! Перерыл весь интернет. единственное, что нашел это obfuscate-0.2.2.tar. Установить получилось, но как пользоваться я не понял так. И вообще то ли это вообще? Воопщем смысл один! Надо, чтоб не декомпилировался .*pyc

ДА и еще по теме: посоветуйте книги по python 2.7 для ракочайника

 

Edited by ggivi89
Link to comment
Short link
Share on other sites

как защитить файл скрипта!

Посмотрите в теме PjOrion'а, он вроде умеет обфусцировать скрипты.

Так же посмотрите Pyminifier - утилита с хорошей документацией, умеет сжимать и обфусцировать.

 

книги по python 2.7

Много их. Вот, например, на habrahabr.

 

чтоб не декомпилировался .*pyc

Декомпилировать можно всё что угодно. Всё зависит от усилий.

 

P.S. Защита интерпретируемых языков может сильно сказаться на производительности.

Edited by Azbuka_slovensko
  • Upvote 2
Link to comment
Short link
Share on other sites

Посмотрите в теме PjOrion'а, он вроде умеет обфусцировать скрипты.

Так же посмотрите Pyminifier - утилита с хорошей документацией, умеет сжимать и обфусцировать.

 

Много их. Вот, например, на habrahabr.

 

Декомпилировать можно всё что угодно. Всё зависит от усилий.

 

P.S. Защита интерпретируемых языков может сильно сказаться на производительности.

Спасибо огромное. Я просто декомпилил какой то мод там было так:  # Embedded file name: rfcheats Error: tuple index out of range. B PJ Orion закрыты эти функции... Да и я читаю книгу и примеры испытываю на обычном IDLE (Python GUI).

Обращался к Юше. сказал так: давай мод, я обфусцирую... Но я не согласился ); 

Edited by ggivi89
Link to comment
Short link
Share on other sites

 

 

Я просто декомпилил какой то мод

Декомпилировать получится мало - большая часть модификаций обфусцирована.

Лучше воспользуйтесь поиском на GitHub'е - там довольно много модификаций, и есть удобные фильтры поиска.

  • Upvote 1
Link to comment
Short link
Share on other sites

 

 

Что я не так делаю?

Его нужно запускать из командной строки (Win + R -> Ввести cmd -> Ок)

В открывшемся окне терминала нужно ввести:

python pyminifier <аргументы>

Путь к папке с python и pyminifier должен быть в PATH, иначе нужно указывать полные пути.

Можно, конечно, использовать pyminifier и из python, но для этого нужно ознакомиться с документацией

Link to comment
Short link
Share on other sites

Его нужно запускать из командной строки (Win + R -> Ввести cmd -> Ок)

В открывшемся окне терминала нужно ввести:

python pyminifier <аргументы>

Путь к папке с python и pyminifier должен быть в PATH, иначе нужно указывать полные пути.

Можно, конечно, использовать pyminifier и из python, но для этого нужно ознакомиться с документацией

примерно так: python pyminifier --obfuscate "C:\4321.py" ???

Link to comment
Short link
Share on other sites

ХМ наверно я что то не то делаю... Код декомпилируется как и прежде

Обфускатор запутывает код, заменяя имена переменных, функций, классов и т.д.

Вот пример из документации:

'Входной файл'

#!/usr/bin/env python
"""
tumult.py - Because everyone needs a little chaos every now and again.
"""

try:
    import demiurgic
except ImportError:
    print("Warning: You're not demiurgic. Actually, I think that's normal.")
try:
    import mystificate
except ImportError:
    print("Warning: Dark voodoo may be unreliable.")

# Globals
ATLAS = False # Nothing holds up the world by default

class Foo(object):
    """
    The Foo class is an abstract flabbergaster that when instantiated
    represents a discrete dextrogyratory inversion of a cattywompus
    octothorp.
    """
    def __init__(self, *args, **kwargs):
        """
        The initialization vector whereby the ineffiably obstreperous
        becomes paramount.
        """
        # TODO.  BTW: What happens if we remove that docstring? :)

    def demiurgic_mystificator(self, dactyl):
        """
        A vainglorious implementation of bedizenment.
        """
        inception = demiurgic.palpitation(dactyl) # Note the imported call
        demarcation = mystificate.dark_voodoo(inception)
        return demarcation

    def test(self, whatever):
        """
        This test method tests the test by testing your patience.
        """
        print(whatever)

if __name__ == "__main__":
    print("Forming...")
    f = Foo("epicaricacy", "perseverate")
    f.test("Codswallop")

'Выходной файл'

$ pyminifier --obfuscate /tmp/tumult.py
#!/usr/bin/env python
T=ImportError
q=print
m=False
O=object
try:
 import demiurgic
except T:
 q("Warning: You're not demiurgic. Actually, I think that's normal.")
try:
 import mystificate
except T:
 q("Warning: Dark voodoo may be unreliable.")
Q=m
class U(O):
 def __init__(self,*args,**kwargs):
  pass
 def B(self,dactyl):
  G=demiurgic.palpitation(dactyl)
  w=mystificate.dark_voodoo(G)
  return w
 def k(self,whatever):
  q(whatever)
if __name__=="__main__":
 q("Forming...")
 f=U("epicaricacy","perseverate")
 f.test("Codswallop")
# Created by pyminifier.py (https://github.com/liftoff/pyminifier

Совершенно очевидно, что выходной файл совершенно невозможно прочитать. Именно для этого и нужен обфускатор.

Для того, чтобы исключить декомпиляцию байт-кода используются коммерческие защитники, совмещающие обфускатор и компилятор защищённого байткода.

Edited by Azbuka_slovensko
  • Upvote 1
Link to comment
Short link
Share on other sites

 

 

Недекомпелируемым код сделать невозможно

Есть способы защиты, которые сводятся к тому, что для того, чтобы декомпилировать надо потратить.. год (на самый простой скрипт).

В целом - "недекомпилируемым кодом" можно назвать такой код, затраты на декомпиляцию которого больше чем затраты на создание с нуля оригинального кода (как человеко-часы, так и финансовые).

Для примера http://dropmefiles.com/dYmbg

Исходник:

print 'Hello World!'
LOAD_CONST 'Hello World!'
PRINT_ITEM
PRINT_NEWLINE
LOAD_CONST None
RETURN_VALUE

попытайся декомпилировать..;)

Можно назвать этот скрипт недекомпилируемым?

 

А некоторые защиты основываются на дозагрузке некоторой части скрипта (примерно как это реализовано в варпаке)..

  • Upvote 2
Link to comment
Short link
Share on other sites

А некоторые защиты основываются на дозагрузке некоторой части скрипта (примерно как это реализовано в варпаке)..

 

+ инжектирование скрипта не питон-методами (ассм,  си, делфи, ... инжектор). Что в реальности и составляет защиту как таковую.

 


@ggivi89, obfuscate-0.2.2.tar - это набор функций для шифрования текста на питоне, к защите или обфускации отношения почти не имеет. Pyminifier - обфусцирует пользовательские имена путем их замены на абракадабру. Это ни как не усложняет декомпиляцию, но вот разобраться в коде будет сложновато. В PjOrion я сейчас работаю над обфускацией и протекцией в ближайшее время буду вводить функциональность по частям. Если хочешь чтобы не декомпилировалось, то надо научиться скрамблировать pyc-скрипт. Это остановит тех, кто знает питон только на уровне правки чужих готовых модов, остальным это не помеха.

 

"Вот небольшой отрывок с моего поста о скрамблировании"

.....Я так понял ты пытался сделать скрамблер от дизассемблера, типа АСМ-петли с мусором внутри. Простой скрамблер сделать не сложно, но надо быть аккуратным с петлями и мусором в них, там главное что бы мусор не смещал точку входу в рабочую инструкцию. Инструкции бывают разной длины, есть те у кого два байта под параметры идет, а есть и больше. Если мусор интерпретируется как многобайтовая инструкция то она может сожрать точку входу.

 

Разберу пример:

 

1. Берем исходный код py-модуля:

 

import sys

s = sys.copyright

print s

 

Он же в dis.dis():

 

  1           0 LOAD_CONST               0 (-1)          0x64

              3 LOAD_CONST               1 (None)        0x64

              6 IMPORT_NAME              0 (sys)         0x6c

              9 STORE_NAME               0 (sys)         0x5a

  2          12 LOAD_NAME                0 (sys)         0x65

             15 LOAD_ATTR                1 (copyright)   0x6a

             18 STORE_NAME               2 (s)           0x5a

  3          21 LOAD_NAME                2 (s)           0x65

             24 PRINT_ITEM                               0x47

             25 PRINT_NEWLINE                            0x48

             26 LOAD_CONST               1 (None)        0x64

             29 RETURN_VALUE                             0x53

 

Он же в HxD программе:

 

64 00 00

64 01 00

6C 00 00

5A 00 00

65 00 00

6A 01 00

5A 02 00

65 02 00

47

48

64 01 00

53 28 02

 

2. Впихиваем в исходный код заготовки для АСМ-петель, например вот такие:

 

if False:

    a = 1

    b = 2

    c = 3

 

код такой заготовки имеет вид:

 

72 1B 00 64 00 00 5A 01 00 64 01 00 5A 02 00 64 02 00 5A 03 00 6E 00 00

 

Пихаем:

 

import sys

if False:

    a = 1

    b = 2

    c = 3

s = sys.copyright

if False:

    a = 1

    b = 2

    c = 3

print s

 

3. Теперь компилим и заполняем петлю мусором. Фокус тут в том, что не надо делать больших петель с огромными кусками мусора - это наоборот облегчает чистку кода, их видно очень хорошо, для блокировки ассмблера достаточно одного ложного кода в петле, но вот этих петель надо наставить побольше и разных - вот тогда чтоб их все убрать в большом исходнике нужно будет повозиться.

 

Имеем dis.dis код:

 

  1           0 LOAD_CONST               0 (-1)

              3 LOAD_CONST               1 (None)

              6 IMPORT_NAME              0 (sys)

              9 STORE_NAME               0 (sys)

  2          12 LOAD_NAME                1 (False)

             15 POP_JUMP_IF_FALSE       39             0x72

  3          18 LOAD_CONST               2 (1)

             21 STORE_NAME               2 (a)

  4          24 LOAD_CONST               3 (2)         ....

             27 STORE_NAME               3 (b)

  5          30 LOAD_CONST               4 (3)

             33 STORE_NAME               4 ©

             36 JUMP_FORWARD             0 (to 39)     0x6e

  6     >>   39 LOAD_NAME                0 (sys)

             42 LOAD_ATTR                5 (copyright)

             45 STORE_NAME               6 (s)

  7          48 LOAD_NAME                1 (False)

             51 POP_JUMP_IF_FALSE       75             0x72

  8          54 LOAD_CONST               2 (1)

             57 STORE_NAME               2 (a)

  9          60 LOAD_CONST               3 (2)

             63 STORE_NAME               3 (b)         ....

10           66 LOAD_CONST               4 (3)

             69 STORE_NAME               4 ©

             72 JUMP_FORWARD             0 (to 75)     0x6e

11     >>    75 LOAD_NAME                6 (s)

             78 PRINT_ITEM         

             79 PRINT_NEWLINE      

             80 LOAD_CONST               1 (None)

 

             83 RETURN_VALUE 

 

а в HxD редакторе вот такой код:

 

64 00 00 64 01 00 6C 00 00 5A 00 00 65 01 00 72 27 00 64 02 00 5A 02 00 64 03 00 5A 03 00 64 04 00 5A 04 00 6E 00 00 65 00 00 6A 05 00 5A 06 00 65 01 00 72 4B 00 64 02 00 5A 02 00 64 03 00 5A 03 00 64 04 00 5A 04 00 6E 00 00 65 06 00 47 48 64 01 00 53 28 05

 

Замусорим некоторые инструкции и их значения, например случайно увеличим/уменьшим на 1, но при этом последнюю инструкцию трогать не будем:

 

64 00 00 64 01 00 6C 00 00 5A 00 00 65 01 00 72 27 00 47 02 01 50 03 01 65 02 FF 5B 02 01 65 03 FF 50 05 00 6E 00 00 65 00 00 6A 05 00 5A 06 00 65 01 00 71 4B 00 64 03 00 5B 01 FF 63 02 01 5B 04 01 64 04 00 5A 04 00 6E 00 00 65 06 00 47 48 64 01 00 53 28 05

 

4. Чтобы петли было тяжелее отследить можно произвольно поменять некоторые джампы с 72 на 71:

JUMP_ABSOLUTE     - 0x71

POP_JUMP_IF_FALSE - 0x72

 

5. Смотрим результат, вот чего выдает dis.dis():

 

  1           0 LOAD_CONST               0 (-1)

              3 LOAD_CONST               1 (None)

              6 IMPORT_NAME              0 (sys)

              9 STORE_NAME               0 (sys)

  2          12 LOAD_NAME                1 (False)

             15 POP_JUMP_IF_FALSE       39

  3          18 PRINT_ITEM         

             19 ROT_TWO            

             20 POP_TOP            

             21 BREAK_LOOP         

             22 ROT_THREE          

             23 POP_TOP            

  4          24 LOAD_NAME            65282

Traceback (most recent call last):

  File "<pyshell#9>", line 1, in <module>

    dis.dis(code)

  File "C:\Python27\lib\dis.py", line 43, in dis

    disassemble(x)

  File "C:\Python27\lib\dis.py", line 97, in disassemble

    print '(' + co.co_names[oparg] + ')',

IndexError: tuple index out of range

 

А вот как выглядит код модуля dis.dis(XXX.co_code):

 

          0 LOAD_CONST          0 (0)

          3 LOAD_CONST          1 (1)

          6 IMPORT_NAME         0 (0)

          9 STORE_NAME          0 (0)

         12 LOAD_NAME           1 (1)

         15 POP_JUMP_IF_FALSE    39

         18 PRINT_ITEM    

         19 ROT_TWO       

         20 POP_TOP       

         21 BREAK_LOOP    

         22 ROT_THREE     

         23 POP_TOP       

         24 LOAD_NAME       65282 (65282)

         27 DELETE_NAME       258 (258)

         30 LOAD_NAME       65283 (65283)

         33 BREAK_LOOP    

         34 ROT_FOUR      

         35 STOP_CODE     

         36 JUMP_FORWARD        0 (to 39)

    >>   39 LOAD_NAME           0 (0)

         42 LOAD_ATTR           5 (5)

         45 STORE_NAME          6 (6)

         48 LOAD_NAME           1 (1)

         51 JUMP_ABSOLUTE       75

         54 LOAD_CONST          3 (3)

         57 DELETE_NAME     65281 (65281)

         60 DUP_TOPX          258

         63 DELETE_NAME       260 (260)

         66 LOAD_CONST          4 (4)

         69 STORE_NAME          4 (4)

         72 JUMP_FORWARD        0 (to 75)

    >>   75 LOAD_NAME           6 (6)

         78 PRINT_ITEM    

         79 PRINT_NEWLINE 

         80 LOAD_CONST          1 (1)

         83 RETURN_VALUE

 

---------------------------------------------------------------------------------------------------

 

Код на выходе будет работоспособен на 100%, а вот дизассемблер на нем загнется.........


 

 

 

Для примера http://dropmefiles.com/dYmbg

 

Это откуда? 

Edited by StranikS_Scan
  • Upvote 1
Link to comment
Short link
Share on other sites

https://github.com/0vercl0k/stuffz/blob/master/Python's%20internals/wildfire.py

но там ctypes используется (я потому и хотел в Орионе потестить немного). короче в танках этот способ защиты не применим :(

 

Глянул мельком - замена опкодов с расшифровкой на лету?

Link to comment
Short link
Share on other sites

  • 6 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...