ily is an obfuscator for Python scripts.
f0rK 63ca451e44 i love markdown | 2 weken geleden | |
---|---|---|
examples | 2 weken geleden | |
README.md | 2 weken geleden | |
obfuscator.py | 2 weken geleden |
./obfuscator.py <obfuscations> <filename>
<obfuscations>
- string, containing a sequence of obfuscations to apply left-to-right.
<filename>
- filename of the program to obfuscate.
ily will output the obfuscated result to STDOUT.
Obfuscation character: i
Obfuscation safety: Safe
This obfuscation replaces every integer constant with a sum of random integers:
def mult_by_5(x):
return 5 * x
print(mult_by_5(10))
def mult_by_5(x):
return (--16 + -171 + -313 + -173 + --15 + -685 + --1316) * x
print(mult_by_5(-993 + -306 + --77 + --794 + -105 + -667 + --29 + -911 + --67 + --2025))
Obfuscation character: s
Obfuscation safety: Safe
This obfuscation replaces every string constant with a sum of chr()
calls:
print("Hello, world!")
print(chr(72) + chr(101) + chr(108) + chr(108) + chr(111) + chr(44) + chr(32) + chr(119) + chr(111) + chr(114) + chr(108) + chr(100) + chr(33))
Obfuscation character: m
Obfuscation safety: Safe
Wraps imports inside an exec()
call in order to be further obfuscated by some other obfuscation (like StringInflationObfuscation)
import random
print(random.randint(10, 20))
exec('import random')
print(random.randint(10, 20))
Obfuscation character: v
Obfuscation safety: Relatively safe
This obfuscation replaces all top-level names (including import
's and from a import b
's, in the second case b
will be obfuscated) with gibberish.
NOTE: This obfuscation does not obfuscate class methods and attributes (Nested classes are not obfuscated at all), since it is impossible to determine the type of an expression without running the program, thus making it impossible to figure out whether the attriubute name should be obfuscated or not.
class SomeClass:
def __init__(self, a, b):
self.a = a
self.b = b
def get_a(self):
return self.a
def get_b(self):
return self.b
def some_func():
alpha = 13
beta = 37
return str(alpha) + str(beta)
print(SomeClass(2, 3).get_a())
print(SomeClass(5, 6).get_b())
print(some_func())
class WIQXJMIUJSUJKNFKN:
def __init__(PWRXDSUBTGVWFO, DJMCCKOVVCJ, UWTDMFEB):
PWRXDSUBTGVWFO.a = DJMCCKOVVCJ
PWRXDSUBTGVWFO.b = UWTDMFEB
def get_a(PWRXDSUBTGVWFO):
return PWRXDSUBTGVWFO.a
def get_b(PWRXDSUBTGVWFO):
return PWRXDSUBTGVWFO.b
def MICWCKPPQMNYYHUARS():
SPMTLGTUGXLOAVRQIJKK = 13
PHQOLPIOECPKWOYYQPIL = 37
return str(SPMTLGTUGXLOAVRQIJKK) + str(PHQOLPIOECPKWOYYQPIL)
print(WIQXJMIUJSUJKNFKN(2, 3).get_a())
print(WIQXJMIUJSUJKNFKN(5, 6).get_b())
print(MICWCKPPQMNYYHUARS())
Obfuscation character: a
Obfuscation safety: Relatively unsafe (Not tested much)
This obfuscation replaces attribute accesses with getattr()
and setattr()
where applicable:
import random
import string
class RandomStringBuilder:
def __init__(self, length):
self.length = length
def build_random_string(self):
return "".join([random.choice(string.ascii_letters) for i in range(self.length)])
print(RandomStringBuilder(13).build_random_string())
import random
import string
class RandomStringBuilder:
def __init__(self, length):
setattr(self, 'length', length)
def build_random_string(self):
return getattr('', 'join')([getattr(random, 'choice')(getattr(string, 'ascii_letters')) for i in range(getattr(self, 'length'))])
print(getattr(RandomStringBuilder(13), 'build_random_string')())
Obfuscation character: b
Obfuscation safety: Relatively unsafe (Not tested much)
This obfuscation wraps all built-ins in builtins.
, for example: range
turns into builtins.range
. It also wraps True
, False
and None
into builtins.getattr(builtins, 'True')
, builtins.getattr(builtins, 'False')
and builtins.getattr(builtins, 'None')
respectively.
NOTE: This obfuscation breaks if user code has redefined built-in names. For example, if the program has a def input()
or a def hash(x)
, this obfuscation won't work properly.
def EncodeNegBase(n, b): #Converts from decimal
if n == 0:
return "0"
out = []
while n != 0:
n, rem = divmod(n, b)
if rem < 0:
n += 1
rem -= b
out.append(rem)
return "".join(map(str, out[::-1]))
def DecodeNegBase(nstr, b): #Converts to decimal
if nstr == "0":
return 0
total = 0
for i, ch in enumerate(nstr[::-1]):
total += int(ch) * b**i
return total
if __name__=="__main__":
print ("Encode 10 as negabinary (expect 11110)")
result = EncodeNegBase(10, -2)
print (result)
if DecodeNegBase(result, -2) == 10: print ("Converted back to decimal")
else: print ("Error converting back to decimal")
print ("Encode 146 as negaternary (expect 21102)")
result = EncodeNegBase(146, -3)
print (result)
if DecodeNegBase(result, -3) == 146: print ("Converted back to decimal")
else: print ("Error converting back to decimal")
print ("Encode 15 as negadecimal (expect 195)")
result = EncodeNegBase(15, -10)
print (result)
if DecodeNegBase(result, -10) == 15: print ("Converted back to decimal")
else: print ("Error converting back to decimal")
import builtins
def EncodeNegBase(n, b):
if n == 0:
return '0'
out = []
while n != 0:
n, rem = builtins.divmod(n, b)
if rem < 0:
n += 1
rem -= b
out.append(rem)
return ''.join(builtins.map(builtins.str, out[::-1]))
def DecodeNegBase(nstr, b):
if nstr == '0':
return 0
total = 0
for i, ch in builtins.enumerate(nstr[::-1]):
total += builtins.int(ch) * b ** i
return total
if __name__ == '__main__':
builtins.print('Encode 10 as negabinary (expect 11110)')
result = EncodeNegBase(10, -2)
builtins.print(result)
if DecodeNegBase(result, -2) == 10:
builtins.print('Converted back to decimal')
else:
builtins.print('Error converting back to decimal')
builtins.print('Encode 146 as negaternary (expect 21102)')
result = EncodeNegBase(146, -3)
builtins.print(result)
if DecodeNegBase(result, -3) == 146:
builtins.print('Converted back to decimal')
else:
builtins.print('Error converting back to decimal')
builtins.print('Encode 15 as negadecimal (expect 195)')
result = EncodeNegBase(15, -10)
builtins.print(result)
if DecodeNegBase(result, -10) == 15:
builtins.print('Converted back to decimal')
else:
builtins.print('Error converting back to decimal')
Q: Why even make a Python obfuscator, if readabilty is Python's big thing?
A: I was bored.
Q: Is this safe to use commercially?
A: If you are brave enough, but most likely no. I don't recommend this.
Q: Feature <insert feature name here> is not supported. Will you update ily to support it?
A: Probably not, unless it is extensively used.
Q: What does ily stand for?
A: It stands for I love you, thank you for asking :)