Obfuscation: know your enemy



Similar documents
Static Analysis of Virtualization- Obfuscated Binaries

Applications of obfuscation to software and hardware systems

Software Protection through Code Obfuscation

Binary Code Extraction and Interface Identification for Security Applications

Introduction to Program Obfuscation

Second year review WP2 overview SW-based Method. Trento - October 17th, 2008

Smartphone Security for Android Applications

Code Obfuscation Literature Survey

How To Trace

Software Code Protection Through Software Obfuscation

Parasitics: The Next Generation. Vitaly Zaytsev Abhishek Karnik Joshua Phillips

Code Obfuscation. Mayur Kamat Nishant Kumar

All Your Code Belongs To Us Dismantling Android Secrets With CodeInspect. Steven Arzt Secure Software Engineering Group Steven Arzt 1

CSE 504: Compiler Design. Data Flow Analysis

Software Reverse Engineering

Habanero Extreme Scale Software Research Project

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Static Taint-Analysis on Binary Executables

Python Programming: An Introduction to Computer Science

GameTime: A Toolkit for Timing Analysis of Software

Implementation of an Obfuscation Tool for C/C++ Source Code Protection on the XScale Architecture *

Surreptitious Software

Lecture 26: Obfuscation

ʻpyREticʼ In memory reverse engineering for obfuscated Python bytecode

Advanced compiler construction. General course information. Teacher & assistant. Course goals. Evaluation. Grading scheme. Michel Schinz

CS 111 Classes I 1. Software Organization View to this point:

Platform Independent Code Obfuscation

Lecture 12: Software protection techniques. Software piracy protection Protection against reverse engineering of software

1 Classical Universal Computer 3

Mobile Payment Security

Scoping (Readings 7.1,7.4,7.6) Parameter passing methods (7.5) Building symbol tables (7.6)

Upcompiling Legacy Code to Java

A Framework for Measuring Software Obfuscation Resilience Against Automated Attacks

Symbol Tables. Introduction

Automated Identification of Cryptographic Primitives in Binary Programs

Python for Rookies. Example Examination Paper

Sandy. The Malicious Exploit Analysis. Static Analysis and Dynamic exploit analysis. Garage4Hackers

Why? A central concept in Computer Science. Algorithms are ubiquitous.

Seminar: Cryptographic Protocols Staged Information Flow for JavaScript

Android Packer. facing the challenges, building solutions. Rowland YU. Senior Threat Researcher Virus Bulletin 2014

SOURCE CODE OBFUSCATION BY MEAN OF EVOLUTIONARY ALGORITHMS

C++ Programming Language

Behavioral Analysis of Obfuscated Code

SAF: Static Analysis Improved Fuzzing

Static Analysis of Binary Executables

AUTOMATED TEST GENERATION FOR SOFTWARE COMPONENTS

A Test Suite for Basic CWE Effectiveness. Paul E. Black.

Obfuscating C++ Programs via Control Flow Flattening

OBFUSCATING C++ PROGRAMS VIA CONTROL FLOW FLATTENING

Software Reversing Engineering (a.k.a. Reversing) Spiros Mancoridis. What is Reverse Engineering? Software Reverse Engineering: Reversing

Instruction Set Architecture (ISA)

Efficient Program Exploration by Input Fuzzing

DATA STRUCTURES USING C

Area 1 (Virtual Machines and Compilation)

Transparent Monitoring of a Process Self in a Virtual Environment

DATA OBFUSCATION. What is data obfuscation?

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

OKLAHOMA SUBJECT AREA TESTS (OSAT )

C Compiler Targeting the Java Virtual Machine

Object Oriented Software Design

Outline. hardware components programming environments. installing Python executing Python code. decimal and binary notations running Sage

vmprof Documentation Release 0.1 Maciej Fijalkowski, Antonio Cuni, Sebastian Pawlus

The P3 Compiler: compiling Python to C++ to remove overhead

Impeding Malware Analysis Using Conditional Code Obfuscation

IVR Studio 3.0 Guide. May Knowlarity Product Team

High-Level Programming Languages. Nell Dale & John Lewis (adaptation by Michael Goldwasser)

Towards Revealing Attackers Intent by Automatically Decrypting Network Traffic

Instruction Set Architecture of Mamba, a New Virtual Machine for Python

Lecture 4 on Obfuscation by Partial Evaluation of Distorted Interpreters

Review; questions Discussion of Semester Project Arbitrary interprocedural control flow Assign (see Schedule for links)

Bachelor of Games and Virtual Worlds (Programming) Subject and Course Summaries

Interpreters and virtual machines. Interpreters. Interpreters. Why interpreters? Tree-based interpreters. Text-based interpreters

Optimizations. Optimization Safety. Optimization Safety. Control Flow Graphs. Code transformations to improve program

Obfuscatorreloaded. Pascal Junod HEIG-VD Julien Rinaldini HEIG-VD Marc Romanens- EIA-FR Jean-Roland Schuler EIA-FR

Moving from CS 61A Scheme to CS 61B Java

Obfuscation of Abstract Data-Types

Dr. Jinyuan (Stella) Sun Dept. of Electrical Engineering and Computer Science University of Tennessee Fall 2010

X86-64 Architecture Guide

ML for the Working Programmer

Mike Melanson

Compilers. Introduction to Compilers. Lecture 1. Spring term. Mick O Donnell: michael.odonnell@uam.es Alfonso Ortega: alfonso.ortega@uam.

Storm Worm & Botnet Analysis

Chapter 3: Restricted Structures Page 1

C# and Other Languages

Jonathan Worthington Scarborough Linux User Group

Semester Review. CSC 301, Fall 2015

language 1 (source) compiler language 2 (target) Figure 1: Compiling a program

Generating Test Cases With High Branch Coverage for Web Applications

Topics. Introduction. Java History CS 146. Introduction to Programming and Algorithms Module 1. Module Objectives

Jedd: A BDD-based Relational Extension of Java

PCF: A Portable Circuit Format For Scalable Two-Party Secure Computation

Specifying Imperative Data Obfuscations

7.1 Our Current Model

Sources: On the Web: Slides will be available on:

Optimizing compilers. CS Modern Compilers: Theory and Practise. Optimization. Compiler structure. Overview of different optimizations

VLIW Processors. VLIW Processors

2) Write in detail the issues in the design of code generator.

Glossary of Object Oriented Terms

Introduction to Python

Attacking Obfuscated Code with IDA Pro. Chris Eagle

Transcription:

Obfuscation: know your enemy Ninon EYROLLES neyrolles@quarkslab.com Serge GUELTON sguelton@quarkslab.com

Prelude

Prelude

Plan 1 Introduction What is obfuscation? 2 Control flow obfuscation 3 Data flow obfuscation 4 Python obfuscation

What is obfuscation? Code obfuscation Definition Obfuscation is used to make code analysis as complex and expensive as possible, while keeping the original behaviour of the program (input/output equivalence). Malwares (try to avoid signature detection) Protection of sensitive algorithm (DRM, intellectual property...) Theoretically: transformation of symetric-key encryption in asymetric-key encryption, homomorphic encryption algorithm...

What is obfuscation? Don t shoot the messenger Why this talk? Obfuscation exists and is widely used. You might be interested in breaking it (to rewrite some code as free software for example). If you want to break it, you need to know how it works!

What is obfuscation? Several obfuscation types Control flow obfuscation Data-flow obfuscation Symbols rewriting: variable names, function names... Code encryption, packing...

What is obfuscation? Several obfuscation types Control flow obfuscation Data-flow obfuscation Symbols rewriting: variable names, function names... Code encryption, packing...

Plan 1 Introduction 2 Control flow obfuscation Definitions Control-flow obfuscation Control flow flattening 3 Data flow obfuscation 4 Python obfuscation

Definitions Control flow Illustrates the execution flow of a program: the different paths that are possible during the execution Cycles (for, while...), conditions (if), calls to other functions... It s represented with a Control Flow Graph (CFG): it s formed of basic blocks and links between them

Definitions Control flow x = 10 y = 0 while(x 0) true false y = y + 2 x = x 1 return y Figure : CFG of pseudo-code Figure : CFG of assembly code

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG:

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling;

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; search for patterns

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; search for patterns

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; search for patterns comparison of code

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; junk code insertion; search for patterns comparison of code

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; junk code insertion; search for patterns comparison of code liveness analysis

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; junk code insertion; opaque predicates; search for patterns comparison of code liveness analysis

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; junk code insertion; opaque predicates; search for patterns comparison of code liveness analysis SMT solver

Control-flow obfuscation Various techniques The goal is to transform the structure of the CFG: loop unrolling; inlining of function; junk code insertion; opaque predicates; control flow flattening. search for patterns comparison of code liveness analysis SMT solver

Control flow flattening Definition Control flow flattening Transforms the structure of the program to make CFG reconstruction difficult Encodes the control flow information and hide the result in the data flow

Control flow flattening Principle Implementation Basic blocks are numbered A dispatcher handles the execution A variable contains the value of the next block to be executed At the end of every block, this variable is updated, and the execution flow goes back to the dispatcher which then jumps to the next block block 1 some code val = 2 INIT val = 1 DISPATCHER switch(val) block 2 some code val = 3 Figure : Principle of control flow flattening block 3 some code return

Control flow flattening Example Figure : CFG after the control flow flattening Figure : original CFG

Control flow flattening Weakness INIT val = 1 What is the weakness of the control flow flattening? DISPATCHER switch(val) block 1 some code val = 2 block 2 some code val = 3 block 3 some code return

Control flow flattening Weakness INIT val = 1 DISPATCHER switch(val) What is the weakness of the control flow flattening? variable containing the execution flow block 1 some code val = 2 block 2 some code val = 3 block 3 some code return

Control flow flattening Weakness INIT val = 1 What is the weakness of the control flow flattening? DISPATCHER switch(val) variable containing the execution flow Obfuscation techniques: block 1 some code val = 2 block 2 some code val = 3 block 3 some code return multiple (context) variables opaque predicates hash

Control flow flattening Weakness INIT val = 1 What is the weakness of the control flow flattening? DISPATCHER switch(val) variable containing the execution flow Obfuscation techniques: block 1 some code val = 2 block 2 some code val = 3 block 3 some code return multiple (context) variables opaque predicates hash dynamic analysis (tracing) can also be used

Plan 1 Introduction 2 Control flow obfuscation 3 Data flow obfuscation Definition A few techniques 4 Python obfuscation

Definition Data Flow analysis Several ways to do it Information provided by the program s data: strings, numbers, structures... Relations between the data or between the input and output (of a program, a function, a basic block) Interactions between the program and the data: reading, writing, location in memory... Formal notions: live variable, data flow equations, backward and forward analysis...

A few techniques Examples To make data analysis more complex:

A few techniques Examples To make data analysis more complex: encode constants (strings for example);

A few techniques Examples To make data analysis more complex: encode constants (strings for example); look for decoding routine

A few techniques Examples To make data analysis more complex: encode constants (strings for example); look for decoding routine insert useless data (close to junk code);

A few techniques Examples To make data analysis more complex: encode constants (strings for example); look for decoding routine insert useless data (close to junk code); use symbolic execution, data tainting / slicing

A few techniques Examples To make data analysis more complex: encode constants (strings for example); look for decoding routine insert useless data (close to junk code); use symbolic execution, data tainting / slicing complexify arithmetic operations on data; x + y (x y) + 2 (x y)

A few techniques Examples To make data analysis more complex: encode constants (strings for example); look for decoding routine insert useless data (close to junk code); use symbolic execution, data tainting / slicing complexify arithmetic operations on data; x + y (x y) + 2 (x y) use bruteforce and build heuristic

A few techniques Examples modify the way data are stored / manipulated: split tables, change the calling convention of functions, etc;

A few techniques Examples modify the way data are stored / manipulated: split tables, change the calling convention of functions, etc; spot similar elements (probably processed by the same instructions) dynamic analysis to get arguments of a function

A few techniques Examples modify the way data are stored / manipulated: split tables, change the calling convention of functions, etc; spot similar elements (probably processed by the same instructions) dynamic analysis to get arguments of a function encode data while reading and writing. x f MEMORY f (x) f 1 x

A few techniques Examples modify the way data are stored / manipulated: split tables, change the calling convention of functions, etc; spot similar elements (probably processed by the same instructions) dynamic analysis to get arguments of a function encode data while reading and writing. x f MEMORY f (x) f 1 x find the relevant variables, and look for the corresponding encoding

Plan 1 Introduction 2 Control flow obfuscation 3 Data flow obfuscation 4 Python obfuscation Modified Interpreter Source-to-source obfuscation A few examples

Context Applications are developed in Python (DropBox for example): a modified interpreter is delivered with the binary Creation of packers to make access to the code difficult Few traditional obfuscations here! Three ways to obfuscate: - modified interpreter so that access to compiled files is difficult; - measures to make decompilation harder; - source to source obfuscation in case of decompilation success.

Modified Interpreter State of the art Based on the work of Kholia and Wegrzyn 1 : Change the magic number Number specific to each version of CPython, prevent decompilation bruteforce ( 50 possibilities) 1 Looking Inside the (Drop) Box, by D. Kholia and P. Wegrzyn

Modified Interpreter State of the art Based on the work of Kholia and Wegrzyn 1 : Change the magic number Number specific to each version of CPython, prevent decompilation bruteforce ( 50 possibilities) Suppress some features Remove some functions like PyRun_File(), or attributes like co_code 1 Looking Inside the (Drop) Box, by D. Kholia and P. Wegrzyn

Modified Interpreter State of the art Based on the work of Kholia and Wegrzyn 1 : Change the magic number Number specific to each version of CPython, prevent decompilation bruteforce ( 50 possibilities) Suppress some features Remove some functions like PyRun_File(), or attributes like co_code Opcode encryption Encrypt compiled files find decryption routine 1 Looking Inside the (Drop) Box, by D. Kholia and P. Wegrzyn

Modified Interpreter State of the art Opcode remapping Applies a permutation on the opcodes of the instruction set. 34 35 36 LOAD_GLOBAL CALL_FUNCTION POP_TOP 34 75 35 23 36 12 75 23 12 LOAD_FAST LOAD_CONST ROT_TWO

Modified Interpreter State of the art Opcode remapping Applies a permutation on the opcodes of the instruction set. 34 35 36 LOAD_GLOBAL CALL_FUNCTION POP_TOP 34 75 35 23 36 12 75 23 12 LOAD_FAST LOAD_CONST ROT_TWO Compare permuted bytecode with standard bytecode for standard Python module

Modified Interpreter State of the art Opcode remapping Applies a permutation on the opcodes of the instruction set. 34 35 36 LOAD_GLOBAL CALL_FUNCTION POP_TOP 34 75 35 23 36 12 75 23 12 LOAD_FAST LOAD_CONST ROT_TWO Compare permuted bytecode with standard bytecode for standard Python module Get into the application runtime and execute arbitrary code

Modified Interpreter New techniques Addition of new opcodes Substitution of series of opcodes with a new opcode LOAD_GLOBAL CALL_FUNCTION POP_TOP LOAD_GLOBAL CALL_AND_POP Analyse the interpreter! Insertion of junk opcode

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP VAR 0

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP VAR 1 VAR 0

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP DICT VAR 1 VAR 0

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP VAR 1 VAR 0 DICT

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP VAR 0 + VAR 1 DICT

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP DICT VAR 0 + VAR 1

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP VAR 0 + VAR 1

Modified Interpreter New techniques Addition of new opcodes Insertion of junk opcode Use opcodes for stack manipulation: ROT_TWO, ROT_THREE or POP_TOP Combine it to modify bytecode without changing computed values LOAD_FAST 0 LOAD_FAST 1 BUILD_MAP ROT_THREE BINARY_ADD ROT_TWO POP_TOP Prevent decompilation with uncompyle, but pycdc still works.

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: LOAD_GLOBAL CALL_FUNCTION POP_TOP LOAD_FAST LOAD_CONST INPLACE_SUB

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: > LOAD_GLOBAL < CALL_FUNCTION POP_TOP LOAD_FAST LOAD_CONST INPLACE_SUB

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: LOAD_GLOBAL > CALL_FUNCTION < POP_TOP LOAD_FAST LOAD_CONST INPLACE_SUB

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: > LOAD_GLOBAL CALL_FUNCTION POP_TOP LOAD_FAST LOAD_CONST INPLACE_ADD <

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: > LOAD_GLOBAL CALL_FUNCTION POP_TOP LOAD_FAST LOAD_CONST INPLACE_ADD <

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: LOAD_GLOBAL CALL_FUNCTION POP_TOP LOAD_FAST > LOAD_CONST < INPLACE_ADD

Modified Interpreter Self-modifying code 1 def foo (b): 2 b += 1 3... 1 def foo (b): 2 modify_bytecode () 3 b -= 1 4... During execution: LOAD_GLOBAL CALL_FUNCTION POP_TOP LOAD_FAST LOAD_CONST > INPLACE_ADD <

Source-to-source obfuscation Abstract Syntax Tree Abstract Syntax Tree (AST): tree representation of the abstract structure of source code. Nodes are operators Leaves are operands x + y z Figure : AST representation of (x + y) z

Source-to-source obfuscation Python source-to-source Principle Figure : Compilation flow for Python source-to-source Obfuscation Examples

Source-to-source obfuscation Python source-to-source Principle Obfuscation Examples Control flow transformations: loop unrolling, mixing if and while with opaque predicates, transformation in functional style Data flow transformations: string encoding, use of mixed boolean-arithmetic expressions. Symbols obfuscation: replacing names of functions and variables with random string

A few examples Loop unrolling 1 for i in range (3) : 2 if b & 1 == 1: 3 p ^= a 4 hibitset = a & 0 x80 5 a <<= 1 1 i = 0 2 if ((b & 1) == 1): 3 p ^= a 4 hibitset = (a & 128) 5 a <<= 1 6 i = 1 7 if ((b & 1) == 1): 8 p ^= a 9 hibitset = (a & 128) 10 a <<= 1 11 i = 2 12 if ((b & 1) == 1): 13 p ^= a 14 hibitset = (a & 128) 15 a <<= 1 Look for patterns (instructions, variables)

A few examples Mixing if and while 1 # original code 2 if cond1 : 3 work () 1 # obfuscated if 2 opaque_pred = 1 3 while opaque_pred & cond1 : 4 work () 5 opaque_pred = 0 Holds only if the predicates are difficult to evaluate statically and not obvious for a human

A few examples Opaque predicates 1 x = ((((2 * (( -816744550) 816744552) ) - 2 (( -816744550) ^ 816744552) ) * 3 (((3783141896 ^ 3921565134) - 4 (2 * (( 3783141896) & 3921565134) )) 5 ((4009184523 & ( 3870761249) ) - 6 (( 4009184523) & 3870761249) ))) - 7 (((2105675179 & ( 2244098417) ) - 8 (( 2105675179) & 2244098417) ) ^ 9 ((3657555079 + ( 3519131805) ) + 1))) Use constant folding: x = 36 1 x = (80* b **2 + 160* b*( b) + 36821* b + 2 80*( b) **2 + 36821*( b) + 4236969) % 256 Bruteforce, heuristics...

A few examples Transformation in functional style 1 def fibo (n): 2 return n if n < 2 else ( fibo (n - 1) + fibo (n - 2)) 1 fibo = ( lambda n: ( lambda _: (_. setitem ( $, ((_[ n ] if ( n in _) else n) if ((_[ n ] if ( n in _) else n) < 2) else ((_[ fibo ] if ( fibo in _) else fibo ) ((( _[ n ] if ( n in _) else n) - 1)) + (_[ fibo ] if ( fibo in _) else fibo ) ((( _[ n ] if ( n in _) else n) - 2))))), _) [( -1) ]) ({ n : n, $ : None })[ $ ]) Either you re comfortable with functional style, or you use input/output analysis or symbols information.

Conclusion There s a lot of obfuscation techniques Understanding obfuscation can be useful (interoperability) Keep focused on the context and what you want to know Every obfuscation can be broken with time and resources

Questions? contact@quarkslab.com I @quarkslab.com

Table of contents 1 Introduction What is obfuscation? 2 Control flow obfuscation Definitions Control-flow obfuscation Control flow flattening 3 Data flow obfuscation Definition A few techniques 4 Python obfuscation Modified Interpreter Source-to-source obfuscation A few examples