qquick / opy Goto Github PK
View Code? Open in Web Editor NEWObfuscator for Python
License: Other
Obfuscator for Python
License: Other
1
I found opy will obfuscate some keywords like "open".
Hello,
I'm trying to use Opy on a rather large project and so far, it's the best available solution I've found. But I find the limitation about '#' characters that can only appear at the beginning of a string to be really annoying. There are a lot of such strings in the code I'm trying to obfuscate, and the project is a living one, so we'll have to remember to format all strings correctly or the obfuscation won't work. I also noticed that even if strings are not obfuscated, the limitation applies anyway, and a string containing a '#' not in the first position will cause invalid code to be generated.
Is there any chance that this limitation will go away one day? And also, would it be at least possible to detect the 'bad' string and make the obfuscation fail, instead of generating wrong code? On large projects, the full obfuscation can last for quite some time; finding out in the end that the results are unusable because we've forgotten a string containing a '#' somewhere is quite frustrating…
Thanks!
In opy_config.txt, I stated my module name as you suggested, and I wrote a usage function that prints out the usage when any invalid parameter given, in which I state the module name again.
However, while Opy obfuscates my script, the module name is reserved and this reservation makes the string ill-formed.
Python gets error running the ill-formed obfuscated script.
Is this a bug, or an intended behavior?
--Update
print("test.here #hey")
becomes
print("test.here
and these are fine
" '' "
' "" '
""" '' """
''' "" '''
A --help option would be quite nice for opy.
The last version in master branch does not define this variable (but it does use it).
Hi, I am very interested in this tool, however, some of its behavior is unexpected to me, likely because I don't fully understand how it works.
I have the following structure:
test.py:
from mylib import myFct
for obj in myFct():
if obj.prop == "val":
print("success")
mylib.py:
class Thing():
def __init__(self):
self.prop = "val"
def myFct():
return [Thing()]
opy_config:
obfuscate_strings = True
obfuscated_name_tail = '_opy_'
plain_marker = '_opy_'
pep8_comments = True
source_extensions = '''
py
pyx
'''
skip_extensions = '''
pyc
'''
skip_path_fragments = '''
opy.py
'''
external_modules = '''
mylib
'''
plain_files = '''
opy_config.txt
'''
plain_names = '''
opy
test
'''
The problem is that is still goes and modifies my mylib.py file (eg self.prop turned into self.l1ll_opy_):
# coding: UTF-8
import sys
l11l_opy_ = sys.l1l_opy_ [0] == 2
l11l1_opy_ = 2048
l1llll_opy_ = 7
def l1l11_opy_ (l111l_opy_):
global l11ll_opy_
l11_opy_ = ord (l111l_opy_ [-1])
ll_opy_ = l111l_opy_ [:-1]
l1l1_opy_ = l11_opy_ % len (ll_opy_)
l1ll1_opy_ = ll_opy_ [:l1l1_opy_] + ll_opy_ [l1l1_opy_:]
if l11l_opy_:
l1111_opy_ = l1_opy_ () .join ([l111_opy_ (ord (l1l1l_opy_) - l11l1_opy_ - (l1lll_opy_ + l11_opy_) % l1llll_opy_) for l1lll_opy_, l1l1l_opy_ in enumerate (l1ll1_opy_)])
else:
l1111_opy_ = str () .join ([chr (ord (l1l1l_opy_) - l11l1_opy_ - (l1lll_opy_ + l11_opy_) % l1llll_opy_) for l1lll_opy_, l1l1l_opy_ in enumerate (l1ll1_opy_)])
return eval (l1111_opy_)
class Thing():
def __init__(self):
self.l1ll_opy_ = l1l11_opy_ (u"ࠨࡶࡢࠥࠂ")
def myFct():
return [Thing()]
Is this the intended behavior?
Thanks for the help.
Hello,
I have this code (python 2.7) but I am not able to successfully obfuscate it. Any idea?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pprint import pprint
import sys
import getopt
argv=sys.argv[1:]
opts, args = getopt.getopt(argv, "hg:d")
print str(int(args[0])*2+int(args[1])*2)
Your code is already obfuscated!
Please, follow PEP8, and don't commit your .pyc.
Hi,
I have created a new OPY full of new features and highly obfuscated .. i would like to know what is your opinion ?!
Do you recommend merging my OPY2 with your OPY or i need to create a new OPY2 in my GitHub account .. It is my first time building something by using another person work as a base for my work ?!
I actually build my OPY2 based on the OPY from BuvinJT .. https://github.com/BuvinJT/Opy .. I don't know if it is you or he is a different person ?!!
Please advice .. What is the best way to publish my OPY2 !!
Thank you for this OPY
i have a python file that has the below commented BAD LINE ... i executed your OPY and it worked without errors but file execution failed
I only removed the quotation mark ( ' ) from the below commented BAD LINE ... and that caused the execution to succeed
BAD LINE:
# If the field has the first two bits equal to 1, it's a pointer
GOOD LINE:
# If the field has the first two bits equal to 1, it s a pointer
.
When trying to use a namedtuple the attributes are not matching up:
Original:
Arg = ntup('Arg','name nix gnu help default action',defaults=(None,)*6)
for arg in args:
parser.add_argument(arg.nix, arg.gnu, action='store', help=arg.help, default=arg.default)
Obfsucated:
l1l111l_opy_ = namedtuple(l1ll1ll_opy_ (u"ࠫࡆࡸࡧࠨࡩ"),l1ll1ll_opy_ (u"ࠬࡴࡡࡧࠣࡲࡾࠠࡨࡰࡸࠤࡱࠢࡧࡩࡧࡵࡶࠣࡥࡨࡺࡩࡰࡰࠪࡪ"),defaults=(None,)*6)
for arg in args:
parser.add_argument(arg.l11111l_opy_, arg.l1llll1l1_opy_, action=l1ll1ll_opy_ (u"ࠧࡴࡶࡲࡶࡪ࠭ࡺ"), help=arg.help, default=arg.default)
Result:
AttributeError: 'Arg' object has no attribute 'l11111l_opy_'
Hi there, your project is definetely useful, especially because it allows for obfuscation of module names.
I've spent few hours trying to make your program work with my (not too big) project, but gave up at the end. The problem is that I have to blacklist all external module names found like the following:
import module1
from module1 import class1
import module1.class2
... etc
After a lot of grepping and manual selection I succeeded, but found that the following also doesn't work:
from name1 import name2
name2.method()
Although blacklisting name1 and name2, method() is being obfuscated and thus does not work. I don't see an easy automated way to collect all those method()s
a) I think you could add automatic detection of project modules (not too difficult AFAIU) and exclude all external modules/namespaces from obfuscation.
b) Another solution is to obfuscate only those symbols which are NOT modules and o. modules by whitelist. Getting a whitelist of (project) modules is an easy task, even if done manually
Would be great obfuscation of numbers, they speaks. Are you considering this?
Thank you
Code to replicate the issue:
print("This is a very very very long string argument "
"splitted in two lines to demonstrate a bug")
or even:
s = ("This is a very very very long string argument "
"splitted in two lines to demonstrate a bug")
print(s)
This is valid Python code. After obfuscation, the code contains a syntax error:
File "../code_opy/test.py", line 18
l1l1lll1_opy_ (u"ࠨࡳࡱࡸࡹࡤࠡࡱࠤࡲࡵࡲࡦࠢࡳࡳࠣࡤ"))
^
SyntaxError: invalid syntax
The same happens putting "\" at the end of every line.
I have the from __future__ import absolute_import
in the python3 code.
Hello,
please, is there any way how to obfuscate content of string variables?
I would like to obfuscate only content of string variables (only variables, not functions, classes, etc) and other variables should be left untouched. Thank you!
myvariable1 = "should be obfuscated"
myvariable2 = 'should be obfuscated'
myvariable3 = glob.glob #should not be obfuscated
I have an issue when i import the module of tensorflow, outputing no file in the project.
I've a test.py script:
import tensorflow as tf with tf.Graph().as_default(): a = tf.constant('hello') sess = tf.Session() print(sess.run(a))
and i add 'tensorflow' in the parameter list of 'external_modules' in the opy_config.txt file.
Executing opy.py shows a warning 'WARNING:tensorflow:VARIABLES collection name is deprecated, please use GLOBAL_VARIABLES instead; VARIABLES will be removed after 2017-03-02.', but there is no file generated.
Thanks for you answering.
Hi,
I have multiple python modules which make a single page Javascript application by compilation using Transcrypt. Now I would like to obfuscate my code for commercial reasons. Is it possible to use Opy for this?
So preferred steps:
Is this possible?
(I didn't try it yet, but I will, and I guess it is good to have the question posted to help others)
Regards,
Pieter Jan
As the README comments, freedom in software is important. So, it may be appropriate to link to Richard Stallman's essays.
I need a way to toggle off the obfuscation of the key names for dictionaries. I have to pass dictionaries to functions that are imported and the names cannot change. As a workaround I am having to put all of the dictionaries into a plain text file.
some of the files in the directory can not be copied or obfuscated, and they are '.py' files. Their sub-directory is also ignored. What is the probably reason?
\folder
code.py
opy.py
opy_config.txt
\folder
\folder2
code.py
opy.py
opy_config.txt
both folder structures failed.
py3.5, win10 10586
In the folder_opy folder, the opy.py is obfuscated, but the code.py is the same as the original one
Sample program that produces error.
#!/usr/bin/python
problemstring = b''
problemstring2 = b'hello'
print( problemstring )
print( problemstring2 )
Generated code:
#!/usr/bin/python
# coding: UTF-8
import sys
l1111_opy_ = sys.version_info [0] == 2
l11l1_opy_ = 2048
l11l1l1_opy_ = 7
def l1l111l_opy_ (l111l1l_opy_):
global l11l11l_opy_
l1111ll_opy_ = ord (l111l1l_opy_ [-1])
l1llllll_opy_ = l111l1l_opy_ [:-1]
l111ll1_opy_ = l1111ll_opy_ % len (l1llllll_opy_)
l1ll11l_opy_ = l1llllll_opy_ [:l111ll1_opy_] + l1llllll_opy_ [l111ll1_opy_:]
if l1111_opy_:
l1lll111_opy_ = l1ll1ll_opy_ () .join ([l111l1_opy_ (ord (char) - l11l1_opy_ - (l1lll1_opy_ + l1111ll_opy_) % l11l1l1_opy_) for l1lll1_opy_, char in enumerate (l1ll11l_opy_)])
else:
l1lll111_opy_ = str () .join ([chr (ord (char) - l11l1_opy_ - (l1lll1_opy_ + l1111ll_opy_) % l11l1l1_opy_) for l1lll1_opy_, char in enumerate (l1ll11l_opy_)])
return eval (l1lll111_opy_)
l1l11l1l1_opy_ = l1llll1l_opy_ (u"ࠨࠩ")
l1l11l11l_opy_ = l1llll1l_opy_ (u"ࠩࡩࡱࡲࠨ")
print( l1l11l1l1_opy_ )
print( l1l11l11l_opy_ )
Error that occurs:
Traceback (most recent call last):
File "test.py", line 18, in <module>
l1l11l1l1_opy_ = l1llll1l_opy_ (u"ࠨࠩ")
NameError: name 'l1llll1l_opy_' is not defined
Is it an issue that I'm running opy.py and the above script using Python 3.5.2?
import l1llllll_opy
ModuleNotFoundError: No module named 'l1llllll_opy_'
File name of my .py is changes to l11l11lll_opy_.py, l11l11111_opy_.py, l11lll111_opy_.py and etc. I have 3 py files what is needs to be executed. How will I know which is it? Its been obfuscated. Any ideas?
I'm getting errors when I obfuscate strings that contain the # character.
This error happens both for single quoted strings and triple quoted strings:
type A: single quoted
DISCONNECTED_MESSAGE = u"Estás utilizando esTTela sin conexión a la red. Volviendo a intentar conectar en {} <a href='LINK'><font color=#ffffff>Reintentar</font></a>"
Becomes:
l1ll11lllll1l1_opy_ = u"Estás utilizando esTTela sin conexión a la red. Volviendo a intentar conectar en {} <a href='LINK'><font color=
Note that the quotes are not closed at the end of the string, therefore the obfuscated code fails with "SyntaxError: EOL while scanning string literal"
type B: triple quoted
message_link = """<a href='LINK'><font color=#ffffff>click acá</font></a>"""
Becomes:
message_link = """<a href='LINK'><font color=
This case is actually worse because it comments the rest of the code (though it is obfuscated).
I debugged opy trying to fix this, but I am miles away from the author in regEx knowledge. The issue arises in line 431 of opy.py:
normalContent = commentRegEx.sub (getCommentPlaceholderAndRegister, normalContent)
Up until that point, the comment is correctly loaded. There it is sliced.
I think the regEx that needs to be fixed is the one found in line 229 of opy.py:
commentRegEx = re.compile (r'{0}{1}{2}.*?$'.format ( r"(?<!')", r'(?<!")', r'#' ), re.MULTILINE)
What is the licence for the opy_config.txt file?
license_reference.txt
and opy.py
suggest Apache 2.0, but the opy_config.txt
file points to a (missing) www.qquick.org/licence.html
$ python3.7 -m opy -h
Opy (TM) Configurable Multi Module Python Obfuscator Version 1.1.29
Copyright (C) Geatec Engineering. License: Apache 2.0 at http://www.apache.org/licenses/LICENSE-2.0
/usr/bin/python3.7: No module named opy.__main__; 'opy' is a package and cannot be directly executed
I would like to use opy in some build scripts I am writing, but the fact that opy is deciding where to create its output is making things a bit harder. Can an option be added to specify an output directory instead of just storing in ../sourcedir_opy_
while in my code:
MySQLdb.connect( p1=xx, p2=xx)
and I added MySQLdb to external_modules
expected:
the p1 and p2 should be kept as original names.
actual:
python3 ../py_opy/x.py
Traceback (most recent call last):
File "../py_opy/x.py", line 26, in
, l1ll_opy_ = l1_opy_ (u"ࠪࡸࡪࡹࡴࠨࠆ")
File "/usr/lib64/python3.4/site-packages/MySQLdb/init.py", line 86, in Connect
return Connection(*args, **kwargs)
File "/usr/lib64/python3.4/site-packages/MySQLdb/connections.py", line 204, in init
super(Connection, self).init(*args, **kwargs2)
TypeError: 'l1l1l_opy_' is an invalid keyword argument for this function
the codes as below:
import MySQLdb
if __name__ == '__main__':
MySQLdb.connect( host = '127.0.0.1'
, port = 3306
, user = 'test'
, passwd = 'test'
, db = 'test'
, charset = 'utf8'
, use_unicode = True
, sql_mode = 'test'
)
I have another issue with the tool that may again come from a certain misunderstanding.
This time, it requires flash to me installed on the computer.
I've a test.py script:
from flask import Flask
proxy = Flask(__name__)
proxy.run(host='0.0.0.0', port=5000, debug=True, threaded=True)
And my opy_config.txt file
obfuscate_strings = True
obfuscated_name_tail = '_opy_'
plain_marker = '_opy_'
pep8_comments = True
source_extensions = '''
py
pyx
'''
skip_extensions = '''
pyc
'''
skip_path_fragments = '''
opy.py
'''
external_modules = '''
flask
'''
plain_files = '''
opy_config.txt
'''
plain_names = '''
opy
test
'''
The result is the following:
# coding: UTF-8
import sys
l1l1_opy_ = sys.version_info [0] == 2
l11ll_opy_ = 2048
l1l_opy_ = 7
def l1l11_opy_ (l111_opy_):
global l111l_opy_
l1lll_opy_ = ord (l111_opy_ [-1])
l1ll_opy_ = l111_opy_ [:-1]
l11l_opy_ = l1lll_opy_ % len (l1ll_opy_)
l11_opy_ = l1ll_opy_ [:l11l_opy_] + l1ll_opy_ [l11l_opy_:]
if l1l1_opy_:
l1l1l_opy_ = l11l1_opy_ () .join ([l1_opy_ (ord (char) - l11ll_opy_ - (l1ll1_opy_ + l1lll_opy_) % l1l_opy_) for l1ll1_opy_, char in enumerate (l11_opy_)])
else:
l1l1l_opy_ = str () .join ([chr (ord (char) - l11ll_opy_ - (l1ll1_opy_ + l1lll_opy_) % l1l_opy_) for l1ll1_opy_, char in enumerate (l11_opy_)])
return eval (l1l1l_opy_)
from flask import Flask
proxy = Flask(__name__)
proxy.run(host=l1l11_opy_ (u"ࠫ࠵࠴࠰࠲࠱࠴ࠬࠀ"), port=5000, debug=True, ll_opy_=True)
The interesting part is the change from:
proxy.run(host='0.0.0.0', port=5000, debug=True, threaded=True)
to:
proxy.run(host=l1l11_opy_ (u"ࠫ࠵࠴࠰࠲࠱࠴ࠬࠀ"), port=5000, debug=True, ll_opy_=True)
Checkout https://github.com/pallets/flask/blob/master/flask/app.py def run
line 840. It looks like opy knows not to rename the host
, port
and debug
keywords before of the fonction declaration def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
. But to me it's an issue that the threaded
keyword is renamed.
I am again wondering if this is the intended behavior and if I'm missing something here.
Thank you
C:\Windows\system32>pip install Opy
Collecting Opy
Using cached Opy-1.1.27.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\user\AppData\Local\Temp\pip-build-864qjt_y\Opy\setup.py", line 18, in <module>
read ('README.rst') + '\n\n' +
File "C:\Users\user\AppData\Local\Temp\pip-build-864qjt_y\Opy\setup.py", line 11, in read
return aFile.read()
UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 3715: illegal multibyte sequence
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\user\AppData\Local\Temp\pip-build-864qjt_y\Opy\
#__pragma__ ('noanno')
is obfuscated to
#__pragma__ (l1l1lll1_opy_ (u"࠭ࡰࡣࡱࡲࡴ࠭ੱ"))
How can I prevent it from obfuscation? _ _ pragma _ _ is compiler sensitive command, and it causes an error if obfuscated.
By the way, thank you for building this useful tool too. I was looking for a useful Python obfuscator for a long time. I will be really happy if this tool works for my source code.
When I try to execute OPY I get this error:
" File "opy.py", line 349
exec (
SyntaxError: unqualified exec is not allowed in function 'init' it is a nested function"
Thank you from Spain.
I'm sorry but I can't understand how I'm supposed to use your obfuscator.
I had opy.py and the config in a directory with a script I want to obfuscate.
What now? You said "run opy.py" but that doesn't work and I can't see a specification of which .py file it is meant to target etc.
Thanks
In the pre-release version, skip_path_fragments in opy_config.txt doesn't work.
It seems that it is not used in opy.py.
I'm using the latest version of Pycharm and I'm getting this error when I debug opy.py:
C:/Users/Dev5/Documents/myProject/opy.py:360: RuntimeWarning: tp_compare didn't return -1 or -2 for exception
For some reason, this hangs the execution. The error comes from the check:
if anObject in externalObjects:
return
in the addExternalNames function. A simple way to fix this is to check in the function if the argument is Hashable. If it is not, then it shouldn't be in externalObjects so I return.
def addExternalNames(anObject):
if isinstance(anObject, collections.Hashable):
return
if anObject in externalObjects:
return
I don't know why this bug exists though and this is simply a patch to avoid something that shouldn't happen in the first place.
I am creating a demo for python obfuscation and packaging for Windows 10 64bit and the process hangs with high cpu usage
To workaround I had to kill the process externally:
https://github.com/vkhazin/python-obfuscate/blob/master/package.ps1#L24
PS C:\Users\vladi\Projects\packaged> python --version
Python 3.7.8
opy-distbuilder 0.9.1.1
After running overnight, technically it not hanging, but takes over 25min for a hello world project and fails with an error at the end:
Traceback (most recent call last):
File ".\env\Lib\site-packages\opy/opy.py", line 602, in
targetFile.write (content)
File "C:\Users\vladi\AppData\Local\Programs\Python\Python37\lib\codecs.py", line 721, in write
return self.writer.write(data)
File "C:\Users\vladi\AppData\Local\Programs\Python\Python37\lib\codecs.py", line 377, in write
data, consumed = self.encode(object, self.errors)
UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' in position 149234: surrogates not allowed
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.