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. Numbers obfuscation
    in Python
    Dmitry Alimov
    2017

    View Slide

  2. 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.

    View Slide

  3. Fixed in Python 3
    >>> {} > []
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: '>' not supported between instances of 'dict' and 'list'
    Let's use the following approach in Python 3:
    >>> [] < []
    False

    View Slide

  4. 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.

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide

  7. 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

    View Slide

  8. 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)

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. 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 =
    (((((-~(-~([]<[]))<<-~-~(-~([]<[])))-~(-~([]<[])))*(-~(-~([]<[]))<<-~-~(-~([]<[])))-~(-~-~(
    -~([]<[]))<<-~(-~([]<[]))))*(-~(-~([]<[]))<<-~-~(-~([]<[])))-~-~-~-~-~(-~([]<[])))*(-~(-~([
    ]<[]))<<-~-~(-~([]<[])))-~-~-~-~-~-~-~(-~([]<[])))*(-~(-~([]<[]))<<-~-~(-~([]<[])))-~-~-~-~
    -~-~(-~([]<[]))

    View Slide

  12. Other examples
    Negative numbers: change the sign in front of the parentheses
    Possible errors for huge numbers :(
    Traceback (most recent call last):
    File "", line 1, in
    File "", line 8, in get_number
    ...
    File "", 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

    View Slide

  13. Questions
    https://t.me/spbpython
    https://t.me/piterpy_meetup

    View Slide

  14. Links
    http://delimitry.blogspot.com/2015/01/python-numbers-obfuscation.html
    https://docs.python.org/2/library/stdtypes.html#comparisons

    View Slide