Подскажите пожалуйста, как в приложении определить скомпилировался ли метод в этом приложении и если скомпилировался, то как узнать адрес начала машинного кода этого метода?
Ps: читал 2 статьи про инъекцию кода во время выполнения. Одна с исходными кодами элементарную инъекцию так и не сделала, а после тестирования второго способа компьютер начал показывать порно товары, хотя инъекция предполагала замену сложения на вычетание))
Здравствуйте, SanyaVB, Вы писали:
SVB>Подскажите пожалуйста, как в приложении определить скомпилировался ли метод в этом приложении и если скомпилировался, то как узнать адрес начала машинного кода этого метода?
Здравствуйте, Sinix, Вы писали:
S>Зависит от задачи. Можно извратиться ч/з CLR MD, можно полезть в кишкигрязными руками, правильный способ — не делать вообще.
Первая статья не очень... она одна из тех о которых я писал в начале. Много стороннего С++ кода, причем бинарник не соответствует исходнику(если кто-то осмелиться все таки скомпилировать исходник — вот так просто не получится , проще Linux руками собрать)... короче вирусня.
А вот вторая ссылка мне понравилась. Походу это то что нужно! Спасибо!
Здравствуйте, SanyaVB, Вы писали:
SVB>А вот вторая ссылка мне понравилась. Походу это то что нужно! Спасибо!
С вероятностью в 99% — это не то, что вам нужно. Long story short, лезть в кишки CLR и менять значения напрямую примерно так же безопасно и надёжно, как флипать рандомный бит в адресном пространстве чужого процесса.
Решения есть, но они все не универсальные. Нужно знать точную задачу, чтоб подсказать точнее.
Здравствуйте, SanyaVB, Вы писали:
SVB>Подскажите пожалуйста, как в приложении определить скомпилировался ли метод в этом приложении и если скомпилировался, то как узнать адрес начала машинного кода этого метода?
SVB>Ps: читал 2 статьи про инъекцию кода во время выполнения. Одна с исходными кодами элементарную инъекцию так и не сделала, а после тестирования второго способа компьютер начал показывать порно товары, хотя инъекция предполагала замену сложения на вычетание))
Здравствуйте, Sinix, Вы писали:
S>Решения есть, но они все не универсальные. Нужно знать точную задачу, чтоб подсказать точнее.
Защита ПО. Идея состоит в том чтобы определенные методы находились в бесполезном виде (т.е. не несут в себе полезной работы), но во время выполнения они могут поменять свой функционал и после выполнения возвратить себя в исходное состояние (как бы подчистить следы в памяти). менять функционал будет отдельный поток (manage или native не имеет значения)
Здравствуйте, SanyaVB, Вы писали:
S>>Решения есть, но они все не универсальные. Нужно знать точную задачу, чтоб подсказать точнее. SVB>Защита ПО. Идея состоит в том чтобы определенные методы находились в бесполезном виде...
В натив проще вытащить. Все остальные способы или обходятся через стандартные API, или портят приложение разнообразным и непредсказуемым способом. Самое эпичное из того что попадалось — приложение-суицидник: через какое-то время после установки отрабатывал Auto NGen Maintenance Task ииии упс Ключевые слова для поиска: NGen indirections + NGen fix-up tables.
Если коротко, то чтобы хоть примерно разобраться с тем, как заставить это дело работать, придётся перелопатить гору матчасти. И 99.9 за то, что итоговым решением будет "любой другой способ кроме заигрываний с JIT".
UPD: А, ну или замените прямые вызовы на вызовы делегатов (главное, не хранить делегат в static readonly-поле), тело делегата заполняйте динамически. По производительности ппц будет, да и приключений нахватаетесь, но оно хоть работать будет. В основном.
Здравствуйте, Sinix, Вы писали:
S>UPD: А, ну или замените прямые вызовы на вызовы делегатов (главное, не хранить делегат в static readonly-поле), тело делегата заполняйте динамически. По производительности ппц будет, да и приключений нахватаетесь, но оно хоть работать будет. В основном.
Ну... да! работать будет. Но такую защиту любой начинающий взломать может. И тогда встает вопрос — стоит ли громоздить эти делегаты или ограничиться простым условием?
if(trial)
{
}
else
{
}
По скорости взлома и кол-ву людей которые могут взломать примерно одинаково, зато реализация и отладка — шустрая
Здравствуйте, SanyaVB, Вы писали:
SVB>Ну... да! работать будет. Но такую защиту любой начинающий взломать может.
Ну усложните им задачу — собирайте часть кода динамически. Или, скажем, сделайте словарь guid-делегат, заполните её на 99% мусором, 1% — правильные методы, созданные через expression tree. Таблицу заполнять в рантайме, правильные ключики к методам подставлять в рантайме. Смысла в этом нет никакого, но 99% начинающих отпугнёт.
SVB>И тогда встает вопрос — стоит ли громоздить эти делегаты или ограничиться простым условием?
Не стоит. Большинство продуктов вообще сводят проверку к ключику в реестре или файлу в %appdata%. И ничо, живут как-то. Люди, которые жопятся потратить $10-20 на полезный инструмент вряд ли вообще являются вашими клиентами, смысл с ними бороться?
Сделайте простенькую проверку — храните подписанную приватным ключиком дату установки и меняйте ключик каждый релиз. Ключика нет — просите переустановить. Всё.
Здравствуйте, Sinix, Вы писали:
SVB>>И тогда встает вопрос — стоит ли громоздить эти делегаты или ограничиться простым условием? S>Не стоит. Большинство продуктов вообще сводят проверку к ключику в реестре или файлу в %appdata%. И ничо, живут как-то. Люди, которые жопятся потратить $10-20 на полезный инструмент вряд ли вообще являются вашими клиентами, смысл с ними бороться?
Вообще есть всякие Dotfuscator — ы. Появилась идея(часть её я тут описал) как можно было бы сделать похитрее. Проблема для реализации стал JIT как писал и ранее. Ссылки которые вы мне прислали действительно дали хорошее представление о решении проблемы. И это представление говорит мне в полный голос что проблем будет много
Кстати про делегаты... делегат — это грубо говоря указатель на метод. и скомпилированное(native) тело метода из памяти не удаляется до завершения процесса. Или все таки удаляется?
SVB>Кстати про делегаты... делегат — это грубо говоря указатель на метод. и скомпилированное(native) тело метода из памяти не удаляется до завершения процесса. Или все таки удаляется?
Удаляется для expression trees и c ограничениями — для эмита. Всё остальное — по завершению домена, если сборка не сохранена явно
В .net core Collectible Assemblies то включали, то отключали, не уследил, попало оно в релиз или нет. Начать можно вот отсюда.
Здравствуйте, SanyaVB, Вы писали:
SVB>Вообще есть всякие Dotfuscator — ы. Появилась идея(часть её я тут описал) как можно было бы сделать похитрее. Проблема для реализации стал JIT как писал и ранее. Ссылки которые вы мне прислали действительно дали хорошее представление о решении проблемы. И это представление говорит мне в полный голос что проблем будет много
Может быть тут ConfuserEx уже порешали твои идеи? Много что умеет + поддержка плагинов (т.е. твоя собственная уникальная защита).
А проверять результат можно вот этим de4dot
_>Может быть тут ConfuserEx уже порешали твои идеи? Много что умеет + поддержка плагинов (т.е. твоя собственная уникальная защита).
Неа, это эталонный "обфускатор, который не смог". Как оно было два года назад
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, pilgrim_, Вы писали:
_>>Может быть тут ConfuserEx уже порешали твои идеи? Много что умеет + поддержка плагинов (т.е. твоя собственная уникальная защита). S>Неа, это эталонный "обфускатор, который не смог". Как оно было два года назад
А что он (обфускатор) не смог? Там сама идея заключается в написании "защит" в виде плагинов на managed языке (что не мешает самим плагинам встраивать нативный (и обфусцированный) код в отдельные секции PE для дальнейшего использования в runtime, а также часть логики приложения), а те плагины, код которых выполняется в runtime сами также могут (и так и происходит) подвергаться пассивной и активной защите.
Имхо свою цель — защита managed приложений от статической (в большей степени) и динамической "атаки", проект выполняет на отлично, и является хорошим каркасом для своих ("уникальных" )расширений.
ps: сам в защите не копенгаген, но на 1-й взгляд в проекте толковый и расширяемый подход.
, так и осталось.
_>Там сама идея заключается в написании "защит" в виде плагинов на managed языке
Ну вот это и fail. Не спасает даже от скрипткидди средней квалификации.
Альтернатива ничем не лучше впрочем — разнообразные трансляторы в натив разнообразно же портят приложение, ловля подобных багов — то ещё удовольствие.
, так и осталось.
_>>Там сама идея заключается в написании "защит" в виде плагинов на managed языке S>Ну вот это и fail. Не спасает даже от скрипткидди средней квалификации.
Я не силен в современных методах/инструментах "взлома", но с выделенным не согласен, то что код защиты написан на C# вряд ли сильно упростит "взлом", который должен будет проходить в runtime (в статике все зашифрованно), и вряд ли это легче чем анализ нативного
кода.
Скорее всего "fail" в том что код рассматриваемого проекта открытый? Использование того же Environment.FailFast можно определить в статике по метаданным, но если его заменить на TerminateProcess ("импортируемый" в рантайм)/принудительный AV, то уже немножко усложнит анализ.
ps: я это к чему, вопрос то защиты (в том числе натив кода) холиварный и периодически поднимался на форуме, но мне кажется что разницы особой нет, что натив, что managed, в плане сложности взлома.
Здравствуйте, pilgrim_, Вы писали:
_>Я не силен в современных методах/инструментах "взлома", но с выделенным не согласен, то что код защиты написан на C# вряд ли сильно упростит "взлом", который должен будет проходить в runtime (в статике все зашифрованно), и вряд ли это легче чем анализ нативного
До тех пор, пока мы сохраняем работоспособность произвольного il-кода, включая биндинг, рефлексию, dynamic, загрузку сборок и тыды и тыпы — легче на три порядка, без шуток. Особенно в обсуждаемой реализации, в ней сдампить сборку через clrmd особого труда не составляет.
_>Скорее всего "fail" в том что код рассматриваемого проекта открытый?
Никакой разницы, уж поверьте. С учётом того, что я взломом не занимаюсь никак от слова совсем, хватает опыта реверс-инженеринга наших же продуктов в случае, когда в принципе не понятно, почему оно у клиента не работает + исходники по той или иной причине недоступны.
Т.е. для человека, которым занимается этим профессионально + действует не в режиме дедлайна проблем ещё меньше будет.
S>Использование того же Environment.FailFast можно определить в статике по метаданным, но если его заменить на TerminateProcess ("импортируемый" в рантайм)/принудительный AV, то уже немножко усложнит анализ.
Даблин, не важно как реализована "защита". До тех пор, пока она вызывается через il-код, нет никаких принципиальных препятствий эти вызовы найти и выбросить. Ну да, можно сгенерить пару миллионов методов с проверками и разбросать их по коду, задача осложнится ненамного — просто автоматизировать то, что иначе руками делается. По сравнению с мрачными вывертами сознания, доступными в нативе — детский сад, да и только..
_>ps: я это к чему, вопрос то защиты (в том числе натив кода) холиварный и периодически поднимался на форуме, но мне кажется что разницы особой нет, что натив, что managed, в плане сложности взлома.
_теоретически_, с трансляцией в натив — таки да. Практически — это вряд ли. Другое дело, что в большинстве случаев (если мы говорим про энтерпрайз) самой эффективной защитой является обновляемая каждый релиз простенькая проверка на сертификатах или подписанным ключиком в реестре. Если так хочется, можно оставить дополнительную закладку с нагскрином, которая сработает через пару месяцев.
Всё, что сложнее пользователей не прибавляет, скорее наоборот.
Здравствуйте, Sinix, Вы писали:
S>Даблин, не важно как реализована "защита". До тех пор, пока она вызывается через il-код, нет никаких принципиальных препятствий эти вызовы найти и выбросить. Ну да, можно сгенерить пару миллионов методов с проверками и разбросать их по коду, задача осложнится ненамного — просто автоматизировать то, что иначе руками делается. По сравнению с мрачными вывертами сознания, доступными в нативе — детский сад, да и только..
Что то не туда все понесло. Давайте определим какие типы защиты существуют! Оказывается их да
1) условная
2) безусловная
Условная защита — это примитивная защита в которой содержится условный оператор if или switch. Ломается она простой инъекцией кода... в реализации она очень проста и используется только на том софте, который интересен домохозяйкам.
безусловная защита — это защита которая не использует условные операторы. Вот тут без покупки софта (какой бы профессиональный хакер не был) взломать не возможно. Явный пример такой защиты — это архив RAR под паролем. Тут пароль является ключом распаковки. подобрать ключ не реально, если он длинный. Тут уже никакие вызовы выбросить не получится — дабы нет смысла в этом.
В итоге безусловная защита выглядит намного красивее, НО — это защита до первой покупки... Хитрожопые жадные фирмы покупают одну копию софта, а потом плодят её как могут (если софт по договоренности обязан работать в офлайн режиме)
В этом случае на помощь приходит защита Гейзенберга, которая вносит неопределенность выявления ключа для безусловной защиты. Её реализовывают разными способами, но только в Native коде... в управляемом я ни разу не встречал такого(как полагаю связано это с JIT — компилятором)
Здравствуйте, SanyaVB, Вы писали:
SVB>Что то не туда все понесло. Давайте определим какие типы защиты существуют! Оказывается их да SVB>1) условная SVB>2) безусловная
Опять не с той стороны думаете. Попробуйте взглянуть на проблему как взломщик/реверсер. И внезапно вместо надуманной классификации вырисовывается вполне жизненные:
1. Мы можем получить валидный il-код в рантайме, подцепившись отладчиком.
2. Всё то же самое, только с "не" (расставить по вкусу).
В первом варианте от реверсера не требуется вообще никаких навыков, кроме уметь думать — весь готовый инструментарий уже есть, задача сводится к правке il-кода, что не особо сложнее правки исходников. Ну а с исходниками чего можно сделать? Непонятные имена и лишний код? Так с этим сами авторы отлично справляются
Во втором — упс, но этот же упс относится и к разработчикам приложения. Т.к. отвалиться может что угодно, от биндинга и до сериализации. Что в свою очередь означает кучу времени на тестирование и отладку именно обфусцированной версии и постепенное исключение из обфускации отдельных кусков кода, иначе никак. И в итоге получается то, о чём писал в самом начале — ядро в нативе (или вообще в облаке), приятной отладки