Obfuscation of Abstract Data-Types - Rowan
Obfuscation of Abstract Data-Types - Rowan
Obfuscation of Abstract Data-Types - Rowan
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
CHAPTER 2. OBFUSCATIONS FOR INTERMEDIATE LANGUAGE 33<br />
2.3.5 Applying transformations<br />
Although the logic language we have described makes it convenient to define<br />
side conditions for program transformation, it would be rather difficult to use<br />
this language to apply these transformations, since that would require the program<br />
flow graph to be represented as a logic term. The approach that is taken is<br />
that a successful logic query should also bind its parameter to a list <strong>of</strong> symbolic<br />
“actions” which define a correct transformation on the flow graph. A high-level<br />
strategy language, which is similar to Stratego [55], is responsible for directing<br />
in what order logic queries should be tried and for applying the resulting<br />
transformations.<br />
An action is a term, which can be either <strong>of</strong> the form replace vertex(V ,W)<br />
or new local(T,N). The former replaces the vertex V with the vertex W , while<br />
the latter introduces a new local variable named N <strong>of</strong> type T. We write a list<br />
<strong>of</strong> actions as the last parameter <strong>of</strong> predicate.<br />
Suppose that we have a predicate P specified. If we want to apply this<br />
predicate once then we write apply(P) in the strategy language. If we want to<br />
exhaustively apply this predicate (i.e. keep applying the predicate while it is<br />
true) then we write exhaustively(apply(P)). An example <strong>of</strong> a strategy is given<br />
at the end <strong>of</strong> the next section.<br />
2.3.6 Variable Transformation<br />
For our first example, let us consider how to define a variable transformation<br />
(Section 1.3.3). The first part <strong>of</strong> the transformation involves finding a suitable<br />
variable and for simplicity, we require that the variable is local and has integer<br />
type. We also require that it is assigned somewhere (otherwise there would be<br />
no point in performing the transformation). Once we find a suitable variable<br />
(which we call OldVar), we generate a new name using @fresh name which<br />
takes a type as a parameter. We can write the search for a suitable variable as<br />
follows:<br />
find local (OldVar,<br />
NewVar,<br />
new local(int(true,b32),NewVarName) : nil<br />
) :−<br />
exists ( { }∗ ;<br />
{ ′ set(OldVar,V ),<br />
OldVar = expr type(localvar( ),int(true,b32))}<br />
) (entry,OldVarVert),<br />
@fresh name (int(true,b32),NewVarName),<br />
NewVar = expr type(localvar (sname(NewVarName)),<br />
int(true,b32)).<br />
The next step <strong>of</strong> the transformation replaces uses and assignments <strong>of</strong> OldVar<br />
exhaustively. To do this, we need to define predicates which allow us to build<br />
expressions corresponding to f and g (the functions used for variable transformation).<br />
The predicate use fn(A,B) binds B to a representation <strong>of</strong> g(A) and<br />
similarly, assign fn(C,D) binds D to f (C). We can specify any variable transformation<br />
by changing these two predicates. As an example, let us suppose