1. C# / Говнокод #3261

    +113

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    private static void assertNoReflection()
    {
        foreach (StackFrame stackFrame in new StackTrace().GetFrames())
        {
            if (stackFrame.GetMethod().DeclaringType.Namespace == "System.Reflection")
            {
                throw new MethodAccessException();
            }
        }
    }
    
    internal static string GetKey()
    {
        assertNoReflection();
    
    // ...
    }

    Вот так вот приходится говнить, потому что в дотнете рефлексией можно спокойно вызывать internal- и private- методы.
    assertNoReflection(); проверяет, что вверх по стеку вызовов никто не балуется рефлексией.
    После assertNoReflection(); из нативной длл получаем обфусцированную (вручную, лол) строку, которая далее с помощью запутанных алгоритмов (некоторые параметры для "расшифровки" опять берутся из нативной длл) приводит её в вид пароля (для доступа к запароленному архиву).
    Софт не прямо уж суперсекретный, просто нужно скрыть ресурсы хотя бы для приличия. Пароль через подключение к серверу не катит.
    Ко всему этому оно собрано в одно exe моновским mkbundle'ом (рефлектор не может открыть!) и поверх upx'ом. В общем, большое количество кулхацкеров отсекается (должны знать ассемблер и MSIL).
    Чувствую, что говнорешение, но не могу придумать что-то более умное. Обфускаторы тоже не очень катят, ибо плохо дружат с моно.

    Запостил: cfdev, 18 Мая 2010

    Комментарии (10) RSS

    • Шифрование нативной длл и реализация критических кусков кода в ней.
      Ответить
      • Сделано для галочки же: "софт не прямо уж суперсекретный, просто нужно скрыть ресурсы хотя бы для приличия".

        В принципе по существу только первые два предложения описания, далее просто к сведению (о говноподвигах в области безопасности) (была бы возомжность постредактирования, вырезал бы :\)

        Так вот, вопрос открыт пока: есть ли в дотнете какие-то иные способы защиты от вызова интернал- и прайвет-методов через рефлексию? (забудем, что можно в рефлекторе просто так посмотреть сам код). Логично предположить, что есть что-то связанное с аттрибутами (допустим), но при фул-трасте, похоже, рантайму на всё насрать.
        Ответить
        • можно ли узнать список методов и вложенных классов в рантайме??
          Ответить
        • Теперь pushkoff тебя взломает. Приготовся. :D
          Ответить
          • и запостит на ГК.ру ))))
            Ответить
          • мне для собственного развития... а то по всему инету распиарена рефлексия в С#, а я ума не приложу где ее можно применить в реальных проектах...
            хотя при помощи рефлексии в питоне мы выгружаем описание данных, это немного удобнее чем описывать их в XML.
            Ответить
        • Неа, рефлексия могуча.

          Единственный реальный способ - делать проверки у себя, что-то вроде того, что у вас, только более вменяемое.
          Ответить
      • А вообще тут как бы логика в том, что средний обыватель вообще об этом ничего не знает, а кулхацкер в x86 скорей всего мало шарит в MSIL и наоборот (часть дешифровки происходит в нативе, а часть - в маенеджед + ресурсы добываются так же), ибо малопересекающиеся миры на самом деле (те, кто пишет пинвоки, в основном только спеки умеют читать).

        Плюс собранный mkbundleом эксешник хотя и содержит внутри себя как контейнер реальные CIL-образы, валидным CIL-образом мейнстримным рефлектором не считается и не открывается, тут кулхацкеры тоже будут репы долго чесать.

        А ежли кулхацкеры каким-то образом смогут извлечь оригинальный эксешник (может, mkbundle имеют такую опцию (как и upx) - не в курсе), то, не желая морочиться с реверсингом алгоритма, решат просто вызвать рефлексией GetKey и посмотреть результат - им это тоже не удастся. Вроде бы.

        А некулхацкеры они любую "замкнутую систему" (т.е. без ключа на стороне) поломают, тут сопротивляться особо не стоит. Поэтому говнобезопасность - правильное решение.
        Ответить
    • Обходится парой строк кода через Delegate.CreateDelegate().
      Ответить

    Добавить комментарий