Translate this page:
Please select your language to translate the article


You can just close the window to don't translate
Library
Your profile

Back to contents

Cybernetics and programming
Reference:

Obfuscation algorithm

Korobeinikov Anatolii Grigor'evich

Doctor of Technical Science

professor, Pushkov institute of terrestrial magnetism, ionosphere and radio wave propagation of the Russian Academy of Sciences St.-Petersburg Filial

199034, Russia, g. Saint Petersburg, ul. Mendeleevskaya, 1

Korobeynikov_A_G@mail.ru
Other publications by this author
 

 
Kutuzov Il'ya Mikhailovich

graduate student, Department of Design and Security of Computer Systems, St. Petersburg National Research University of Information Technologies, Mechanics and Optics

197101, Russia, St. Petersburg, Kronverkskiy prospect, d. 49

formalizator@gmail.com
Other publications by this author
 

 

DOI:

10.7256/2306-4196.2013.3.9356

Received:

18-05-2013


Published:

1-06-2013


Abstract: The paper deals with the algorithm of Chenxi Wang’s, shows are the main disadvantages of this algorithm. The authors suggest the ways of modification to improve it. The algorithm of Chenxi Wang's is one of the most famous. The input data for the algorithm is the usual procedure, written in high level language. The authors describe the three stages of obfuscation of any such procedure. In the classic version of Chenxi Wang's the algorithm has poor stability. The authors suggest ways to improve stability of the algorithm, present modified version of the algorithm and reviews results of its implementation. The authors compare the source code and the resulting code and conclude that it is almost impossible to establish their functional identity and the logic of the program code is very difficult to understand using obfuscated source. Sometimes this can be done using the examples run of the resulting source code. This implies that after eliminating the shortcomings the algorithm is quite effective.


Keywords:

obfuscation, technology, source code, algorithm, Chenxi Wang, graph, variable, stability, dynamic analysis, information security


Введение

В настоящее время развиваются технологии запутывания программного кода на базе методов обфускации.
Обфускация (от лат. Obfuscare – затенять, затемнять; и англ. Obfuscate – делать неочевидным, запутанным, сбивать с толку) или запутывание кода – это процесс приведения исходного текста или исполняемого кода программы к виду, сохраняющему ее функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции.
Сейчас имеются разные алгоритмы, которые производят обфускацию. В данной работе будет рассмотрен алгоритм Chenxi Wang s, как один из наиболее известных [1].

Анализ Chenxi Wang's алгоритма

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

1. Проектирование графа потока управления процедурой. Граф задаётся множеством вершин (блоков) и множеством ребер (связей). Затем граф разбивается, заменяя циклические конструкции на конструкции "if (условие) goto".

2. Производится нумерация всех вершин с добавлением в код процедуры переменной (например "postNumber"), отвечающей за номер следующего выполняемого блока.

3. Преобразование графа к однородному ("плоскому") виду.

Основные недостатки

В классическом варианте алгоритм "Chenxi Wang's algorithm" обладает плохой устойчивостью. Это связано с простотой определения следующего выполняемого блока. Как было предложено выше, его можно хранить в переменной "postNumber". Для повышения устойчивости можно ввести массив (например "@gg"), содержащий кроме номеров блоков, бессмысленную информацию. Таким образом происходит модификация записи "$ = S6" в "$postNumber = $gg($gg(1) + $gg(3))".

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

Пример использования модифицированного Chenxi Wang's

Для начала отметим, что в силу ограничений языка программирования Java, условные переходы к меткам применять нельзя. В данном примере они были заменены на циклический переход в конструкции switch-case.

Для анализа эффективности Chenxi Wang's возьмем простой пример:

public class ExampleClass extends ArrayList {

private static Integer instance = null;

public static void main(String`[]` args) { hello(); world(); }

private static void hello() { System.out.print("Hello "); }

private static void world(){ System.out.print("World!!!rn"); }

}

После обработки алгоритмом получаем на выходе

Листинг вывода

run:

1363432304488

public class ExampleClass extends ArrayList{private static Integer instance = null;public static void main(String`[]` args){java.util.Stack stack = new java.util.Stack<>(); stack.push(1);int postNumber; while(stack.size()>0){postNumber = stack.pop(); switch(postNumber){case 1:stack.push(4);stack.push(2);break;case 4: stack.push(5); stack.push(3); break;case 5: break;case 2:System.out.print("Hello");break;case 3: System.out.print("World!!!rn"); break;}}}}

1363432304492

BUILD SUCCESSFUL (total time: 0 seconds)

Анализ полученного результата

Для полноты проведения анализа алгоритма требуется произвести обратное преобразование в ручном режиме [2,3]. Для этого сначала полученный код приводится к виду, согласно Code Style Convention (CSC) для языка программирования Java.

Обфусцированный код

Код приведенный согласно CSC

public class ExampleClass extends ArrayList<String>{private static Integer instance = null;public static void main(String`[]` args){java.util.Stack<Integer> stack = new java.util.Stack<>(); stack.push(1);int postNumber; while(stack.size()>0){postNumber = stack.pop(); switch(postNumber){case 1:stack.push(4);stack.push(2);break;case 4:

stack.push(5);stack.push(3);break;case 5:break;case 2:System.out.print("Hello ");break;case 3:System.out.print("World!!!rn");break;}}}}

public class ExampleClass extends ArrayList<String> {

private static Integer instance = null;

public static void main(String`[]` args) {

java.util.Stack<Integer> stack = new java.util.Stack<>();

stack.push(1);

int postNumber;

while (stack.size() > 0) {

postNumber = stack.pop();

switch (postNumber) {

case 1:

stack.push(4);

stack.push(2);

break;

case 4:

stack.push(5);

stack.push(3);

break;

case 5:

break;

case 2:

System.out.print("Hello ");

break;

case 3: System.out.print("World!!!rn");

break;

}

}

}

}

В данном примере можно увидеть, что любой switch-case вызывается всего 1 раз, и инициируется одним случаем. Это подсказывает путь, при котором все вызовы сводятся к одному, естественно учитывая порядок вызова. После удаления цикла, отрабатывающего всего один раз, получам следующий исходный код:

public class ExampleClass extends ArrayList<String> {

private static Integer instance = null;

public static void main(String`[]` args) {

System.out.print("Hello ");

System.out.print("World!!!rn");

}

}

Этот исходный код получен исключительно за счет того, что каждый из переключателей switch-case использован один раз. При более сложном графе управления, проведение такого анализа не представляется возможным [4].

Заключение

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

References
1. Christian, C. A Taxonomy of Obfuscating Transformations// Christian Collberg, Clark Thomborson. Douglas Low//Technical Report #148. Department of Computer Science. The University of Auckland. July. 1997.
2. Chernov, L. V. Analiz zaputyvayushchikh preobrazovanii programm/L.V. Chernov//Trudy Instituta sistemnogo programmirovaniya RAN. Tom 3, 2002 g. ctr. 7-38.
3. Rollcs, R. Unpacking virtualization obfuscators/R. Rollcs.//In Proc. 3rd USENIX Workshop on Offensive Technologies (WOOT'09), August 2009.
4. Tikhonov, A. Yu. Metodika izvlecheniya algoritma iz binarnogo koda na osnove dinamicheskogo analiza/ A.Yu.Tikhonov, L.I.Avetisyan, V.A.Iadaryan// Problemy informatsionnoi bezopasnosti. Komp'yuternye sistemy. — 2008. — T. №3. — S. 66-71.