Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Numbers obfuscation in Python

Delimitry
December 20, 2017

Numbers obfuscation in Python

The presentation from SPbPython community / PiterPy meetup.
The presentation tells about one idea how it is possible to perform an obfuscation of numbers in Python.

Delimitry

December 20, 2017
Tweet

More Decks by Delimitry

Other Decks in Programming

Transcript

  1. Types comparison >>> {} > [] # i.e. 'd' >

    'l' ([d]ict > [l]ist) False >>> [] > {} # i.e. 'l' > 'd' ([l]ist > [d]ict) True Python 2 only! CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.
  2. Fixed in Python 3 >>> {} > [] Traceback (most

    recent call last): File "<stdin>", line 1, in <module> TypeError: '>' not supported between instances of 'dict' and 'list' Let's use the following approach in Python 3: >>> [] < [] False
  3. True and False As bool type inherits from int, bool

    values explicitly considered as integer, it's possible to get 0 and 1 from False and True. >>> False == 0 True >>> True == 1 True NB: In Python 2 it is possible to reassign True and False. In Python 3 True and False are keywords and always equal to 1 and 0.
  4. Numbers Other numbers can be obtained by applying logical operations

    E.g. "~" = bitwise NOT, or "<<" bitwise left shift. For example 2: 2 = -(-2) = -(~1) >>> 2 == -(-2) == -(~1) True
  5. Numbers (Python 2) nums = [ '([]<{})', # 0 '([]>{})',

    # 1 '-~([]>{})', # 2 '-~-~([]>{})', # 3 '-~-~-~([]>{})', # 4 '-~-~-~-~([]>{})', # 5 '-~-~-~-~-~([]>{})', # 6 '-~-~-~-~-~-~([]>{})', # 7 '-~-~-~-~-~-~-~([]>{})', # 8 '~-~([]>{})*~-~([]>{})', # 9 '~-~-~-~([]>{})*~([]>{})', # 10 '-~-~(~-~([]>{})*~-~([]>{}))', # 11 '(-~-~([]>{})<<-~([]>{}))', # 12 '-~(-~-~([]>{})<<-~([]>{}))', # 13 '-~-~-~-~-~-~([]>{})*-~([]>{})', # 14 '~-~([]>{})*~-~-~-~([]>{})', # 15 '(-~([]>{})<<-~-~([]>{}))', # 16 ] numbers_count = len(nums) - 1
  6. Numbers (Python 3) nums = [ '([]<[])', # 0 '(-~([]<[]))',

    # 1 '-~(-~([]<[]))', # 2 '-~-~(-~([]<[]))', # 3 '-~-~-~(-~([]<[]))', # 4 '-~-~-~-~(-~([]<[]))', # 5 '-~-~-~-~-~(-~([]<[]))', # 6 '-~-~-~-~-~-~(-~([]<[]))', # 7 '-~-~-~-~-~-~-~(-~([]<[]))', # 8 '~-~(-~([]<[]))*~-~(-~([]<[]))', # 9 '~-~-~-~(-~([]<[]))*~(-~([]<[]))', # 10 '-~-~(~-~(-~([]<[]))*~-~(-~([]<[])))', # 11 '(-~-~(-~([]<[]))<<-~(-~([]<[])))', # 12 '-~(-~-~(-~([]<[]))<<-~(-~([]<[])))', # 13 '-~-~-~-~-~-~(-~([]<[]))*-~(-~([]<[]))', # 14 '~-~(-~([]<[]))*~-~-~-~(-~([]<[]))', # 15 '(-~(-~([]<[]))<<-~-~(-~([]<[])))', # 16 ] numbers_count = len(nums) - 1
  7. Converting numbers Let’s take 16 as a base (i.e. hexadecimal

    numeral system) therefore each decimal number can be obtained by sum of multiplications of each decimal digit of a number by 16. Example: 17 = (16+1) 42 = (2*16+10) 123 = (7*16+11) 1000 = ((3*16+14)*16+8)
  8. Converting numbers def get_number(num): r = '' if num >

    numbers_count: if num // numbers_count > 1: if num % numbers_count == 0: r += '(%s*%s)' % (get_number(num // numbers_count), numbers_count) else: r += '(%s*%s+%s)' % (get_number(num // numbers_count), numbers_count, num % numbers_count) else: r += '(%s+%s)' % (numbers_count, get_number(num - numbers_count)) else: r = '%s' % num return r def convert_nums(s): res = s for n in range(numbers_count, -1, -1): res = res.replace(str(n), nums[n]) res = res.replace('+-', '-') return res
  9. Examples num = 1234567 num_str = get_number(num) num_str = num_str[1:-1]

    if num_str[0] == '(' and num_str[-1] == ')' else num_str print(num_str) # ((((16+2)*16+13)*16+6)*16+8)*16+7 obfuscated = convert_nums(num_str) print(obfuscated) #(((((-~([]>{})<<-~-~([]>{}))-~([]>{}))*(-~([]>{})<<-~-~([]>{}))-~(-~-~([]>{})<<-~([]>{}))) *(-~([]>{})<<-~-~([]>{}))-~-~-~-~-~([]>{}))*(-~([]>{})<<-~-~([]>{}))-~-~-~-~-~-~-~([]>{}))* (-~([]>{})<<-~-~([]>{}))-~-~-~-~-~-~([]>{}) print(eval(obfuscated)) # 1234567
  10. Examples Python 2: 1234567 = ((((16+2)*16+13)*16+6)*16+8)*16+7 = (((((-~([]>{})<<-~-~([]>{}))-~([]>{}))*(-~([]>{})<<-~-~([]>{}))-~(-~-~([]>{})<<-~([]>{})))* (-~([]>{})<<-~-~([]>{}))-~-~-~-~-~([]>{}))*(-~([]>{})<<-~-~([]>{}))-~-~-~-~-~-~-~([]>{}))*( -~([]>{})<<-~-~([]>{}))-~-~-~-~-~-~([]>{})

    Python 3: 1234567 = ((((16+2)*16+13)*16+6)*16+8)*16+7 = (((((-~(-~([]<[]))<<-~-~(-~([]<[])))-~(-~([]<[])))*(-~(-~([]<[]))<<-~-~(-~([]<[])))-~(-~-~( -~([]<[]))<<-~(-~([]<[]))))*(-~(-~([]<[]))<<-~-~(-~([]<[])))-~-~-~-~-~(-~([]<[])))*(-~(-~([ ]<[]))<<-~-~(-~([]<[])))-~-~-~-~-~-~-~(-~([]<[])))*(-~(-~([]<[]))<<-~-~(-~([]<[])))-~-~-~-~ -~-~(-~([]<[]))
  11. Other examples Negative numbers: change the sign in front of

    the parentheses Possible errors for huge numbers :( Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 8, in get_number ... File "<stdin>", line 3, in get_number RecursionError: maximum recursion depth exceeded in comparison _push: parser stack overflow Traceback (most recent call last): File "obfuscation.py", line 51, in print(eval(obfuscated)) MemoryError