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 29<br />
• Initially we have zero or more edges that we do not particularly care about<br />
which is indicated by { }∗ — the interpretation <strong>of</strong> { } is a predicate that<br />
is always true.<br />
• Next, we require an edge whose target node is an expression <strong>of</strong> the form<br />
X := A where X is local variable.<br />
• Then we want zero or more edges to nodes that do not re-define X.<br />
• Finally we reach an edge pointing to node N which uses variable X.<br />
A pattern, which denotes an property on the control flow graph, is a regular<br />
expression whose alphabet is given by temporal goals — the operator ; represents<br />
sequential composition, + represents choice, ∗ is zero or more occurrences and<br />
ɛ an empty path. A temporal goal is a list <strong>of</strong> temporal predicates, enclosed<br />
in curly brackets. A temporal predicate is either an ordinary predicate (like<br />
local in the example we just examined), or a ticked predicate (like use). Ticked<br />
predicates are properties involving edges and are denoted by the use <strong>of</strong> a tick<br />
mark ( ′ ) in front <strong>of</strong> the predicate. For example, def (X,E) is a predicate that<br />
takes two arguments: a variable X and an edge E, and it holds true when the<br />
edge points at a node where X is assigned. Similarly, use(X,E) is true when<br />
the target <strong>of</strong> E is a node that is labelled with a statement that makes use <strong>of</strong><br />
X. When we place a tick mark in front <strong>of</strong> a predicate inside a path pattern, the<br />
current edge is added as a final parameter when the predicate is called.<br />
We can think <strong>of</strong> the path patterns in the usual way as automata, where the<br />
edges are labelled with temporal goals. In turn, a temporal goal is interpreted<br />
as a property <strong>of</strong> an edge in the flow graph. The pattern<br />
{p 0 ,p 1 , . . . ,p k−1 }<br />
holds at edge e if each <strong>of</strong> its constituents holds at edge e. To check whether<br />
a ticked predicate holds at e, we simply add e as a parameter to the given<br />
predicate and non-ticked predicates ignore e. A syntax for this language and a<br />
more detail discussion <strong>of</strong> all and exists is given in [22].<br />
2.3.2 Expression IL<br />
Since IL is a stack based language, performing a simple variable transformation<br />
described in Section 2.2.1 leads to performing quite a complicated replacement.<br />
To make specifying transformation easier we work with a representation <strong>of</strong> IL<br />
which replaces stack-based computations with expressions — this representation<br />
is called Expression IL (EIL). To convert from IL to EIL, we introduce a new<br />
local variable for each stack location and replace each IL instruction with an<br />
assignment. As we use only verifiable IL, this translation is possible.<br />
EIL is analogous to both the Jimple and Grimp languages from the SOOT<br />
framework [53, 54] — the initial translation produces code similar to the threeaddress<br />
code <strong>of</strong> Jimple, and assignment merging leaves us with proper expressions<br />
like those <strong>of</strong> Grimp.