![]() |
|
||||||||||
|
|||||
|
Регистрация: Jun 2012
Сообщений: 70
|
Написал свой обфускатор as3 кода.
Используются 2 библиотеки: работа с тегами swf файла as3swf, работа с байтокодом as3abc. Последнюю библиотеку дополнил возможностью сохранять измененный байткод, т.к. она позволяла только получить данные о классах, методах и т.д. Обфускатор умеет обфусцировать: неймспейсы, классы, переменные, методы, геттеры/сеттеры, и константы. Для проверки на возможность переименовывания методов/переменных/констант, я написал анализатор байткода. Он ищет во всех функциях опкоды которые обрабатывают строки и запоминает эти строки, чтобы в дальнейшем не сломать их, если вдруг будет переменная с таким же именем, при её обфускации. Т.е. если в коде где-нибудь встречается строка "Update" и метод Update, то этот метод не переименуется, т.к. в таблице строк тега abc, хранится один экземпляр строки Update, который соответствует и строке и имени метода. Теперь вылез вот такой случай, например есть такой код: Код: Когда мы обфусцируем метод Foo, вместе с ним обфусцируется и свойство Foo у obj, но это не правильно, т.к. это свойство динамическое, то в рантайме вылезет ошибка. Так вот выходом было добавление в анализатор, обработки таких случаев. Если опкод один из этих GetProperty, SetProperty, CallProperty, CallPropVoid то добавляем в игнорлист его значение. В примере это свойство Foo обьекта obj. Так все работает, но только если обфусцировать приложения скомпилированное в Flex Sdk, если приложение скомпилированное во Flash, то получается что все, выше перечисленные опкоды, применяются когда класс обращается к своему члену, а не как обращение к динамическому методу обьекта. И получается ни один метод не переименовывается, т.к. находится в игнор листе. Посоветуйте как это лучше сделать.
__________________
Блог: http://devizgl.blogspot.com/ Последний раз редактировалось vizgl; 28.06.2012 в 20:59. |
|
|||||
|
офигеть, дайте две! as3abc я так и не полез дописывать сборщик на место. Вы опубликовали или собираетесь ли опубликовать сырцы этого дополнения?
Действительно есть над чем подумать. А что вы делаете с jmp в коде? все пересчитываете на новые адреса?
__________________
:) |
|
|||||
|
Регистрация: Jun 2012
Сообщений: 70
|
Сам обфускатор открывать не буду, а дописанную либу могу опубликовать. В репозитории последний коммит 2 года назад, не думаю что автор еще собирается поддерживать проект.
На счет jmp, я не заморачивался, автор библиотеки не дописал этот функционал, я тоже не писал. Сам то не использую метки в коде. К тому же код я не меняю, а только таблицу констант, в таком случае не приходится пересчитывать смещения для меток свича, джампов и т.д.
__________________
Блог: http://devizgl.blogspot.com/ Последний раз редактировалось vizgl; 28.06.2012 в 21:42. |
|
|||||
|
Регистрация: Jun 2012
Сообщений: 70
|
Вот дополненная библиотека. Еще многое нужно тестировать, т.к. думаю багов полно будет, если изменять само байткод.
Есть еще такая библиотека AS3 Commons Bytecode но она у меня что-то плохо собирала файл обратно.
__________________
Блог: http://devizgl.blogspot.com/ Последний раз редактировалось vizgl; 28.06.2012 в 21:52. |
|
|||||
|
Регистрация: Nov 2010
Сообщений: 497
|
Цитата:
В первом случае придется разбирать либо один вариант GetProperty (если там multiname) или пару getpropertystrict + getproperty (если во втором multinameL). Также придется смотреть на тип obj в динамическом вызове и проверять, есть ли у этого тип соответствующие методы или нет (на этапе анализа, исходя из типов аргументов функции, например). Ну и при выполнении всех условий заменять опкод (или два) на один "строгий" вызов. Во втором случае все примерно так же. В этом случае одна из констант переименовывается вместе с именем метода/свойства. Но в исходном подходе "маскирования" свойств есть большая проблема. Как вы обрабатываете multinameL? Пример: multinameL скорее всего будут, например, при работе со внешним миром (что-то по сети прочитали, распарсили, сложили в map). По идее в качестве значения может быть все, что угодно, и это автоматически запретит переименования везде. Так что нужно определять набор классов, к каким допустимо переименование, а к каким - нет. И при этом учитывать, что запрет переименования в родителе не всегда должен приводить к невозможности переименования в детях (иначе обычный динамический доступ к Object опять убъет все переименования). Это тоже делается, для каждой переменной нужно строить список классов, значения которых могут храниться в этой переменной (не то, что заявлено типами, а то, что туда может придти через program flow). |
|
|||||
|
Регистрация: Jun 2012
Сообщений: 70
|
Цитата:
А действительно некоторые опкоды выполняют разные задачи при компиляции flex sdk и в flash ide? Или это я где-то натупил?
__________________
Блог: http://devizgl.blogspot.com/ |
|
|||||
|
Регистрация: Nov 2010
Сообщений: 497
|
А кто их как строки то отметит? Если бы там было
тогда да. А мой код эквивалентен Вы же, наверное, не все "строки" из пула строк помечаете как невалидные. Но даже это не поможет против multinameL, имена могут быть не в пуле: В этом случае у вас в процессе вычисления на стек будет класться значение 'field' + i. Не выполняя выполнения кода (или какого-то сложного анализа) вы просто не узнаете все возможные строки. Это вряд ли, для этого придется усложнять плеер. А вот то, что одна и та же AS3-конструкция компилируется по-разному flex и flash вполне возможно. |
|
|||||
|
Регистрация: Jun 2012
Сообщений: 70
|
Цитата:
IntStringIntIntOperation StringOperation Ну и multiname операции GetProperty SetProperty CallProperty CallPropVoid Так, то все ваши примеры будут работать нормально. Обфускатор уже тестировался на 2 зарелизиных игрушках, просто собирались они под flex sdk. Вот решил обфусцировать свою первую игру на flash и вылезли такие косяки с динамическими свойствами.
__________________
Блог: http://devizgl.blogspot.com/ |
|
|||||
|
Modus ponens
|
Я бы шел по такому пути: искал бы только пользовательские классы, не динамические, и переименовывал их свойства тогда когда из кода понятно, что обращаются именно к экземпляру этого класса. То, что обращаются именно к экземпляру нужного класса всегда можно понять в самом месте вызова, так что даже далеко ходить не нужно. Остальное не трогал бы. Самое худшее, что в таком случае может произойти - пользовательский ввод интерпретируется как имя свойства - но от этого вы никак не застрахуетесь, так что прийдется смирится, т.как если какой-нибудь паблик-морозов в коде есть, то таким образом можно даже к приватным свойствам обратиться.
__________________
Hell is the possibility of sanity |
|
|||||
|
Регистрация: Jun 2012
Сообщений: 70
|
Цитата:
Update: с ключевым словом dynamic
__________________
Блог: http://devizgl.blogspot.com/ Последний раз редактировалось vizgl; 29.06.2012 в 00:25. |
![]() |
![]() |
Часовой пояс GMT +4, время: 12:16. |
|
|
« Предыдущая тема | Следующая тема » |
|
|