отражение возможно на запутывании - PullRequest
2 голосов
/ 22 сентября 2010

Я борюсь с этой проблемой с прошлой недели. Я запутал exe моего приложения. Наше приложение является автономным инструментом для онлайн веб-приложений. Клиент установит это приложение и один раз подключится к Интернету, приложение загрузит соответствующую информацию и сохранит ее в xml-файле на клиентском компьютере для дальнейшего отображения. в целях безопасности мы шифруем эти XML-файлы. К сожалению, у нас есть один метод GetCryptXML внутри exe, который будет читать зашифрованный файл settings.xml на клиентском компьютере и возвращать его после расшифровки. этот setting.xml содержит ключ шифрования и для других xml.

Проблема, с которой я здесь сталкиваюсь, заключается в том, что даже после запутывания человек может вызывать метод GetCryptXML, передавая запутанное имя.

Есть ли способ решить эту проблему?

Это моя идея, чтобы решить проблему, но я не уверен, как реализовать.

Моя идея: единственный способ вызвать мою функцию - это отражение с помощью функции InvokeMember (). прежде чем кто-либо сможет вызвать эту функцию, он / она должен загрузить сборку, используя это.

Assembly.LoadFrom("myapplication.exe")

Если код в myapplication.exe может определить, какое приложение пытается загрузить меня, мы можем ограничить их загрузку, если это не предназначенное приложение. Я не знаю, как я могу решить.

Любая помощь очень ценится.

Спасибо.

Ответы [ 3 ]

9 голосов
/ 22 сентября 2010

Запутывание не меняет основы .net или вашего приложения - в конце концов, все, что он делает, это делает его более трудным для чтения и пытается добавить случаи, которые инструменты декомпиляции не могут обработать ... но в любом случае IL все еще там. Если вы дадите им зашифрованный текст (xml) и ключ (отправленный по проводам или скрытый в вашем коде), они смогут его расшифровать. Все, что вы делаете, это усложняете, а не делаете невозможным.

Одна вещь, которую вы можете сделать, - это строгое имя ваших сборок и убедитесь, что вызывающий объект вашего типа происходит из определенной сборки со строгим именем с помощью StrongNameIdentityPermission атрибут. Обратите внимание, что KeeperOfTheSoul является правильным - сборки с полным доверием могут обойти это в версиях .net до 4.0 (насколько я понимаю, в 4.0 этот атрибут больше не использует разрешение для идентификации и работает только при наличии правильных свидетельств).

Вы также можете написать код для получения стека вызовов через System.Diagnostics.StackTrace и проверить методы вызова, чтобы убедиться, что он является одним из ожидаемых абонентов. Это означает немного более медленное выполнение и больше кода, но вы можете контролировать его.

РЕДАКТИРОВАТЬ См. Здесь для ознакомления с использованием StrongNameIdentityPermission. А вот статья о проверке трассировки стека . Опять же, обратите внимание, что ни один из них не является серебряной пулей, но может добавить еще одно препятствие атакующему, если вы считаете, что оно стоит вашего времени. (Помните, что в день интернета, только один успешный злоумышленник может найти результат в любом количестве людей)

2 голосов
/ 22 сентября 2010

Если вы хотите ограничить доступ к методу для конкретной сборки, вы можете сделать следующее:

    private void RestrictedMethod() {
        Assembly calling = Assembly.GetCallingAssembly();
        if(calling.FullName != "myapplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") {
            throw new InvalidOperationException();
        }
        // Do method work...
        return;
    }

Одним из преимуществ этого подхода является то, что если кто-то использовал отражение от несанкционированной сборки, вызовпотерпит неудачу.

1 голос
/ 22 сентября 2010

Если что-то может быть вызвано через Reflection, оно должно вызываться (каким-то образом) через обычный код.

Я бы предложил против этого (поскольку нет способа полностью помешать кому-то, кто непреклонен в выполнении кодаони не должны).

Если вы действительно заинтересованы в том, чтобы сделать что-то подобное, вы можете сломать ОО Принципы C # и сделать все ваши методы закрытыми.Таким образом, только код, выполняемый из вашего класса, может вызывать их регулярно.Всем остальным придется вызывать их через Reflection (и вызов частных членов через Reflection чаще всего считается плохой практикой).

Как ни странно, чем больше я думаю об этом, метод, вероятно, должен быть помечен как закрытый.во всяком случае, так как вы не хотите, чтобы все могли это назвать.Вызывающие абоненты должны вызывать через общедоступный фасад, который определит, разрешено ли вам вызывать метод или нет ... и разрешать только авторизованные вызовы.

...