По поводу Python, можете пояснить подробнее, что подразумевается под динамическим созданием функций и свойствами функций, и чего нету (?) в питоне? Ну и для замыканий в 3ем питоне есть nonlocal. Какие ещё возможности ограничены?
Я сразу написал, что такая обфускация непрактична. Это был контрпример к
> Имея большой запас терпения, можно разобраться в любой обфусцированной программе и выписать алгоритм.
Топик о теоретических подходах к определению обфускации и теоретических пределах. Мой пример — «игрушечный» и к практике имеет мало отношения. Я хотел показать, что криптография по сути может являться обфускацией. Если заменить hash(x) == 123456 на x == 123456 то ведь будет очевидно, что делает код? А если взять что-то посередине, функцию попроще? Где граница между обфускацией и криптографией?
Опечатка, «Скормим этот (кем-то) обфусцированный код тому же идеальному обфускатору» — конечно же код скормим Indistinguishability обфускатору (который по предположению vedenin1980 может выводить просто перестановку слагаемых).
В статье [3] как раз доказывается, что «Indistinguishability Obfuscation» — лучшее, чего можно достичь.
«На пальцах»,
представьте произвольную идеальную обфускацию этого же алгоритма (x = y + z — t). Скормим этот (кем-то) обфусцированный код тому же идеальному обфускатору. Что же он выведет? А выведет он «банальную перестановку суммы» x = y + z — t, ведь исходные программы функционально одинаковы, значит и обфусцированные версии должны быть неотличимы. А это значит, что мы эффективно деобфусцировали исходную идеальную обфускацию и поэтому наш обфускатор (перестановка слагаемых) не хуже того идеального.
Вы можете сказать, что тогда хорошая обфускация невозможна — ведь предложенные вами «обфускации» подходят под определение, а значит это лучшее, чего можно достичь. Вот только мелочь: заверните ваш метод в эффективный алгоритм, да так, чтобы любой запутанный код, эквивалентный (x = y + z — t) он тоже развернул в x = y + z — t. Тогда действительно обфускация невозможна, ведь ваш алгоритм будет отличным деобфускатором.
Ещё раз — никуда шагать не надо, если вход известен. На известном входе можно просто запустить программу.
> ключ расшифровки каждый раз приходит откуда извне, по сути тоже самое что все программа работала на веб сервисе,
Вот и не то же самое. Веб-сервис — черный ящик, у вас нет шансов узнать о программе ничего кроме выводов на запрошенные входы. В случае моей программы код у вас есть. Но не взламывая хэша, нельзя определить, является ли код под хэшем мусором или нет
Следуя вашей логике, не получается деобфусцировать — значит программа — веб-сервис. А ведь это и есть цель обфускации — из программы сделали черный ящик.
> все ключи всем известны
Ключ — это вход для программы. На известных входах можно просто запустить программу и не нужна никакая деобфускация. Но и информации о программе это даст ровно то, что f(x1) = y1.
Вот например мы обфусцируем программу f(x,y) = x + y если x != 31337 иначе f(x,y) = -1. Код получается такой:
1. считаем хитрый хэш от входа
2. если хэш = 1234567, расшифровать и выполнить код1 (ключ = вход)
3. иначе вывести x + y
Чем не обфускация в самом обычном понимании? Исходный код «запутан». Неизвестно, что программа делает, может там бэкдор вообще? Конечно, видно «подозрительное» место. Но может это тот самый «мусор» добавленный обфускатором? Может хэш нереально выполнить? Вот и получается, что криптография сводится к деобфускации.
> Я могу узнать, что одна часть программы расшифровывает другую, и окажусь в том же положении, если бы программа не была обфусцирована
А если для каждого входа отдельный код? Узнав один вход, вы не узнаете что будет на другом. Если вход известен, деобфускация не нужна, можно просто запустить программу на этом входе и узнать выход (черный ящик). Но больше по программе вы ничего сказать не можете.
Конечно, такая обфускация непрактична, но и топик-то о теории.
> это задача, сломанная по определению. Я ставлю на что, это неосуществимо в общем случае.
Спорить не буду, вполне возможно. Но опять же, топик о теории. Докажите.
> Имея большой запас терпения, можно разобраться в любой обфусцированной программе и выписать алгоритм.
Представьте программу, которая берет например sha1 хэш от входа, использует его как ключ для расшифровки остальной части кода. Насколько большой запас терпения нужен чтобы разобраться, что же делает программа?
Вот и связь с криптографией.
> В криптрографии не занимаются security through obscurity.
А как же whitebox имплементации шифров?
Атака «дней рождения» на SHA-256 потребует около 2^128 операций. И несмотря на высокую стоимость, она вполне осуществима хорошо финансируемым злоумышленником.
PS: наверняка с таким простым шифром можно справиться и SAT солвером
Я конечно понимаю, что это «упражнение» на map/filter/reduce но зачем писать такую ерунду? Хотя бы
зачем ещё что-то городить? ;)
PS: для полноты ощущений можно ещё все аттрибуты тоже заглобалить:
Правда записать в атрибуты так ничего не получится, только через this.
А вообще, на python2 это можно сконвертировать совсем просто:
(взято отсюда). Ну или здесь попроще :)
> Имея большой запас терпения, можно разобраться в любой обфусцированной программе и выписать алгоритм.
Топик о теоретических подходах к определению обфускации и теоретических пределах. Мой пример — «игрушечный» и к практике имеет мало отношения. Я хотел показать, что криптография по сути может являться обфускацией. Если заменить hash(x) == 123456 на x == 123456 то ведь будет очевидно, что делает код? А если взять что-то посередине, функцию попроще? Где граница между обфускацией и криптографией?
«На пальцах»,
представьте произвольную идеальную обфускацию этого же алгоритма (x = y + z — t). Скормим этот (кем-то) обфусцированный код тому же идеальному обфускатору. Что же он выведет? А выведет он «банальную перестановку суммы» x = y + z — t, ведь исходные программы функционально одинаковы, значит и обфусцированные версии должны быть неотличимы. А это значит, что мы эффективно деобфусцировали исходную идеальную обфускацию и поэтому наш обфускатор (перестановка слагаемых) не хуже того идеального.
Вы можете сказать, что тогда хорошая обфускация невозможна — ведь предложенные вами «обфускации» подходят под определение, а значит это лучшее, чего можно достичь. Вот только мелочь: заверните ваш метод в эффективный алгоритм, да так, чтобы любой запутанный код, эквивалентный (x = y + z — t) он тоже развернул в x = y + z — t. Тогда действительно обфускация невозможна, ведь ваш алгоритм будет отличным деобфускатором.
> ключ расшифровки каждый раз приходит откуда извне, по сути тоже самое что все программа работала на веб сервисе,
Вот и не то же самое. Веб-сервис — черный ящик, у вас нет шансов узнать о программе ничего кроме выводов на запрошенные входы. В случае моей программы код у вас есть. Но не взламывая хэша, нельзя определить, является ли код под хэшем мусором или нет
Следуя вашей логике, не получается деобфусцировать — значит программа — веб-сервис. А ведь это и есть цель обфускации — из программы сделали черный ящик.
Ключ — это вход для программы. На известных входах можно просто запустить программу и не нужна никакая деобфускация. Но и информации о программе это даст ровно то, что f(x1) = y1.
Вот например мы обфусцируем программу f(x,y) = x + y если x != 31337 иначе f(x,y) = -1. Код получается такой:
1. считаем хитрый хэш от входа
2. если хэш = 1234567, расшифровать и выполнить код1 (ключ = вход)
3. иначе вывести x + y
Чем не обфускация в самом обычном понимании? Исходный код «запутан». Неизвестно, что программа делает, может там бэкдор вообще? Конечно, видно «подозрительное» место. Но может это тот самый «мусор» добавленный обфускатором? Может хэш нереально выполнить? Вот и получается, что криптография сводится к деобфускации.
А если для каждого входа отдельный код? Узнав один вход, вы не узнаете что будет на другом. Если вход известен, деобфускация не нужна, можно просто запустить программу на этом входе и узнать выход (черный ящик). Но больше по программе вы ничего сказать не можете.
Конечно, такая обфускация непрактична, но и топик-то о теории.
> это задача, сломанная по определению. Я ставлю на что, это неосуществимо в общем случае.
Спорить не буду, вполне возможно. Но опять же, топик о теории. Докажите.
Представьте программу, которая берет например sha1 хэш от входа, использует его как ключ для расшифровки остальной части кода. Насколько большой запас терпения нужен чтобы разобраться, что же делает программа?
Вот и связь с криптографией.
> В криптрографии не занимаются security through obscurity.
А как же whitebox имплементации шифров?
Можно просто x/100x $rsp. А ещё лучше x/100xg чтобы выводил 64битные слова.
Компилятору это значение конечно же неизвестно.
PS: зачем было заворачивать код в func?
Просто нужно умножать на обратный к 31 элемент (3186588639).
Че?