├── Obfuscator ├── README.md ├── ast.cpp ├── ast.h ├── bis.y ├── code_generator.cpp ├── code_generator.h ├── compile.sh ├── input.txt ├── lex.l ├── main.cpp ├── obfuscator.cpp ├── obfuscator.h ├── output.html └── samples ├── Combination.html ├── Combination.txt ├── Selection sort.html ├── Selection sort.txt ├── test.html └── test.txt /Obfuscator: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kandeh/Code-Obfuscator/eb918fee149b5723ecf07a3c0e2f3d820dcf1f17/Obfuscator -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code Obfuscation via Control Flow Flattening 2 | 3 | sample input: 4 | ```c 5 | int min(int a, int b) { 6 | if((a < b)) { 7 | return a; 8 | } 9 | return b; 10 | } 11 | 12 | 13 | int Combination(int n, int k) { 14 | int C[(n + 1)][(k + 1)]; 15 | int i; 16 | int j; 17 | for(i = 0; (i <= n); (i++)) { 18 | for(j = 0; (j <= min(i, k)); (j++)) { 19 | if(((j == 0) || (j == i))) { 20 | C[i][j] = 1; 21 | } else { 22 | C[i][j] = (C[(i - 1)][(j - 1)] + C[(i - 1)][j]); 23 | } 24 | } 25 | } 26 | return C[n][k]; 27 | } 28 | 29 | 30 | int main() { 31 | int n = 0; 32 | int k = 0; 33 | int c = Combination(n, k); 34 | printf("(%d, %d) = %d\n", n, k, c); 35 | return 0; 36 | } 37 | ``` 38 | sample output: 39 | ```c 40 | int min(int a, int b) { 41 | int __st__ = 1; 42 | while(__st__) { 43 | if((__st__ == 1)) { 44 | if((a < b)) { 45 | __st__ = 3; 46 | continue; 47 | } 48 | __st__ = 2; 49 | continue; 50 | } 51 | if((__st__ == 2)) { 52 | return b; 53 | __st__ = 0; 54 | continue; 55 | } 56 | if((__st__ == 3)) { 57 | return a; 58 | __st__ = 2; 59 | continue; 60 | } 61 | } 62 | } 63 | 64 | 65 | int Combination(int n, int k) { 66 | int C[(n + 1)][(k + 1)]; 67 | int i; 68 | int j; 69 | int __st__ = 1; 70 | while(__st__) { 71 | if((__st__ == 1)) { 72 | i = 0; 73 | __st__ = 2; 74 | continue; 75 | } 76 | if((__st__ == 2)) { 77 | if((i <= n)) { 78 | __st__ = 4; 79 | continue; 80 | } 81 | __st__ = 3; 82 | continue; 83 | } 84 | if((__st__ == 3)) { 85 | return C[n][k]; 86 | __st__ = 0; 87 | continue; 88 | } 89 | if((__st__ == 4)) { 90 | j = 0; 91 | __st__ = 5; 92 | continue; 93 | } 94 | if((__st__ == 5)) { 95 | if((j <= min(i, k))) { 96 | __st__ = 7; 97 | continue; 98 | } 99 | __st__ = 6; 100 | continue; 101 | } 102 | if((__st__ == 6)) { 103 | (i++); 104 | __st__ = 2; 105 | continue; 106 | } 107 | if((__st__ == 7)) { 108 | if(((j == 0) || (j == i))) { 109 | __st__ = 9; 110 | continue; 111 | } else { 112 | __st__ = 10; 113 | continue; 114 | } 115 | __st__ = 8; 116 | continue; 117 | } 118 | if((__st__ == 8)) { 119 | (j++); 120 | __st__ = 5; 121 | continue; 122 | } 123 | if((__st__ == 9)) { 124 | C[i][j] = 1; 125 | __st__ = 8; 126 | continue; 127 | } 128 | if((__st__ == 10)) { 129 | C[i][j] = (C[(i - 1)][(j - 1)] + C[(i - 1)][j]); 130 | __st__ = 8; 131 | continue; 132 | } 133 | } 134 | } 135 | 136 | 137 | int main() { 138 | int n = 0; 139 | int k = 0; 140 | int c = Combination(n, k); 141 | int __st__ = 1; 142 | while(__st__) { 143 | if((__st__ == 1)) { 144 | printf("(%d, %d) = %d\n", n, k, c); 145 | return 0; 146 | __st__ = 0; 147 | continue; 148 | } 149 | } 150 | } 151 | 152 | ``` 153 | -------------------------------------------------------------------------------- /ast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ast.h" 6 | 7 | using namespace std; 8 | 9 | ast_node *tree; 10 | 11 | void ast_node::add_child(ast_node* node) { 12 | childs.push_back(node); 13 | } 14 | 15 | ast_node* set_st_(ast_node* st_id, int st) { 16 | ast_node* tmp; 17 | tmp = new_node(node_type_assign, 0); 18 | tmp->add_child(st_id); 19 | tmp->add_child(new_node(node_type_int, st)); 20 | return tmp; 21 | } 22 | 23 | void ast_node::set_obf_next_st(ast_node* st_id, int next_st) { 24 | obf_change_st = set_st_(st_id, next_st); 25 | } 26 | 27 | void ast_node::set_obf_break_continue_st(int break_st, int continue_st) { 28 | continue_next_st = continue_st; 29 | break_next_st = break_st; 30 | } 31 | 32 | void ast_node::set_obf_next_st(ast_node* line) { 33 | obf_change_st = line; 34 | } 35 | 36 | ast_node* new_node(int type, long long int tag) { 37 | ast_node* res; 38 | res = new ast_node; 39 | res->type = type; 40 | res->tag = tag; 41 | if(type == node_type_int) 42 | { 43 | res->value = tag; 44 | } 45 | if(type == node_type_exp) 46 | { 47 | res->op = tag; 48 | } 49 | res->obf_change_st = NULL; 50 | res->break_next_st = -1; 51 | res->continue_next_st = -1; 52 | return res; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /ast.h: -------------------------------------------------------------------------------- 1 | #ifndef __ast_H__ 2 | 3 | #define __ast_H__ 4 | 5 | #include 6 | 7 | #define node_type_exp 1 8 | #define node_type_int 2 9 | #define node_type_blocks 4 10 | #define node_type_func_def 5 11 | #define node_type_global_var_def 6 12 | #define node_type_parameter 7 13 | #define node_type_parameters 8 14 | #define node_type_lines 9 15 | #define node_type_line_return 10 16 | #define node_type_call 11 17 | #define node_type_params_set 12 18 | #define node_type_param 13 19 | #define node_type_id 14 20 | #define node_type_end_line 15 21 | #define node_type_var_def 16 22 | #define node_type_return 17 23 | #define node_type_assign 18 24 | #define node_type_assign_array 19 25 | #define node_type_array 20 26 | #define node_type_string 21 27 | #define node_type_for_block 22 28 | #define node_type_if_block 23 29 | #define node_type_indexes_set 24 30 | #define node_type_index 25 31 | #define node_type_while_block 26 32 | #define node_type_inits_set 27 33 | #define node_type_switch_block 28 34 | #define node_type_break_line 29 35 | #define node_type_continue_line 30 36 | 37 | #define op_plus 1 38 | #define op_minus 2 39 | #define op_star 3 40 | #define op_divide 4 41 | #define op_equal 5 42 | #define op_not_equal 6 43 | #define op_less 7 44 | #define op_more 8 45 | 46 | #define op_less_or_equal 9 47 | #define op_more_or_equal 10 48 | 49 | #define op_or 11 50 | #define op_and 12 51 | #define op_mod 13 52 | #define op_not 14 53 | 54 | #define op_plus_plus 15 55 | #define op_minus_minus 16 56 | 57 | #define op_address 17 58 | 59 | #define line_type_return 600 60 | #define line_type_assign 700 61 | #define line_type_def 800 62 | #define line_type_exp 900 63 | 64 | 65 | struct ast_node { 66 | std::vector childs; 67 | 68 | int type; 69 | int op; 70 | long long int value; 71 | char *str; 72 | char *id; 73 | long long int tag; 74 | void add_child(ast_node* node); 75 | void print(); 76 | void print_obfuscated(); 77 | void set_obf_next_st(ast_node* st_id, int next_st); 78 | void set_obf_next_st(ast_node* line); 79 | void set_obf_break_continue_st(int break_st, int continue_st); 80 | 81 | ast_node* obf_change_st; 82 | int continue_next_st; 83 | int break_next_st; 84 | }; 85 | 86 | extern ast_node *tree; 87 | 88 | ast_node* new_node(int type, long long int tag); 89 | 90 | #endif -------------------------------------------------------------------------------- /bis.y: -------------------------------------------------------------------------------- 1 | %token ID COMMA OPEN_PAR CLOSE_PAR IF FOR INTEGER ELSE EQUAL STAR PLUS MINUS DIVIDE END_BR BEGIN_BR RETURN ASSIGN BREAK AND 2 | %token ADDRESS_AND CONTINUE MINUS_MINUS PLUS_PLUS MOD NOT OR SEMICOLON STRING_CONST NOTEQUAL LESS MORE LESS_OR_EQUAL MORE_OR_EQUAL WHILE INT_VAR_TYPE BEGIN_CU END_CU EOF_ 3 | %{ 4 | 5 | #include "ast.h" 6 | #include 7 | #include 8 | #include 9 | 10 | extern void yyerror(char *msg); 11 | 12 | extern int yylex(); 13 | extern int yyparse(); 14 | extern FILE* yyin; 15 | 16 | %} 17 | 18 | %union{ 19 | char *str; 20 | struct ast_node *node; 21 | int d; 22 | } 23 | 24 | %type INTEGER ID STRING_CONST 25 | %type for_block continue_line break_line inits_ inits init lines_ parameters parameter parameters_def while_block integer exp line lines program id block blocks var_def func_def end_line params param call return_line exp_line assign_line array string_const if_block indexes index 26 | 27 | 28 | %left OR 29 | %left AND 30 | 31 | %left EQUAL 32 | %left NOTEQUAL 33 | 34 | %left LESS 35 | %left MORE 36 | %left LESS_OR_EQUAL 37 | %left MORE_OR_EQUAL 38 | 39 | 40 | 41 | 42 | %left PLUS 43 | %left MINUS 44 | %left STAR 45 | %left DIVIDE 46 | %left MOD 47 | 48 | 49 | %right NOT 50 | %right ADDRESS_AND 51 | 52 | %left PLUS_PLUS 53 | %left MINUS_MINUS 54 | 55 | %% 56 | 57 | program: blocks { tree = $1; return NULL; }; 58 | 59 | blocks: blocks block 60 | { 61 | 62 | $1->add_child($2); 63 | $$ = $1; 64 | } 65 | 66 | | block 67 | { 68 | 69 | $$ = new_node(node_type_blocks, 0); 70 | $$->add_child($1); 71 | }; 72 | 73 | block: var_def 74 | { 75 | $$ = $1; 76 | } 77 | 78 | | func_def 79 | { 80 | $$ = $1; 81 | }; 82 | 83 | 84 | var_def: INT_VAR_TYPE id SEMICOLON 85 | { 86 | $$ = new_node(node_type_var_def, 0); 87 | $$->add_child($2); 88 | $$->add_child(NULL); 89 | $$->add_child(NULL); 90 | } 91 | | INT_VAR_TYPE id ASSIGN exp SEMICOLON 92 | { 93 | $$ = new_node(node_type_var_def, 0); 94 | $$->add_child($2); 95 | $$->add_child($4); 96 | $$->add_child(NULL); 97 | } 98 | | INT_VAR_TYPE id indexes SEMICOLON 99 | { 100 | $$ = new_node(node_type_var_def, 0); 101 | $$->add_child($2); 102 | $$->add_child(NULL); 103 | $$->add_child($3); 104 | } 105 | | INT_VAR_TYPE id indexes ASSIGN inits SEMICOLON 106 | { 107 | $$ = new_node(node_type_var_def, 0); 108 | $$->add_child($2); 109 | $$->add_child($5); 110 | $$->add_child($3); 111 | }; 112 | 113 | func_def: 114 | INT_VAR_TYPE id OPEN_PAR parameters_def CLOSE_PAR lines 115 | { 116 | 117 | $$ = new_node(node_type_func_def, 0); 118 | $$->add_child($2); // id 119 | $$->add_child($4); // parameters_def 120 | $$->add_child($6); // lines 121 | } 122 | | INT_VAR_TYPE id OPEN_PAR parameters_def CLOSE_PAR end_line 123 | { 124 | 125 | $$ = new_node(node_type_func_def, 0); 126 | $$->add_child($2); // id 127 | $$->add_child($4); // parameters_def 128 | $$->add_child(NULL); // lines 129 | }; 130 | 131 | parameters_def: parameters 132 | { 133 | $$ = $1; 134 | } 135 | | 136 | { 137 | $$ = NULL; 138 | }; 139 | 140 | parameters: parameters COMMA parameter 141 | { 142 | $$ = $1; 143 | $$->add_child($3); 144 | } 145 | | parameter 146 | { 147 | $$ = new_node(node_type_parameters, 0); 148 | $$->add_child($1); 149 | }; 150 | 151 | 152 | 153 | 154 | parameter: INT_VAR_TYPE id 155 | { 156 | $$ = new_node(node_type_parameter, 0); 157 | $$->add_child($2); 158 | }; 159 | 160 | lines: BEGIN_CU lines_ END_CU 161 | { 162 | $$ = $2; 163 | } 164 | | BEGIN_CU END_CU 165 | { 166 | $$ = NULL; 167 | }; 168 | 169 | lines_: lines_ line 170 | { 171 | $$ = $1; 172 | $$->add_child($2); 173 | } 174 | | line 175 | { 176 | $$ = new_node(node_type_lines, 0); 177 | $$->add_child($1); 178 | }; 179 | 180 | if_block: IF OPEN_PAR exp CLOSE_PAR lines 181 | { 182 | $$ = new_node(node_type_if_block, 0); 183 | $$->add_child($3); // exp 184 | $$->add_child($5); // lines 185 | $$->add_child(NULL); // else_lines 186 | } 187 | | IF OPEN_PAR exp CLOSE_PAR lines ELSE lines 188 | { 189 | $$ = new_node(node_type_if_block, 0); 190 | $$->add_child($3); // exp 191 | $$->add_child($5); // lines 192 | $$->add_child($7); // else_lines 193 | }; 194 | 195 | while_block: WHILE OPEN_PAR exp CLOSE_PAR lines 196 | { 197 | $$ = new_node(node_type_while_block, 0); 198 | $$->add_child($3); // exp 199 | $$->add_child($5); // lines 200 | }; 201 | 202 | for_block: FOR OPEN_PAR id ASSIGN exp SEMICOLON exp SEMICOLON exp CLOSE_PAR lines 203 | { 204 | $$ = new_node(node_type_for_block, 0); 205 | $$->add_child($3); // id 206 | $$->add_child($5); // exp 207 | $$->add_child($7); // exp 208 | $$->add_child($9); // exp 209 | $$->add_child($11); // lines 210 | }; 211 | 212 | 213 | line: return_line {$$ = $1;} 214 | | break_line {$$ = $1;} 215 | | continue_line {$$ = $1;} 216 | | var_def {$$ = $1;} 217 | | exp_line {$$ = $1;} 218 | | assign_line {$$ = $1;} 219 | | if_block {$$ = $1;} 220 | | for_block {$$ = $1;} 221 | | while_block {$$ = $1;} 222 | | end_line {$$ == NULL; }; 223 | 224 | 225 | end_line: SEMICOLON 226 | { 227 | $$ = new_node(node_type_end_line, 0); 228 | }; 229 | 230 | 231 | return_line: RETURN exp end_line 232 | { 233 | $$ = new_node(node_type_return, 0); 234 | $$->add_child($2); 235 | }; 236 | 237 | exp_line: exp end_line 238 | { 239 | $$ = $1; 240 | }; 241 | 242 | break_line: BREAK end_line 243 | { 244 | $$ = new_node(node_type_break_line, 0); 245 | }; 246 | 247 | continue_line: CONTINUE end_line 248 | { 249 | $$ = new_node(node_type_continue_line, 0); 250 | }; 251 | 252 | 253 | assign_line: 254 | id ASSIGN exp end_line 255 | { 256 | $$ = new_node(node_type_assign, 0); 257 | $$->add_child($1); 258 | $$->add_child($3); 259 | } 260 | | array ASSIGN exp end_line 261 | { 262 | $$ = new_node(node_type_assign_array, 0); 263 | $$->add_child($1); 264 | $$->add_child($3); 265 | }; 266 | 267 | 268 | 269 | exp: exp EQUAL exp {$$ = new_node(node_type_exp, op_equal); $$->add_child($1); $$->add_child($3); } 270 | | exp NOTEQUAL exp {$$ = new_node(node_type_exp, op_not_equal); $$->add_child($1); $$->add_child($3); } 271 | | exp LESS exp {$$ = new_node(node_type_exp, op_less); $$->add_child($1); $$->add_child($3); } 272 | | exp MORE exp {$$ = new_node(node_type_exp, op_more); $$->add_child($1); $$->add_child($3); } 273 | | exp PLUS exp {$$ = new_node(node_type_exp, op_plus); $$->add_child($1); $$->add_child($3); } 274 | | exp MINUS exp {$$ = new_node(node_type_exp, op_minus); $$->add_child($1); $$->add_child($3); } 275 | | exp STAR exp {$$ = new_node(node_type_exp, op_star); $$->add_child($1); $$->add_child($3); } 276 | | exp DIVIDE exp {$$ = new_node(node_type_exp, op_divide); $$->add_child($1); $$->add_child($3); } 277 | 278 | | exp OR exp {$$ = new_node(node_type_exp, op_or); $$->add_child($1); $$->add_child($3); } 279 | | exp AND exp {$$ = new_node(node_type_exp, op_and); $$->add_child($1); $$->add_child($3); } 280 | | exp MOD exp {$$ = new_node(node_type_exp, op_mod); $$->add_child($1); $$->add_child($3); } 281 | 282 | | NOT exp {$$ = new_node(node_type_exp, op_not); $$->add_child($2); } 283 | 284 | | ADDRESS_AND exp {$$ = new_node(node_type_exp, op_address); $$->add_child($2); } 285 | 286 | | id PLUS_PLUS {$$ = new_node(node_type_exp, op_plus_plus); $$->add_child($1); } 287 | | id MINUS_MINUS {$$ = new_node(node_type_exp, op_minus_minus); $$->add_child($1); } 288 | 289 | | array PLUS_PLUS {$$ = new_node(node_type_exp, op_plus_plus); $$->add_child($1); } 290 | | array MINUS_MINUS {$$ = new_node(node_type_exp, op_minus_minus); $$->add_child($1); } 291 | 292 | | exp MORE_OR_EQUAL exp {$$ = new_node(node_type_exp, op_more_or_equal); $$->add_child($1); $$->add_child($3); } 293 | | exp LESS_OR_EQUAL exp {$$ = new_node(node_type_exp, op_less_or_equal); $$->add_child($1); $$->add_child($3); } 294 | 295 | | OPEN_PAR exp CLOSE_PAR {$$ = $2;} 296 | | integer {$$ = $1;} 297 | | id {$$ = $1;} 298 | | call {$$ = $1;} 299 | | array {$$ = $1;} 300 | | string_const {$$ = $1;}; 301 | 302 | call: id OPEN_PAR params CLOSE_PAR 303 | { 304 | $$ = new_node(node_type_call, 0); 305 | $$->add_child($1); 306 | $$->add_child($3); 307 | }; 308 | 309 | array: id indexes 310 | { 311 | $$ = new_node(node_type_array, 0); 312 | $$->add_child($1); 313 | $$->add_child($2); 314 | }; 315 | 316 | indexes: indexes index 317 | { 318 | $$ = $1; 319 | $$->add_child($2); 320 | } 321 | | index 322 | { 323 | $$ = new_node(node_type_indexes_set, 0); 324 | $$->add_child($1); 325 | }; 326 | 327 | index: BEGIN_BR exp END_BR 328 | { 329 | $$ = $2; 330 | } 331 | | BEGIN_BR END_BR 332 | { 333 | $$ = NULL; 334 | }; 335 | 336 | integer: INTEGER { 337 | $$ = new_node(node_type_int, atoi($1)); 338 | }; 339 | 340 | 341 | params: params COMMA param 342 | { 343 | $$ = $1; 344 | $$->add_child($3); 345 | } 346 | | param 347 | { 348 | $$ = new_node(node_type_params_set, 0); 349 | $$->add_child($1); 350 | } 351 | | {$$ = NULL;}; 352 | 353 | param: exp 354 | { 355 | $$ = $1; 356 | }; 357 | 358 | 359 | inits: BEGIN_CU inits_ END_CU 360 | { 361 | $$ = $2; 362 | } 363 | 364 | inits_: inits_ COMMA init 365 | { 366 | $$ = $1; 367 | $$->add_child($3); 368 | } 369 | | init 370 | { 371 | $$ = new_node(node_type_inits_set, 0); 372 | $$->add_child($1); 373 | }; 374 | 375 | init: exp 376 | { 377 | $$ = $1; 378 | }; 379 | 380 | 381 | id: ID 382 | { 383 | $$ = new_node(node_type_id, 0); 384 | $$->id = $1; 385 | }; 386 | 387 | string_const: STRING_CONST 388 | { 389 | $$ = new_node(node_type_string, 0); 390 | $$->str = $1; 391 | }; 392 | 393 | %% 394 | 395 | 396 | void yyerror(char *msg) { 397 | printf("%s\n", msg); 398 | //system("pause"); 399 | exit(1); 400 | } 401 | -------------------------------------------------------------------------------- /code_generator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "code_generator.h" 4 | 5 | using namespace std; 6 | 7 | void print_tabs(int tabs) { 8 | int tab_len = 3; 9 | for(int i = 0; i < tabs; i++) { 10 | for(int k = 0; k < tab_len; k++) { 11 | cout << " "; 12 | } 13 | } 14 | } 15 | 16 | void print_params(ast_node* pnode) { 17 | if(pnode == NULL) { 18 | return; 19 | } 20 | ast_node* ch; 21 | int len = pnode->childs.size(); 22 | for(int i = 0; i < len; i++) { 23 | ch = pnode->childs[i]; 24 | print_exp(ch); 25 | 26 | if(i < len - 1) { 27 | cout << ", "; 28 | } 29 | } 30 | } 31 | 32 | void print_indexes(ast_node* inode) { 33 | ast_node* ch; 34 | int len = inode->childs.size(); 35 | for(int i = 0; i < len; i++) { 36 | ch = inode->childs[i]; 37 | cout << "["; 38 | if(ch != NULL) { 39 | print_exp(ch); 40 | } 41 | cout << "]"; 42 | } 43 | 44 | } 45 | 46 | void print_exp(ast_node* enode) { 47 | if(enode->type == node_type_int) { 48 | cout << enode->value; 49 | return; 50 | } 51 | if(enode->type == node_type_id) { 52 | cout << enode->id; 53 | return; 54 | } 55 | if(enode->type == node_type_array) { 56 | cout << enode->childs[0]->id; 57 | print_indexes(enode->childs[1]); 58 | return; 59 | } 60 | 61 | if(enode->type == node_type_string) { 62 | cout << "\"" << enode->str << "\""; 63 | return; 64 | } 65 | 66 | if(enode->type == node_type_exp) { 67 | string op = ""; 68 | cout << "("; 69 | switch(enode->tag) { 70 | case op_equal: print_exp(enode->childs[0]); cout << " == "; print_exp(enode->childs[1]); break; 71 | case op_not_equal: print_exp(enode->childs[0]); cout << " != "; print_exp(enode->childs[1]); break; 72 | case op_less: print_exp(enode->childs[0]); cout << " < "; print_exp(enode->childs[1]); break; 73 | case op_more: print_exp(enode->childs[0]); cout << " > "; print_exp(enode->childs[1]); break; 74 | case op_plus: print_exp(enode->childs[0]); cout << " + "; print_exp(enode->childs[1]); break; 75 | case op_minus: print_exp(enode->childs[0]); cout << " - "; print_exp(enode->childs[1]); break; 76 | case op_divide: print_exp(enode->childs[0]); cout << " / "; print_exp(enode->childs[1]); break; 77 | case op_star: print_exp(enode->childs[0]); cout << " * "; print_exp(enode->childs[1]); break; 78 | case op_and: print_exp(enode->childs[0]); cout << " && "; print_exp(enode->childs[1]); break; 79 | case op_or: print_exp(enode->childs[0]); cout << " || "; print_exp(enode->childs[1]); break; 80 | case op_not: cout << "!"; print_exp(enode->childs[0]); break; 81 | case op_address: cout << "&"; print_exp(enode->childs[0]); break; 82 | case op_plus_plus: print_exp(enode->childs[0]); cout << "++"; break; 83 | case op_minus_minus: print_exp(enode->childs[0]); cout << "--"; break; 84 | case op_mod: print_exp(enode->childs[0]); cout << " % "; print_exp(enode->childs[1]); break; 85 | case op_more_or_equal: print_exp(enode->childs[0]); cout << " >= "; print_exp(enode->childs[1]); break; 86 | case op_less_or_equal: print_exp(enode->childs[0]); cout << " <= "; print_exp(enode->childs[1]); break; 87 | 88 | } 89 | cout << ")"; 90 | return; 91 | } 92 | 93 | if(enode->type == node_type_call) { 94 | cout << enode->childs[0]->id << "("; 95 | print_params(enode->childs[1]); 96 | cout << ")"; 97 | return; 98 | } 99 | } 100 | 101 | void print_arr_init(ast_node* ainode) { 102 | ast_node* ch; 103 | int len = ainode->childs.size(); 104 | cout << "{"; 105 | for(int i = 0; i < len; i++) { 106 | ch = ainode->childs[i]; 107 | print_exp(ch); 108 | if(i < len - 1) { 109 | cout << ", "; 110 | } 111 | } 112 | cout << "}"; 113 | } 114 | 115 | void print_line(int tabs, ast_node* lnode) { 116 | if(lnode->type == node_type_return) { 117 | print_tabs(tabs); 118 | cout << "return "; 119 | print_exp(lnode->childs[0]); 120 | cout << ";" << endl; 121 | return; 122 | } 123 | if(lnode->type == node_type_var_def) { 124 | print_tabs(tabs); 125 | cout << "int "; 126 | cout << (lnode->childs[0]->id); 127 | if(lnode->childs[2] != NULL) { 128 | print_indexes(lnode->childs[2]); 129 | } 130 | if(lnode->childs[1] != NULL) { 131 | cout << " = "; 132 | if(lnode->childs[1]->type == node_type_inits_set) { 133 | print_arr_init(lnode->childs[1]); 134 | } else { 135 | print_exp(lnode->childs[1]); 136 | } 137 | } 138 | cout << ";" << endl; 139 | return; 140 | } 141 | 142 | if(lnode->type == node_type_if_block) { 143 | print_tabs(tabs); 144 | cout << "if("; 145 | print_exp(lnode->childs[0]); 146 | cout << ") {" << endl; 147 | print_lines(tabs + 1, lnode->childs[1]); 148 | print_tabs(tabs); 149 | cout << "}"; 150 | 151 | if(lnode->childs[2] != NULL) { 152 | cout << " else {" << endl; 153 | print_lines(tabs + 1, lnode->childs[2]); 154 | print_tabs(tabs); 155 | cout << "}"; 156 | } 157 | cout << endl; 158 | return; 159 | } 160 | 161 | if(lnode->type == node_type_for_block) { 162 | print_tabs(tabs); 163 | cout << "for("; 164 | print_exp(lnode->childs[0]); 165 | cout << " = "; 166 | print_exp(lnode->childs[1]); 167 | cout << "; "; 168 | print_exp(lnode->childs[2]); 169 | cout << "; "; 170 | print_exp(lnode->childs[3]); 171 | cout << ") {" << endl; 172 | print_lines(tabs + 1, lnode->childs[4]); 173 | print_tabs(tabs); 174 | cout << "}"; 175 | cout << endl; 176 | return; 177 | } 178 | 179 | if(lnode->type == node_type_while_block) { 180 | print_tabs(tabs); 181 | cout << "while("; 182 | print_exp(lnode->childs[0]); 183 | cout << ") {" << endl; 184 | print_lines(tabs + 1, lnode->childs[1]); 185 | print_tabs(tabs); 186 | cout << "}"; 187 | cout << endl; 188 | return; 189 | } 190 | 191 | if(lnode->type == node_type_break_line) { 192 | print_tabs(tabs); 193 | cout << "break;" << endl; 194 | return; 195 | } 196 | if(lnode->type == node_type_continue_line) { 197 | print_tabs(tabs); 198 | cout << "continue;" << endl; 199 | return; 200 | } 201 | if(lnode->type == node_type_call || lnode->type == node_type_exp) { 202 | print_tabs(tabs); 203 | print_exp(lnode); 204 | cout << ";" << endl; 205 | return; 206 | } 207 | if(lnode->type == node_type_assign || lnode->type == node_type_assign_array) { 208 | print_tabs(tabs); 209 | print_exp(lnode->childs[0]); 210 | cout << " = "; 211 | print_exp(lnode->childs[1]); 212 | cout << ";" << endl; 213 | return; 214 | } 215 | } 216 | 217 | void print_lines(int tabs, ast_node* lnode) { 218 | if(lnode == NULL) { 219 | return; 220 | } 221 | int len = lnode->childs.size(); 222 | ast_node* ch; 223 | for(int i = 0; i < len; i++) { 224 | ch = lnode->childs[i]; 225 | print_line(tabs, ch); 226 | } 227 | if(lnode->obf_change_st != NULL) { 228 | print_line(tabs, lnode->obf_change_st); 229 | print_line(tabs, new_node(node_type_continue_line, 0)); 230 | } 231 | } 232 | 233 | void print_func(ast_node* fnode) { 234 | cout << endl; 235 | cout << "int " << fnode->childs[0]->id << "("; 236 | ast_node* ch; 237 | if(fnode->childs[1] != NULL) { 238 | int len = fnode->childs[1]->childs.size(); 239 | for(int i = 0; i < len; i++) { 240 | ch = fnode->childs[1]->childs[i]; 241 | cout << "int " << ch->childs[0]->id; 242 | if(i < len - 1) { 243 | cout << ", "; 244 | } 245 | } 246 | } 247 | cout << ") {" << endl; 248 | 249 | if(fnode->childs[2] != NULL) { 250 | print_lines(1, fnode->childs[2]); 251 | } 252 | 253 | cout << "}" << endl; 254 | cout << endl; 255 | } 256 | 257 | void print_program(ast_node* tree) { 258 | if(tree->type == node_type_func_def) { 259 | print_func(tree); 260 | return; 261 | } 262 | if(tree->type == node_type_var_def) { 263 | print_line(0, tree); 264 | return; 265 | } 266 | for(int i = 0; i < tree->childs.size(); i++) { 267 | if(tree->childs[i] != NULL) { 268 | print_program(tree->childs[i]); 269 | } 270 | } 271 | } -------------------------------------------------------------------------------- /code_generator.h: -------------------------------------------------------------------------------- 1 | #ifndef __code_generator_H__ 2 | 3 | #define __code_generator_H__ 4 | 5 | #include "ast.h" 6 | 7 | void print_program(ast_node* tree); 8 | void print_func(ast_node* fnode); 9 | void print_lines(int tabs, ast_node* lnode); 10 | void print_line(int tabs, ast_node* lnode); 11 | void print_arr_init(ast_node* ainode); 12 | void print_exp(ast_node* enode); 13 | void print_indexes(ast_node* inode); 14 | void print_params(ast_node* pnode); 15 | void print_tabs(int tabs); 16 | 17 | #endif -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | bison -v -yd bis.y 2 | flex lex.l 3 | g++ -c lex.yy.c 4 | g++ -c y.tab.c 5 | g++ -o Obfuscator -std=c++11 main.cpp ast.cpp code_generator.cpp obfuscator.cpp y.tab.o lex.yy.o 6 | -------------------------------------------------------------------------------- /input.txt: -------------------------------------------------------------------------------- 1 | int min(int a, int b) { 2 | if(a < b) { 3 | return a; 4 | } 5 | return b; 6 | } 7 | 8 | int Combination(int n, int k) { 9 | int C[n + 1][k + 1]; 10 | int i; 11 | int j; 12 | for(i = 0; i <= n; i++) { 13 | for(j = 0; j <= min(i, k); j++) { 14 | if(j == 0 || j == i) { 15 | C[i][j] = 1; 16 | } else { 17 | C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; 18 | } 19 | } 20 | } 21 | return C[n][k]; 22 | } 23 | 24 | int main() { 25 | int n = 0; 26 | int k = 0; 27 | int c = Combination(n, k); 28 | printf("(%d, %d) = %d\n", n, k, c); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /lex.l: -------------------------------------------------------------------------------- 1 | %option noyywrap 2 | %option always-interactive 3 | %{ 4 | #include 5 | #include "y.tab.h" 6 | #include 7 | void set_value(); 8 | void set_str_value(); 9 | using namespace std; 10 | %} 11 | 12 | LETTER [a-zA-Z_] 13 | DIGIT [0-9] 14 | INT {DIGIT}+ 15 | NEWLINE [\n] 16 | WSPACE [ \t\r\n]+ 17 | IDENT {LETTER}({LETTER}|{DIGIT})* 18 | STR \"[^\"]*\" 19 | 20 | %% 21 | {STR} {set_str_value(); return STRING_CONST;} 22 | "int" {return INT_VAR_TYPE;} 23 | "break" {return BREAK;} 24 | "continue" {return CONTINUE;} 25 | "while" {return WHILE;} 26 | "if" {return IF;} 27 | "else" {return ELSE;} 28 | "for" {return FOR;} 29 | "!" {return NOT;} 30 | "&&" {return AND;} 31 | "&" {return ADDRESS_AND;} 32 | "||" {return OR;} 33 | "%" {return MOD;} 34 | "return" {return RETURN;} 35 | "=" {return ASSIGN;} 36 | "+" {return PLUS;} 37 | "-" {return MINUS;} 38 | "*" {return STAR;} 39 | "/" {return DIVIDE;} 40 | "(" {return OPEN_PAR;} 41 | ")" {return CLOSE_PAR;} 42 | "[" {return BEGIN_BR;} 43 | "]" {return END_BR;} 44 | "{" {return BEGIN_CU;} 45 | "}" {return END_CU;} 46 | "," {return COMMA;} 47 | ";" {return SEMICOLON;} 48 | "<" {return LESS;} 49 | ">" {return MORE;} 50 | "<=" {return LESS_OR_EQUAL;} 51 | ">=" {return MORE_OR_EQUAL;} 52 | "++" {return PLUS_PLUS;} 53 | "--" {return MINUS_MINUS;} 54 | "==" {return EQUAL;} 55 | "!=" {return NOTEQUAL;} 56 | {INT} {set_value(); return INTEGER;} 57 | {IDENT} {set_value(); return ID;} 58 | {NEWLINE} {} 59 | {WSPACE} {} 60 | <> { return EOF_;} 61 | %% 62 | 63 | void set_value() { 64 | int i = strlen(yytext) + 1; 65 | yylval.str = new char[i]; 66 | strcpy(yylval.str, yytext); 67 | } 68 | 69 | void set_str_value() { 70 | int i = strlen(yytext) + 1 - 2; 71 | yylval.str = new char[i]; 72 | yytext[strlen(yytext)-1] = '\0'; 73 | strcpy(yylval.str, yytext + 1); 74 | } 75 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "y.tab.h" 7 | #include "ast.h" 8 | #include "code_generator.h" 9 | #include "obfuscator.h" 10 | 11 | using namespace std; 12 | 13 | extern FILE* yyin; 14 | extern int yyparse (void); 15 | 16 | int main() 17 | { 18 | freopen("output.html", "w", stdout); 19 | 20 | yyin = fopen("input.txt","r"); 21 | yyparse(); 22 | 23 | 24 | cout << "
 
"; 25 | cout << "

input

"; 26 | print_program(tree); 27 | cout << "
"; 28 | 29 | 30 | do_CFA(tree); 31 | 32 | 33 | cout << "
"; 34 | cout << "

control flow obfuscated

"; 35 | print_program(tree); 36 | cout << "
"; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /obfuscator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ast.h" 6 | 7 | void flat_case(ast_node* control_variable_id, int& state_couner, ast_node* node, ast_node* control_while_lines) { 8 | ast_node* case_then_lines; 9 | ast_node* first_line; 10 | ast_node* if_; 11 | ast_node* if_lines; 12 | ast_node* if_condition; 13 | 14 | again: 15 | 16 | case_then_lines = node->childs[1]; 17 | first_line = case_then_lines->childs[0]; 18 | 19 | if(first_line->type == node_type_break_line) { 20 | if(case_then_lines->childs.size() > 1) { 21 | ast_node* if_ = new_node(node_type_if_block, 0); 22 | ast_node* if_condition = new_node(node_type_exp, op_equal); 23 | ast_node* if_lines = new_node(node_type_lines, 0); 24 | if_condition->add_child(control_variable_id); 25 | if_condition->add_child(new_node(node_type_int, state_couner)); 26 | if_->add_child(if_condition); 27 | state_couner++; 28 | control_while_lines->add_child(if_); 29 | if_->add_child(if_lines); 30 | if_->add_child(NULL); 31 | for(int i = 1; i < case_then_lines->childs.size(); i++) { 32 | if_lines->add_child(case_then_lines->childs[i]); 33 | } 34 | 35 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 36 | case_then_lines->set_obf_next_st(control_variable_id, state_couner - 1); 37 | } 38 | case_then_lines->childs.erase(case_then_lines->childs.begin() + 0, case_then_lines->childs.end()); 39 | case_then_lines->set_obf_next_st(control_variable_id, case_then_lines->break_next_st); 40 | 41 | 42 | } else if(first_line->type == node_type_continue_line) { 43 | if(case_then_lines->childs.size() > 1) { 44 | ast_node* if_ = new_node(node_type_if_block, 0); 45 | ast_node* if_condition = new_node(node_type_exp, op_equal); 46 | ast_node* if_lines = new_node(node_type_lines, 0); 47 | if_condition->add_child(control_variable_id); 48 | if_condition->add_child(new_node(node_type_int, state_couner)); 49 | if_->add_child(if_condition); 50 | state_couner++; 51 | control_while_lines->add_child(if_); 52 | if_->add_child(if_lines); 53 | if_->add_child(NULL); 54 | for(int i = 1; i < case_then_lines->childs.size(); i++) { 55 | if_lines->add_child(case_then_lines->childs[i]); 56 | } 57 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 58 | case_then_lines->set_obf_next_st(control_variable_id, state_couner - 1); 59 | } 60 | case_then_lines->childs.erase(case_then_lines->childs.begin() + 0, case_then_lines->childs.end()); 61 | case_then_lines->set_obf_next_st(control_variable_id, case_then_lines->continue_next_st); 62 | 63 | 64 | } else if(first_line->type == node_type_if_block && first_line->childs[1] != NULL) { 65 | if(case_then_lines->childs.size() > 1) { 66 | ast_node* if_ = new_node(node_type_if_block, 0); 67 | ast_node* if_condition = new_node(node_type_exp, op_equal); 68 | ast_node* if_lines = new_node(node_type_lines, 0); 69 | if_condition->add_child(control_variable_id); 70 | if_condition->add_child(new_node(node_type_int, state_couner)); 71 | if_->add_child(if_condition); 72 | state_couner++; 73 | control_while_lines->add_child(if_); 74 | if_->add_child(if_lines); 75 | if_->add_child(NULL); 76 | for(int i = 1; i < case_then_lines->childs.size(); i++) { 77 | if_lines->add_child(case_then_lines->childs[i]); 78 | } 79 | case_then_lines->childs.erase(case_then_lines->childs.begin() + 1, case_then_lines->childs.end()); 80 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 81 | if_lines->set_obf_break_continue_st(case_then_lines->break_next_st, case_then_lines->continue_next_st); 82 | 83 | case_then_lines->set_obf_next_st(control_variable_id, state_couner - 1); 84 | } 85 | 86 | ast_node* if_ = new_node(node_type_if_block, 0); 87 | ast_node* if_condition = new_node(node_type_exp, op_equal); 88 | ast_node* if_lines = new_node(node_type_lines, 0); 89 | if_condition->add_child(control_variable_id); 90 | if_condition->add_child(new_node(node_type_int, state_couner)); 91 | if_->add_child(if_condition); 92 | state_couner++; 93 | control_while_lines->add_child(if_); 94 | if_->add_child(if_lines); 95 | if_->add_child(NULL); 96 | for(int i = 0; i < first_line->childs[1]->childs.size(); i++) { 97 | if_lines->add_child(first_line->childs[1]->childs[i]); 98 | } 99 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 100 | if_lines->set_obf_break_continue_st(case_then_lines->break_next_st, case_then_lines->continue_next_st); 101 | 102 | first_line->childs[1]->childs.clear(); 103 | first_line->childs[1]->set_obf_next_st(control_variable_id, state_couner - 1); 104 | 105 | 106 | if(first_line->childs[2] != NULL) { 107 | ast_node* if_ = new_node(node_type_if_block, 0); 108 | ast_node* if_condition = new_node(node_type_exp, op_equal); 109 | ast_node* if_lines = new_node(node_type_lines, 0); 110 | if_condition->add_child(control_variable_id); 111 | if_condition->add_child(new_node(node_type_int, state_couner)); 112 | if_->add_child(if_condition); 113 | state_couner++; 114 | control_while_lines->add_child(if_); 115 | if_->add_child(if_lines); 116 | if_->add_child(NULL); 117 | 118 | for(int i = 0; i < first_line->childs[2]->childs.size(); i++) { 119 | if_lines->add_child(first_line->childs[2]->childs[i]); 120 | } 121 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 122 | if_lines->set_obf_break_continue_st(case_then_lines->break_next_st, case_then_lines->continue_next_st); 123 | 124 | first_line->childs[2]->childs.clear(); 125 | first_line->childs[2]->set_obf_next_st(control_variable_id, state_couner - 1); 126 | 127 | } 128 | 129 | } else if(first_line->type == node_type_while_block && first_line->childs[1] != NULL) { 130 | if(case_then_lines->childs.size() > 1) { 131 | ast_node* if_ = new_node(node_type_if_block, 0); 132 | ast_node* if_condition = new_node(node_type_exp, op_equal); 133 | ast_node* if_lines = new_node(node_type_lines, 0); 134 | if_condition->add_child(control_variable_id); 135 | if_condition->add_child(new_node(node_type_int, state_couner)); 136 | if_->add_child(if_condition); 137 | state_couner++; 138 | control_while_lines->add_child(if_); 139 | if_->add_child(if_lines); 140 | if_->add_child(NULL); 141 | for(int i = 1; i < case_then_lines->childs.size(); i++) { 142 | if_lines->add_child(case_then_lines->childs[i]); 143 | } 144 | case_then_lines->childs.erase(case_then_lines->childs.begin() + 1, case_then_lines->childs.end()); 145 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 146 | if_lines->set_obf_break_continue_st(case_then_lines->break_next_st, case_then_lines->continue_next_st); 147 | 148 | case_then_lines->set_obf_next_st(control_variable_id, state_couner - 1); 149 | } 150 | 151 | ast_node* if_ = new_node(node_type_if_block, 0); 152 | ast_node* if_condition = new_node(node_type_exp, op_equal); 153 | ast_node* if_lines = new_node(node_type_lines, 0); 154 | if_condition->add_child(control_variable_id); 155 | if_condition->add_child(new_node(node_type_int, state_couner)); 156 | if_->add_child(if_condition); 157 | state_couner++; 158 | control_while_lines->add_child(if_); 159 | if_->add_child(if_lines); 160 | if_->add_child(NULL); 161 | for(int i = 0; i < first_line->childs[1]->childs.size(); i++) { 162 | if_lines->add_child(first_line->childs[1]->childs[i]); 163 | } 164 | if_lines->set_obf_next_st(control_variable_id, node->childs[0]->childs[1]->value); 165 | 166 | if_lines->set_obf_break_continue_st(case_then_lines->obf_change_st->childs[1]->value, node->childs[0]->childs[1]->value); 167 | 168 | first_line->childs[1]->childs.clear(); 169 | first_line->childs[1]->set_obf_next_st(control_variable_id, state_couner - 1); 170 | first_line->type = node_type_if_block; 171 | first_line->add_child(NULL); // else 172 | 173 | } else if(first_line->type == node_type_for_block && first_line->childs[1] != NULL) { 174 | ast_node* assign; 175 | ast_node* lines; 176 | assign = new_node(node_type_assign, 0); 177 | assign->add_child(first_line->childs[0]); 178 | assign->add_child(first_line->childs[1]); 179 | case_then_lines->childs.insert(case_then_lines->childs.begin(), assign); 180 | first_line->type = node_type_while_block; 181 | lines = first_line->childs[4]; 182 | lines->add_child(first_line->childs[3]); 183 | first_line->childs.erase(first_line->childs.begin(), first_line->childs.begin() + 2); 184 | first_line->childs.erase(first_line->childs.begin() + 1); 185 | first_line->add_child(NULL); 186 | goto again; 187 | 188 | } else { 189 | for(int i = 0; i < case_then_lines->childs.size(); i++) { 190 | if(((case_then_lines->childs[i]->type == node_type_for_block 191 | || case_then_lines->childs[i]->type == node_type_if_block 192 | || case_then_lines->childs[i]->type == node_type_while_block) 193 | && case_then_lines->childs[i]->childs[1] != NULL) 194 | || (case_then_lines->childs[i]->type == node_type_break_line 195 | || case_then_lines->childs[i]->type == node_type_continue_line)) { 196 | ast_node* if_ = new_node(node_type_if_block, 0); 197 | ast_node* if_condition = new_node(node_type_exp, op_equal); 198 | ast_node* if_lines = new_node(node_type_lines, 0); 199 | if_condition->add_child(control_variable_id); 200 | if_condition->add_child(new_node(node_type_int, state_couner++)); 201 | if_->add_child(if_condition); 202 | control_while_lines->add_child(if_); 203 | if_->add_child(if_lines); 204 | if_->add_child(NULL); 205 | for(int j = i; j < case_then_lines->childs.size(); j++) { 206 | if_lines->add_child(case_then_lines->childs[j]); 207 | } 208 | case_then_lines->childs.erase(case_then_lines->childs.begin() + i, case_then_lines->childs.end()); 209 | if_lines->set_obf_next_st(case_then_lines->obf_change_st); 210 | case_then_lines->set_obf_next_st(control_variable_id, state_couner - 1); 211 | if_lines->set_obf_break_continue_st(case_then_lines->break_next_st, case_then_lines->continue_next_st); 212 | break; 213 | } 214 | } 215 | } 216 | } 217 | 218 | ast_node* do_CFA_on_function(ast_node* fnode) { 219 | int state_couner = 1; 220 | ast_node* ch; 221 | ast_node* otree = new_node(node_type_func_def, 0); 222 | ast_node* olines = new_node(node_type_lines, 0); 223 | 224 | otree->add_child(fnode->childs[0]); // id 225 | otree->add_child(fnode->childs[1]); // parameters_def 226 | otree->add_child(olines); // lines 227 | 228 | int len = fnode->childs[2]->childs.size(); 229 | for(int i = 0; i < len; i++) { 230 | ch = fnode->childs[2]->childs[i]; 231 | if(ch->type == node_type_var_def) { 232 | olines->add_child(ch); 233 | } 234 | } 235 | ast_node* control_variable_id = new_node(node_type_id, 0); 236 | control_variable_id->id = new char[10]; 237 | 238 | strcpy(control_variable_id->id, "__st__"); 239 | 240 | ast_node* control_while = new_node(node_type_while_block, 0); 241 | ast_node* control_while_lines = new_node(node_type_lines, 0); 242 | 243 | control_while->add_child(control_variable_id); 244 | control_while->add_child(control_while_lines); 245 | 246 | ast_node* tmp; 247 | tmp = new_node(node_type_var_def, 0); 248 | tmp->add_child(control_variable_id); 249 | tmp->add_child(new_node(node_type_int, state_couner)); 250 | tmp->add_child(NULL); 251 | olines->add_child(tmp); 252 | olines->add_child(control_while); 253 | 254 | 255 | ast_node* if_ = new_node(node_type_if_block, 0); 256 | ast_node* if_condition = new_node(node_type_exp, op_equal); 257 | ast_node* if_lines = new_node(node_type_lines, 0); 258 | if_condition->add_child(control_variable_id); 259 | if_condition->add_child(new_node(node_type_int, state_couner)); 260 | if_->add_child(if_condition); 261 | state_couner++; 262 | control_while_lines->add_child(if_); 263 | if_->add_child(if_lines); 264 | if_->add_child(NULL); 265 | for(int i = 0; i < len; i++) { 266 | ch = fnode->childs[2]->childs[i]; 267 | if(ch->type == node_type_var_def) { 268 | continue; 269 | } 270 | if_lines->add_child(ch); 271 | } 272 | 273 | if_lines->set_obf_next_st(control_variable_id, 0); 274 | 275 | for(int i = 0; i < control_while_lines->childs.size(); i++) { 276 | ch = control_while_lines->childs[i]; 277 | if(ch->type == node_type_if_block) { 278 | flat_case(control_variable_id, state_couner, ch, control_while_lines); 279 | } 280 | 281 | } 282 | return otree; 283 | } 284 | 285 | ast_node* do_CFA(ast_node* tree) { 286 | for(int i = 0; i < tree->childs.size(); i++) { 287 | if(tree->childs[i]->type == node_type_func_def) { 288 | tree->childs[i] = do_CFA_on_function(tree->childs[i]); 289 | } 290 | } 291 | } -------------------------------------------------------------------------------- /obfuscator.h: -------------------------------------------------------------------------------- 1 | #ifndef __obfuscator_H__ 2 | 3 | #define __obfuscator_H__ 4 | 5 | #include "ast.h" 6 | ast_node* do_CFA(ast_node* tree); 7 | ast_node* do_CFA_on_function(ast_node* fnode); 8 | void flat_case(ast_node* st_id, int& st, ast_node* node, ast_node* control_while_lines); 9 | 10 | #endif -------------------------------------------------------------------------------- /output.html: -------------------------------------------------------------------------------- 1 |
 

input

2 | int min(int a, int b) { 3 | if((a < b)) { 4 | return a; 5 | } 6 | return b; 7 | } 8 | 9 | 10 | int Combination(int n, int k) { 11 | int C[(n + 1)][(k + 1)]; 12 | int i; 13 | int j; 14 | for(i = 0; (i <= n); (i++)) { 15 | for(j = 0; (j <= min(i, k)); (j++)) { 16 | if(((j == 0) || (j == i))) { 17 | C[i][j] = 1; 18 | } else { 19 | C[i][j] = (C[(i - 1)][(j - 1)] + C[(i - 1)][j]); 20 | } 21 | } 22 | } 23 | return C[n][k]; 24 | } 25 | 26 | 27 | int main() { 28 | int n = 0; 29 | int k = 0; 30 | int c = Combination(n, k); 31 | printf("(%d, %d) = %d\n", n, k, c); 32 | return 0; 33 | } 34 | 35 |

control flow obfuscated

36 | int min(int a, int b) { 37 | int __st__ = 1; 38 | while(__st__) { 39 | if((__st__ == 1)) { 40 | if((a < b)) { 41 | __st__ = 3; 42 | continue; 43 | } 44 | __st__ = 2; 45 | continue; 46 | } 47 | if((__st__ == 2)) { 48 | return b; 49 | __st__ = 0; 50 | continue; 51 | } 52 | if((__st__ == 3)) { 53 | return a; 54 | __st__ = 2; 55 | continue; 56 | } 57 | } 58 | } 59 | 60 | 61 | int Combination(int n, int k) { 62 | int C[(n + 1)][(k + 1)]; 63 | int i; 64 | int j; 65 | int __st__ = 1; 66 | while(__st__) { 67 | if((__st__ == 1)) { 68 | i = 0; 69 | __st__ = 2; 70 | continue; 71 | } 72 | if((__st__ == 2)) { 73 | if((i <= n)) { 74 | __st__ = 4; 75 | continue; 76 | } 77 | __st__ = 3; 78 | continue; 79 | } 80 | if((__st__ == 3)) { 81 | return C[n][k]; 82 | __st__ = 0; 83 | continue; 84 | } 85 | if((__st__ == 4)) { 86 | j = 0; 87 | __st__ = 5; 88 | continue; 89 | } 90 | if((__st__ == 5)) { 91 | if((j <= min(i, k))) { 92 | __st__ = 7; 93 | continue; 94 | } 95 | __st__ = 6; 96 | continue; 97 | } 98 | if((__st__ == 6)) { 99 | (i++); 100 | __st__ = 2; 101 | continue; 102 | } 103 | if((__st__ == 7)) { 104 | if(((j == 0) || (j == i))) { 105 | __st__ = 9; 106 | continue; 107 | } else { 108 | __st__ = 10; 109 | continue; 110 | } 111 | __st__ = 8; 112 | continue; 113 | } 114 | if((__st__ == 8)) { 115 | (j++); 116 | __st__ = 5; 117 | continue; 118 | } 119 | if((__st__ == 9)) { 120 | C[i][j] = 1; 121 | __st__ = 8; 122 | continue; 123 | } 124 | if((__st__ == 10)) { 125 | C[i][j] = (C[(i - 1)][(j - 1)] + C[(i - 1)][j]); 126 | __st__ = 8; 127 | continue; 128 | } 129 | } 130 | } 131 | 132 | 133 | int main() { 134 | int n = 0; 135 | int k = 0; 136 | int c = Combination(n, k); 137 | int __st__ = 1; 138 | while(__st__) { 139 | if((__st__ == 1)) { 140 | printf("(%d, %d) = %d\n", n, k, c); 141 | return 0; 142 | __st__ = 0; 143 | continue; 144 | } 145 | } 146 | } 147 | 148 |
-------------------------------------------------------------------------------- /samples/Combination.html: -------------------------------------------------------------------------------- 1 |
 

input

2 | int min(int a, int b) { 3 | if((a < b)) { 4 | return a; 5 | } 6 | return b; 7 | } 8 | 9 | 10 | int Combination(int n, int k) { 11 | int C[(n + 1)][(k + 1)]; 12 | int i; 13 | int j; 14 | for(i = 0; (i <= n); (i++)) { 15 | for(j = 0; (j <= min(i, k)); (j++)) { 16 | if(((j == 0) || (j == i))) { 17 | C[i][j] = 1; 18 | } else { 19 | C[i][j] = (C[(i - 1)][(j - 1)] + C[(i - 1)][j]); 20 | } 21 | } 22 | } 23 | return C[n][k]; 24 | } 25 | 26 | 27 | int main() { 28 | int n = 0; 29 | int k = 0; 30 | int c = Combination(n, k); 31 | printf("(%d, %d) = %d\n", n, k, c); 32 | return 0; 33 | } 34 | 35 |

control flow obfuscated

36 | int min(int a, int b) { 37 | int __st__ = 1; 38 | while(__st__) { 39 | if((__st__ == 1)) { 40 | if((a < b)) { 41 | __st__ = 3; 42 | continue; 43 | } 44 | __st__ = 2; 45 | continue; 46 | } 47 | if((__st__ == 2)) { 48 | return b; 49 | __st__ = 0; 50 | continue; 51 | } 52 | if((__st__ == 3)) { 53 | return a; 54 | __st__ = 2; 55 | continue; 56 | } 57 | } 58 | } 59 | 60 | 61 | int Combination(int n, int k) { 62 | int C[(n + 1)][(k + 1)]; 63 | int i; 64 | int j; 65 | int __st__ = 1; 66 | while(__st__) { 67 | if((__st__ == 1)) { 68 | i = 0; 69 | __st__ = 2; 70 | continue; 71 | } 72 | if((__st__ == 2)) { 73 | if((i <= n)) { 74 | __st__ = 4; 75 | continue; 76 | } 77 | __st__ = 3; 78 | continue; 79 | } 80 | if((__st__ == 3)) { 81 | return C[n][k]; 82 | __st__ = 0; 83 | continue; 84 | } 85 | if((__st__ == 4)) { 86 | j = 0; 87 | __st__ = 5; 88 | continue; 89 | } 90 | if((__st__ == 5)) { 91 | if((j <= min(i, k))) { 92 | __st__ = 7; 93 | continue; 94 | } 95 | __st__ = 6; 96 | continue; 97 | } 98 | if((__st__ == 6)) { 99 | (i++); 100 | __st__ = 2; 101 | continue; 102 | } 103 | if((__st__ == 7)) { 104 | if(((j == 0) || (j == i))) { 105 | __st__ = 9; 106 | continue; 107 | } else { 108 | __st__ = 10; 109 | continue; 110 | } 111 | __st__ = 8; 112 | continue; 113 | } 114 | if((__st__ == 8)) { 115 | (j++); 116 | __st__ = 5; 117 | continue; 118 | } 119 | if((__st__ == 9)) { 120 | C[i][j] = 1; 121 | __st__ = 8; 122 | continue; 123 | } 124 | if((__st__ == 10)) { 125 | C[i][j] = (C[(i - 1)][(j - 1)] + C[(i - 1)][j]); 126 | __st__ = 8; 127 | continue; 128 | } 129 | } 130 | } 131 | 132 | 133 | int main() { 134 | int n = 0; 135 | int k = 0; 136 | int c = Combination(n, k); 137 | int __st__ = 1; 138 | while(__st__) { 139 | if((__st__ == 1)) { 140 | printf("(%d, %d) = %d\n", n, k, c); 141 | return 0; 142 | __st__ = 0; 143 | continue; 144 | } 145 | } 146 | } 147 | 148 |
-------------------------------------------------------------------------------- /samples/Combination.txt: -------------------------------------------------------------------------------- 1 | int min(int a, int b) { 2 | if(a < b) { 3 | return a; 4 | } 5 | return b; 6 | } 7 | 8 | int Combination(int n, int k) { 9 | int C[n + 1][k + 1]; 10 | int i; 11 | int j; 12 | for(i = 0; i <= n; i++) { 13 | for(j = 0; j <= min(i, k); j++) { 14 | if(j == 0 || j == i) { 15 | C[i][j] = 1; 16 | } else { 17 | C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; 18 | } 19 | } 20 | } 21 | return C[n][k]; 22 | } 23 | 24 | int main() { 25 | int n = 0; 26 | int k = 0; 27 | printf("(%d, %d) = %d\n", n, k, Combination(n, k)); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /samples/Selection sort.html: -------------------------------------------------------------------------------- 1 |
 

input

2 | int main() { 3 | int array[500]; 4 | int n; 5 | int c; 6 | int d; 7 | int position; 8 | int swap; 9 | printf("Enter number of elements\n"); 10 | scanf("%d", (&n)); 11 | printf("Enter %d integers\n", n); 12 | for(c = 0; (c < n); (c++)) { 13 | scanf("%d", (&array[c])); 14 | } 15 | for(c = 0; (c < (n - 1)); (c++)) { 16 | position = c; 17 | for(d = (c + 1); (d < n); (d++)) { 18 | if((array[position] > array[d])) { 19 | position = d; 20 | } 21 | } 22 | if((position != c)) { 23 | swap = array[c]; 24 | array[c] = array[position]; 25 | array[position] = swap; 26 | } 27 | } 28 | printf("Sorted list in ascending order:\n"); 29 | for(c = 0; (c < n); (c++)) { 30 | printf("%d\n", array[c]); 31 | } 32 | return 0; 33 | } 34 | 35 |

control flow obfuscated

36 | int main() { 37 | int array[500]; 38 | int n; 39 | int c; 40 | int d; 41 | int position; 42 | int swap; 43 | int __st__ = 1; 44 | while(__st__) { 45 | if((__st__ == 1)) { 46 | printf("Enter number of elements\n"); 47 | scanf("%d", (&n)); 48 | printf("Enter %d integers\n", n); 49 | __st__ = 2; 50 | continue; 51 | } 52 | if((__st__ == 2)) { 53 | c = 0; 54 | __st__ = 3; 55 | continue; 56 | } 57 | if((__st__ == 3)) { 58 | if((c < n)) { 59 | __st__ = 5; 60 | continue; 61 | } 62 | __st__ = 4; 63 | continue; 64 | } 65 | if((__st__ == 4)) { 66 | c = 0; 67 | __st__ = 6; 68 | continue; 69 | } 70 | if((__st__ == 5)) { 71 | scanf("%d", (&array[c])); 72 | (c++); 73 | __st__ = 3; 74 | continue; 75 | } 76 | if((__st__ == 6)) { 77 | if((c < (n - 1))) { 78 | __st__ = 8; 79 | continue; 80 | } 81 | __st__ = 7; 82 | continue; 83 | } 84 | if((__st__ == 7)) { 85 | printf("Sorted list in ascending order:\n"); 86 | __st__ = 9; 87 | continue; 88 | } 89 | if((__st__ == 8)) { 90 | position = c; 91 | __st__ = 10; 92 | continue; 93 | } 94 | if((__st__ == 9)) { 95 | c = 0; 96 | __st__ = 11; 97 | continue; 98 | } 99 | if((__st__ == 10)) { 100 | d = (c + 1); 101 | __st__ = 12; 102 | continue; 103 | } 104 | if((__st__ == 11)) { 105 | if((c < n)) { 106 | __st__ = 14; 107 | continue; 108 | } 109 | __st__ = 13; 110 | continue; 111 | } 112 | if((__st__ == 12)) { 113 | if((d < n)) { 114 | __st__ = 16; 115 | continue; 116 | } 117 | __st__ = 15; 118 | continue; 119 | } 120 | if((__st__ == 13)) { 121 | return 0; 122 | __st__ = 0; 123 | continue; 124 | } 125 | if((__st__ == 14)) { 126 | printf("%d\n", array[c]); 127 | (c++); 128 | __st__ = 11; 129 | continue; 130 | } 131 | if((__st__ == 15)) { 132 | if((position != c)) { 133 | __st__ = 18; 134 | continue; 135 | } 136 | __st__ = 17; 137 | continue; 138 | } 139 | if((__st__ == 16)) { 140 | if((array[position] > array[d])) { 141 | __st__ = 20; 142 | continue; 143 | } 144 | __st__ = 19; 145 | continue; 146 | } 147 | if((__st__ == 17)) { 148 | (c++); 149 | __st__ = 6; 150 | continue; 151 | } 152 | if((__st__ == 18)) { 153 | swap = array[c]; 154 | array[c] = array[position]; 155 | array[position] = swap; 156 | __st__ = 17; 157 | continue; 158 | } 159 | if((__st__ == 19)) { 160 | (d++); 161 | __st__ = 12; 162 | continue; 163 | } 164 | if((__st__ == 20)) { 165 | position = d; 166 | __st__ = 19; 167 | continue; 168 | } 169 | } 170 | } 171 | 172 |
-------------------------------------------------------------------------------- /samples/Selection sort.txt: -------------------------------------------------------------------------------- 1 | int main() { 2 | int array[500]; 3 | int n; 4 | int c; 5 | int d; 6 | int position; 7 | int swap; 8 | printf("Enter number of elements\n"); 9 | scanf("%d", (&n)); 10 | printf("Enter %d integers\n", n); 11 | for(c = 0; c < n; c++) { 12 | scanf("%d", (&array[c])); 13 | } 14 | for(c = 0; c < n - 1; c++) { 15 | position = c; 16 | for(d = c + 1; d < n; d++) { 17 | if(array[position] > array[d]) { 18 | position = d; 19 | } 20 | } 21 | if(position != c) { 22 | swap = array[c]; 23 | array[c] = array[position]; 24 | array[position] = swap; 25 | } 26 | } 27 | printf("Sorted list in ascending order:\n"); 28 | for(c = 0; (c < n); (c++)) { 29 | printf("%d\n", array[c]); 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /samples/test.html: -------------------------------------------------------------------------------- 1 |
 

input

2 | int main() { 3 | int i; 4 | int j; 5 | for(i = 0; (i < 10); (i++)) { 6 | for(j = 0; (j < 10); (j++)) { 7 | if((i * (j % 3))) { 8 | printf(" "); 9 | } else { 10 | printf("#"); 11 | } 12 | } 13 | printf("\n"); 14 | } 15 | } 16 | 17 |

control flow obfuscated

18 | int main() { 19 | int i; 20 | int j; 21 | int __st__ = 1; 22 | while(__st__) { 23 | if((__st__ == 1)) { 24 | i = 0; 25 | __st__ = 2; 26 | continue; 27 | } 28 | if((__st__ == 2)) { 29 | if((i < 10)) { 30 | __st__ = 3; 31 | continue; 32 | } 33 | __st__ = 0; 34 | continue; 35 | } 36 | if((__st__ == 3)) { 37 | j = 0; 38 | __st__ = 4; 39 | continue; 40 | } 41 | if((__st__ == 4)) { 42 | if((j < 10)) { 43 | __st__ = 6; 44 | continue; 45 | } 46 | __st__ = 5; 47 | continue; 48 | } 49 | if((__st__ == 5)) { 50 | printf("\n"); 51 | (i++); 52 | __st__ = 2; 53 | continue; 54 | } 55 | if((__st__ == 6)) { 56 | if((i * (j % 3))) { 57 | __st__ = 8; 58 | continue; 59 | } else { 60 | __st__ = 9; 61 | continue; 62 | } 63 | __st__ = 7; 64 | continue; 65 | } 66 | if((__st__ == 7)) { 67 | (j++); 68 | __st__ = 4; 69 | continue; 70 | } 71 | if((__st__ == 8)) { 72 | printf(" "); 73 | __st__ = 7; 74 | continue; 75 | } 76 | if((__st__ == 9)) { 77 | printf("#"); 78 | __st__ = 7; 79 | continue; 80 | } 81 | } 82 | } 83 | 84 |
-------------------------------------------------------------------------------- /samples/test.txt: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i; 3 | int j; 4 | for(i = 0; i < 10; i++) { 5 | for(j = 0; j < 10; j++) { 6 | if(i * j % 3) { 7 | printf(" "); 8 | } else { 9 | printf("#"); 10 | } 11 | } 12 | printf("\n"); 13 | } 14 | } --------------------------------------------------------------------------------