Теория и практика защиты программ

       

Практические вопросы построения обфускаторов


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

  private void CalcPayroll(SpecialList employeeGroup)

            {

               while(employeeGroup.HasMore())

               {

                 employee = employeeGroup.GetNext(true);

                 employee.UpdateSalary(); DistributeCheck(employee);

               }

            }

Рис. 12.1. Псевдокод программы до обфускации

private void _1(_1 _2)

            {

              while(_2._1())

              {

                _1 = _2._1(true);

                _1._1();

                _1(_1);

               }

            }

Рис. 12.2. Псевдокод программы после обфускации

Таким образом, задача обфускации заключается, как это видно из рис. 12.1.-12.2., в затруднении для понимания и анализа исходного кода программы, запутывании и устранении логических связей в этом коде.

Основные функции при обфускации программ, например, для .Net-сборок могут заключаться в следующем. Сначала анализируются метаданные, так как не все члены сборки обфускатор может обработать. Например, обфускатору не стоит заменять имена конструкторов типа данных – это может привести к нежелательным последствиям. Хотя в некоторых случаях это возможно.

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

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



Содержание раздела