Decompilation is the Ecient Enumeration of Types Peter T. Breuer*y and Jonathan P. Bowen*

* Oxford University Computing Laboratory Programming Research Group, 11 Keble Road, Oxford OX1 3QD, UK. y Visiting Research Fellow, BT laboratories, Martlesham Heath, Ipswich, Su olk UK E-mail [email protected] & [email protected]

Abstract: A free type de nition may be and preceding these with the transformaremolded into a functional program which enumerates all the terms of the associated grammar. This is the starting point for a reliable method of compiling decompilers. Whilst enumerating arbitrary grammars completely is here proved Halting Problem hard, it is shown, via abstract interpretation, that the technique works for most grammars.

Keywords: Attribute grammar, decompilation, abstract interpretation, FP, LP.

1. Introduction

This paper sets out a technique for the decompilation of object code to a highlevel source code representation of the program, based on an unusual interpretation of attribute grammars. Decompilation is useful if, for example, the original source code has been lost, or in the veri cation of object code. This is an extension of other ideas of reverse engineering conceived on the ESPRIT II REDO project [10], a European collaboration concerned with software maintenance [3, 15]. The project has developed techniques which convert high-level code to Z speci cations The authors have been funded by (2487) project and a research grant from BT Laboratories, and the UK IED sa emos (P1036) project respectively. y the European ESPRIT II REDO

tions considered here allows a speci cation to be generated from a low-level object program. We have followed two lines of research. Firstly, the relation between source code and object code can be speci ed directly in the style of Hoare. It can then be coded as a logic program, and run backwards, with the object code as input. Because of the theoretical reversibility of logic programs, all the source codes which can give rise to the given object code should be enumerated. In practice, logic programs are not reversible per se, because of the interpreter semantics, but the program can be altered minimally or run through a meta-interpreter. This technique is valuable because forward compilers coded as logic programs have been formally veri ed [9], so running them backwards ought to yield a veri ed decompiler. The second approach eliminates the ad-hoc modi cations needed for a logic program to run backwards. We know that the logic program encodes a relation which expresses an attribute grammar: the source code grammar decorated with the object code output. So we read the grammar backwards, as a source code grammar restricted and parameterized by the object code to be compiled from it. This description is converted into a functional program which enumerates all the elements of the grammar. This functional program, given an object code as input, lists all the source code constructs which

2

Peter T. Breuer & Jonathan P. Bowen

could give rise to it by compilation. It is a decompiler, and this article presents the grammar-to-decompiler transformation.

2. Problem statement

In a higher-order language, it is not unusual to build the `complete list of elements' of a given type. Building the list [0 : : : ] of all the natural numbers is simple, but writing a decompiler throws up generic examples which cannot be treated by unstructured approaches. A naive decompiler speci cation enumerates all possible source codes: =

naive decompile y [ x source codes

j

compile x

=y

]

(the list of x from source codes such that compile x = y). Manifestly, the naive speci cation is \correct" { and useful in debugging more opaque algorithms { but it refers to the list source codes, the listing of all valid programs in the source language, and so that must be generated rst. Yet, typically, all that is available is the abstract syntax, given in Figure 1. The syntax is the BNF-likey style familiar from, for example, Miranda [14], where it de nes a `free data type'. The constructor names are capitalised, and the alternative constructions are separated by the `j' symbol. The problem is to nd a way of converting the data-type description in Figure 1 to a program which enumerates the elements of the type. This is clearly impossible without some generic strategy { the type itself is simply too complicated. But only slight lexical modi cations turn out to be needed during the construction. The key is the notation used in Figure 2. We use this notation to distinguish [i] the ` nite', `fully de ned' elements which make up the intended grammar { like DECL v1 SKIP { from [ii] the elements of the domain which embeds the grammar here { these include `in nite elements' y Miranda is a trademark of Research Software Ltd.

source code ::= SKIP IF var source code source code WHILE var source code CHOICE source code source code ABORT SEQ source code source code DECL var source code LET var var SUBR prog source code CALL prog

j j j j j j j j j j

The description of source as a user-de ned free data type.

Figure 1.

code

like DECL v1 (DECL v2 : : :), and `incompletely de ned elements' like DECL ? { and which is denoted by the user-de ned type in Figure 1. Now, semantically, the grammar is the set-theoretic closure of the empty set of source codes under the given constructors, and the domain denoted by the type is the set-theoretic completion and the subsequent analytic completion of the grammar when ? is added to the constructors. So the two denotations are not very far apart from each other, and we choose to deal with the enumeration of grammars, from which the treatment for types then follows on adding `?' as a constructor, and closing under limits x1 < x2 < : : : in the re nement order. source code ::= SKIP IF v s1 s2 v var;s1,s2 source code WHILE v s v var;s source code CHOICE s1 s2 s1,s2 source code ABORT SEQ s1 s2 s1,s2 source code DECL v s v var; s source code LET v1 v2 v1,v2 var SUBR p s p prog; s source code CALL p p prog

j j j j j j j j j j

The grammar representing the source code data type. Figure 2.

3

Decompilation: the Enumeration of Types

2.1. Reverse logic

Note that one may turn the grammar description `on its side', so that the vertical bars now run horizontally, and obtain logical deduction-style rules: SKIP source code

v var; s1;s2 source code IF v s1 s2 source code :::

which, through the canonical logical semantics for Prolog [12], corresponds to the Prolog script shown in Figure 3. The correspondence between Prolog and attribute grammars is well-known [8]. source code(skip). source code(if(V,S1,S2)) :variable(V), source code(S1), source code(S2). source code(while(V,S)) :variable(V), source code(S). source code(choice(S1,S2)) :source code(S1), source code(S2). source code(abort). source code(seq(S1,S2)) :source code(S1), source code(S2). source code(decl(V,S)) :variable(V), source code(S). source code(let(V1,V2)) :variable(V1), variable(V2). source code(subr(P,S)) :prog(P), source code(S). source code(call(P)) :prog(P).

source codes = [ SKIP ] [ IF v s1 s2 s1; s2 [ WHILE v s v vars s [ CHOICE s1 s2 s1; s2 [ ABORT ]

$merge

jj v vars; source codes ] $merge ; jj ; source codes ] $merge jj

jj jj ; jj [ SUBR p s jj p progs; s [ CALL prog jj [ SEQ s1 s2 s1; s2 [ DECL v s v vars s [ LET v1 v2

source codes ]

$merge $merge

source codes ]

$merge $merge

v1; v2

vars ]

$merge

source codes ]

$merge

source codes ]

p

progs ]

Figure 4. Using `interleaving' list comprehensions to get enumeration code for the source code grammar.

programs for compilation and decompilation which have minimal di erences between them. One has to take care to use reversible constructs throughout, and be prepared to further transform the naturally dual decompiler code in order to obtain better performance (e.g., termination), but that is all that is required. This approach is explored in some depth in [2] using Prolog [5]. More modern logic programming languages, such as those using the constraint logic programming (CLP) Figure 3. Prolog code that checks for paradigm [6], may mean that di erences the source code data type. between compiler and decompiler programs can be even less in future. A logic program is essentially un directional in its pure form. Thus a compiler written in such a language should theoret- 2.2. Functional enumerations ically be usable as a decompiler as well. The Prolog code shown in the gure However, problems of non-termination, is one of the kind of code that strictness, irreversible clauses such as one mayexample generate. It is useful as a predibuilt-in arithmetic, and the use of nega- cate { that is, a `compiler' the yes `obtion by failure normally limit the modes ject code', but useless as anofenumerator of of use, since logic programs tend to be valid source codes, because the depth- rst designed under assumptions about which recursion semantics of Prolog ensures that parameters will be instantiated rst. But the output to the query `source code(S)' it is nevertheless possible to use two logic consists of nothing but skips and ifs of

4

Peter T. Breuer & Jonathan P. Bowen

skips. However, a

meta-interpreter which performs breadth- rst recursion instead is easy to write [13], and results in the code behaving as a correct and complete enumerator of the source code grammar (from the yes `object code'). So the di erence between `compiler' and `decompiler' here lies entirely within the detail of the Prolog interpreter's evaluation-order semantics. Functional enumeration code derived automatically from the source code grammar is shown in Figure 4. It uses the list comprehension syntax to be found in Miranda, for example. The `jj' separator in the list comprehension means that the elements are to be generated in interleaved and not nested order (see below), and `$merge' is an in x binary operator, de ned below, which `merges' two lists together in a fair way. Figure 5 illustrates the di erence between interleaved and nested orderings of the pairs of elements from two lists. Interleaved ordering: [(x y) jj x ;

11 ;

1 2!1 3 # 21 22 ;

;

;

#

& "

;

;

;

" & ;

Nested ordering: [(x y)jx y 1 1!1 2!1 3 ;

;

[1; 2; 3]]

23

3 1!3 2 ;

y

;

;

;

;

;

;

;

;

33 ;

[1; 2; 3]]

. 2 1!2 2!2 3 . 3 1!3 2!3 3 Figure 5. Interleaved ordering versus nested ordering of the pairs from [1,2,3]. ;

All that is important here is that the merge of two lists should begin with the head of the rst list: (( : ) $merge B) = a

hd a A

(1)

and this requirement can be extended to a (fair) de nition of $merge: (a : A) $merge B = a : (B $merge A) [ ] $merge B =B

(2)

With this functionality for the `jj' syntax, the code in Figure 4 correctly enumerates the grammar of source code. The explicit transform from the grammar description to the functional code is set out in [4], but it will be clear from this example exactly what the syntactic alterations are.

2.3. The problem with recursion

Recursive grammar de nitions make the derived enumerations potentially in nite. There are always a priori two ways in which a recursion equation may fail to specify the intended enumeration:  the list may contain more elements than were intended, or  the list may terminate or hang on output before all the intended elements have been enumerated. and both the italicised situations actually can occur. The rst is always caused by left recursion in the grammar description (see [4] for more details), and we concentrate on the second problem here. If one looks at a single clause of the de nition of source codes in isolation: [WHILE v s jj v vars; s source codes] and consider what happens when the list source codes is empty, one nds that functional interpreters return ?, not [ ]. This result seems to come as a shock to even experienced functional programmers! It is counter-intuitive but easily explained. List comprehensions hang on any expression of the following kind: [ WHILE v s jj v infinite; s []] = [ ] $merge [ ] $merge [ ] $merge =? because the [ ]$merge function is strict. If this term crops up in the execution of a derived functional enumeration, the program will hang. There is no way to avoid the problem, as the next sections make clear. :::

5

Decompilation: the Enumeration of Types

valid

:: [var] ! [prog] ! source code

! bool (

) & ) &

= ( : ) = ( : ) ) = 2 & 2 ) = 2 )= & ) = & ) = 2 & ) = & = = =

valid vs ps DECL v s True; v = vs valid v vs ps s valid vs ps SUBR p s True; p = ps valid vs p ps s valid vs ps LET v1 v2 True; v1 vs v2 vs valid vs ps CALL p True;p ps valid vs ps CHOICE s1 s2 True; valid vs ps s1 valid vs ps s2 valid vs ps SEQ s1 s2 True; valid vs ps s1 valid vs ps s2 valid vs ps WHILE v s True; v vs valid vs ps s valid vs ps IF v s1 s2 True; v vs valid vs ps s1 valid vs ps s2 valid vs ps SKIP True valid vs ps ABORT True valid vs ps s False

2 ( 2 ( ( ( ( (

2

&

(

Figure 6. Validation code which implements semantic restrictions on the source code grammar.

3. Inherited attributes and constraint programming

The transformation technique illustrated in the previous section can be extended to cover inherited attribute grammars and constrained types. We can construct ecient functional programs which enumerate all the elements of the grammar and which also embody some extra semantic constraints. These are usually applied to the input grammar much later in the parsing or compilation process. The grammar source code will in all practical instances be tted with an extra dynamic constraint on the constructs of the language. Usually, a left-to-right rewrite rule: s  ABORT; not(valid s) is added, where valid is a predicate which makes the appropriate checks. For example, valid in Figure 6 checks that variables referred to in the code have been declared before their rst use, and that they are never re-declared. The

sc vs ps

::=

j j v vs; s1 s2 sc vs ps WHILE v ss j v vs; s sc vs ps CHOICE s1 s2 j s1 s2 sc vs ps ABORT j SEQ s1 s2 j s1 s2 sc vs ps DECL v s j v varsnvs; s sc (v:vs) ps LET v1 v2 j v1 v2 vs SUBR p s j p progsnps; s sc vs (p:ps) CALL p j p ps SKIP IF v s1 s2

;

;

;

;

Figure 7. The inherited attribute grammar sc implementing the semantic restrictions on the source code grammar `inline'.

environment components `ps' and `vs' track the lists of declared subroutines and declared variables, respectively. One would prefer the individual clauses to be somehow attached to the patterns in the de nition of source code for eciency. This is possible with the inherited attribute grammar shown in Figure 7. The extended translation to functional programming code only requires parameterised lists. The enumeration which results is shown in Figure 8. A matching Prolog implementation is given in Figure 9 for comparison. Constraints are coded as clauses of the form {: : : }. The complete list in the present example is obtained by providing empty environment lists to sc, because this expresses the idea that no external variable or subroutine names are present at startup: valid source codes = sc [ ] [ ] but, because of recursion, it is inherently possible that the enumeration list may hang before completion. This happens if we have to evaluate the in nite merge of empty lists, and to show this does not happen, it suces to prove that sc vs ps 6= [ ] for all choices of variable lists vs and program identi er lists ps, and the proof

6

Peter T. Breuer & Jonathan P. Bowen

:: [ var ] ! [ prog ] ! [ source code ] sc vs ps = [SKIP ] $merge [ABORT ] $merge [LET v1 v2 jj v1 v2 vs ] $merge [CALL p jj p ps ] $merge [IF v s1 s2 jj v vs; s1 s2 sc vs ps] $merge [WHILE v s jj v vs; s sc vs ps ] $merge [CHOICE s1 s2jj s1 s2 sc vs ps ] $merge [SEQ s1 s2 jj s1 s2 sc vs ps ] $merge [DECL v s jj v varsnvs; s sc(v:vs)ps] $merge [SUBR p s jj p progsnps; s sc vs(p:ps)] sc

;

;

; ;

Figure 8. The enumeration code derived from the inherited attribute grammar sc. turns out to show the list to be in nite (it is postponed till Section 5. The next section sets out some negative results which show the limitations of any generally applicable transformational approach.

4. The Halting Problem

Proposition 1 There is no computable

and it is WillStopn i the Turing machine will stop in n moves time from an initial tape position (l;m;r). If the Turing machine will not stop, then the grammar is empty. So a non-hanging enumeration would eventually deliver one of the results: [ WillStopn ] or [ ] If one had an algorithm to write the code for such an enumeration, one could apply it to the Turing machine grammar, then execute the code with a particular starting tape and examine the resulting list to see if the Turing machine would have halted, thus solving the Halting Problem [11]. sc(Vs,Ps,skip). sc(Vs,Ps,if(V,S1,S2)) :V in Vs , sc(Vs,Ps,S1), sc(Vs,Ps,S2). sc(Vs,Ps,while(V,S)) :V in Vs , sc(Vs,Ps,S). sc(Vs,Ps,choice(S1,S2)) :sc(Vs,Ps,S1), sc(Vs,Ps,S2). sc(Vs,Ps,abort). sc(Vs,Ps,seq(S1,S2)) :sc(Vs,Ps,S1), sc(Vs,Ps,S2). sc(Vs,Ps,decl(V,S)) :V in vars-Vs , sc([V|Vs],Ps,S). sc(Vs,Ps,let(V1,V2)) :V1 in Vs , V2 in Vs . sc(Vs,Ps,subr(P,S)) :P in progs-Ps , sc(Vs,[P|Ps],S). sc(Vs,Ps,call(P)) :P in Ps .

f

g

f

g

f f f f

g

g f g algorithm which will take an arbitrary inherited attribute grammar description and g always produce a piece of computer code which enumerates all the valid phrases of g the grammar, and then terminates (if the grammar is nite). Figure 9. Prolog code that implements Proof: Consider the Turing machine the sc inherited attribute grammar. grammar T with inherited attributes (l;m;r): Note that the Turing machine atT(l Stop r) ::= WillStop0 tribute grammar is very simple. T(next : l0 MoveLeft r) ::= WillStopn+1 j As a corollary, one cannot expect that WillStopn T(l0 next MoveLeft : r) the compilation method favoured here will generally result in an enumeration in which the attribute (l;m;r) represents which gets to the desired termination the tape of a Turing machine, The pa- point without hanging. Enumerations of rameters l, m, r represent respectively the grammars may contain too few elements. However, it is certainly possible to tape to the left of the read/write head, the `byte' under the head, and the tape restrict to classes of grammars which to the right of the head. Then this gram- are guaranteed to translate to successful mar has at most a single valid phrase, enumerations (non-recursive grammars, for example), but it is impossible in ;

;

;

;

;

:::

;

Decompilation: the Enumeration of Types

general to predict exactly which grammar will compile to a program that hangs: Proposition 2 There is no general (computable) method which takes an attribute grammar description and decides whether or not the compiled code given by the compilation method described here will give a terminating enumeration (for a given value of the attribute). Proof: (statement of Lemma 3 here). So a method which predicts whether or not the enumeration will hang or not, when applied to the Turing machine grammar predicts whether or not the Turing machine halts or not. Done. Lemma 3 The Turing machine grammar T(t) compiles via the method here to a program E [[T]] t with only two possible results, [WillStopn] or ?, and these are achieved respectively precisely when the Turing machine halts from the starting tape setup t, and when it does not. One concludes that particular methods must be applied in particular instances to show that a compiled enumeration will not hang. One possible method is to show that the enumeration list must be in nite, as the following section shows.

5. Predicting success

7 the `len gth' (= n) exactly, whilst a list of the form b = [b1; : : : ; bn] ++ ? gets the length ( n) exactly. len [ ] = (= 0) len (a : b) = (= 1)  len b (3) len ? = ( 0) Len is intended to preserve the natural re nement ordering (in particular, ( 0) is `bottom'). Moreover, it is either continuous at each point, or underestimates the limit of a sequence. That is: Lemma 4 ilim % len si  len ilim % si !1 !1 This lemma can be expressed in the `almost commuting' diagram form: lim [X ] ;! X (4) # len # len lim  N  [N ] ;! We only need the following facts about the `' function: (= 1)  (= m ) = (= (m + 1) (= 1)  ( m ) = ( (m + 1)) (= 1)  (= 1) = (= 1) but it is intended to re ect the way that the merge function works, in that len (x $merge y )  len x  len y with equality when at least one of the lists is nite. The full details are given in [4]. We can calculate the result of an interpreted recursion equation symbolically, and use it thus: sc vs ps is the solution of a xed point equation F s = s , and we show that Lemma 5 len (F s )  (= 1)  len s 8s.

We show that the particular inheritance grammar sc vs ps gives rise to an enumeration list which does not hang on output by mapping sc vs ps into the domain N  (a form of abstract interpretation [7, 1]). The elements of N  have the forms (= n ) or ( n ), where n is a natural number, or (= 1). The ordering is: (= 1)   (= 2)  (= 1)  (= 0) This implies that len (F i ?)  (= _ _ _ i )  ( 0) = ( i ), and therefore that (= 1)   ( 2)  ( 1)  ( 0) len (F i ?) = (= 1). By Lemma 4 These `numbers' represent known lengthslim (lim F i ?) = (= 1) too, and this of lists. We de ne a map len from the do- len limit is (sc vs ps). Hence: main of lists to this domain. The intention is that a list of length n { that is, of Proposition 6 sc vs ps is an in nite the form a = [a1; : : : ; an] { should get list. ::: ::: :::

8

Peter T. Breuer & Jonathan P. Bowen

The procedure is to prove: Lemma 7 F s has the form F s = A $merge B s where A is a list with len A = (= 1), and B has the form B s = F1 s $merge : : : $merge Fk s and each Fi either has [i] len (Fi s )  len s, or [ii] len (Fi s ) = (= n ) for some n (which may be 1). Proof: Each clause of the equation for sc vs ps in Figure 8 gives one of the Fi . The proposition ensures that the derived enumeration never hangs on output.

6. General positive criteria In [4], it is shown that the conditions  the enumeration s is the least xed point of the recursion equation s = A $merge B s

 A is a non-empty nite and ter-

minated or in nite list, and B is a transform which strictly increases the len gth of lists. are sucient to make s a complete in nite enumeration of the closure under B of the set of elements in A. The technique presented here can be modi ed by the use of alternative merge functionalities in practice. One may introduce weighted merges of two lists with unequal inclusion rates, and even use dynamically calculated weights to express ordering preferences. This is useful for decompilation, because one wants the interesting source codes to come out rst. Stochastic merging is also possible, but the theory has not been explored.

7. Decompilation

All the preceding theory goes through when we supply object code as an extra inherited parameter to the source code grammar. The parameter constrains the grammar to those source codes which will compile to the given object code. The enumeration function constructed from the parameterised grammar description is a decompiler. Object code comes in the following forms: d(Vs,Ps,skip,[]). d(Vs,Ps,skip,[jump(N)|Ins]) :Ins in object code , N = 1+len(Ins) . d(Vs,Ps,let(V1,V2), [load(V2),store(V1)]) :V1 in Vs , V2 in Vs . d(Vs,Ps,call(P),[subr(P)]) :P in Ps . d(Vs,Ps,if(V,S1,S2),Ins) :Ins = [load(V),cond(N1)|Ins1]++ [jump(N2)|Ins2] , N1 = 1+len(Ins1) , N2 = 1+len(Ins2) , d(Vs,Ps,S1,Ins1), d(Vs,Ps,S2,Ins2). d(Vs,Ps,while(V,S),Ins) :Ins = [load(V),cond(N)|Ins1]++ [jump(-N)] , N = 1+len(Ins1) , d(Vs,Ps,S,Ins1). d(Vs,Ps,subr(P,S),Ins) :Ins = [push(N)|Ins1]++[return] , N = 2+len(Ins1) , P in progs-Ps , d(Vs,[P|Ps],S,Ins1). d(Vs,Ps,seq(S1,S2),Ins) :Ins = [I1|Ins1]++[I2|Ins2] , d(Vs,Ps,S1,[I1|Ins1]), d(Vs,Ps,S2,[I2|Ins2]).

f f

g

g

f f f f f

g f

g

g

g g

f f

g g

f f f

g

g

f

object code instruction

g

g

Figure 10.

piler.

g

Prolog code for a decom-

== [ instruction ] ::= Load a j a memaddr Store a Jump p Cond p Push p Subr a Return

ja jp jp jp ja j

memaddr offset offset offset memaddr

Decompilation: the Enumeration of Types

9

Prolog code implementing a decompiler is shown in Figure 10. See [4] for details of the encodings for the constraints in curly brackets.

[8] P. Deransart and J. Maluszynski, Relating Logic Programs and AttributeGrammars, Jour. Logic Prog. 3(2), 125{163, 1987. [9] C.A.R. Hoare, He Jifeng, J.P. Bowen and P.K. Pandya, An algebraic approach to veri able compiling speci cation and prototyping of the ProCoS level 0 programming language, in Dir.Gen. of the CEC (Eds.) ESPRIT '90 Conf. Proc., Kluwer Academic Publishers B.V., pp. 804{818, 1990. [10] P.S. Katsoulakos, REDO, in R.J. Norman and R.V. Ghent (eds.), CASE '90: Fourth Intl. Workshop, IEEE Comp. Soc. Press, 1990. [11] S.C. Kleene, Mathematical Logic, New York, 1967. [12] J.W. Lloyd, Foundations of Logic Programming, 2nd edition, Springer 1987. [13] U. Nilsson and J. Maluszynski. Logic, Programming and Prolog, Wiley 1990. [14] D.A. Turner, An Overview of Miranda, in UNIX around the World, Proc. Spring 1988 EUUG Conf, pp. 59{67, 1988. [15] H. van Zuylen (ed.), The REDO Compendium of Reverse Engineering for Software Maintenance, Wiley 1992. [16] P. Wadler, List Comprehensions, in S.L. Peyton-Jones (ed.), The Implementation of Functional Programming Languages, Prentice Hall 1987.

8. Summary

An attribute grammar description may be translated to functional programming code which enumerates the valid terms of the grammar, and there is a corresponding translation to logic programming code. Decompilers result when a compiler speci cation is phrased as a source code grammar parameterised by an object code input.

References bibliographiques

[1] S. Abramsky and C. Hankin (eds.), Abstract Interpretation of Declarative Languages, Computers and their Applications, Halsted Press, New York, 1987. [2] J.P. Bowen, From Programs to Object Code and back again using Logic Programming, Abstract in R. Giegerich and S.L. Graham (eds.), Code Generation { Concepts, Tools, Techniques, DagstuhlSeminar-Report 13, 20{24.5.1991(9121), IBFI GmbH, Schlo Dagstuhl, W-6648, Wadern, Germany, 1991. [3] P.T. Breuer and K.C. Lano. Creating Speci cations from Code: Reverse Engineering Techniques, Journal of Software Maintenance 3, 145{162, Sept. 1991. [4] P.T. Breuer and J.P. Bowen, Decompilation: the Enumeration of Types and Grammars, Oxford University Comp. Lab., PRG Tech. Report PRG-TR-1192, 1992. [5] W.F. Clocksin and C.S. Mellish, Programming in Prolog, 3rd ed., Springer 1987. [6] J. Cohen, Constraint Logic Programming languages, Comm. ACM 33(7), 52{68, 1990. [7] P. Cousot and R. Cousot, Abstract Interpretation: A Uni ed Lattice Model for Static Analysis of Programs by Construction or Approximation of Fixpoints. in Proc. 4th ACM POPL Symposium, pp. 238{252, 1977.

Decompilation is the E cient Enumeration of Types

treated by unstructured approaches. A ... of converting the data-type description in. Figure 1 to a program ... code as a user-defined free data type. like DECL v1 ...

237KB Sizes 2 Downloads 219 Views

Recommend Documents

E cient Approaches to Subset Construction
Technology Research Center, and the Natural Sciences and Engineering ... necessary to analyze searching and sorting routines, abstract data types, and .... 6.4 Virtual Power-Bit Vector : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 5

Parallel Computing System for e cient computation of ...
Host Code: C++. The string comparison process is made in parallel. Device Code: CUDA for C. Raul Torres. Parallel Computing System for e cient computation ...

A Framework for Systematic Specification and E cient Verification of ...
then a description of an abstract level (such as the assembly language level), while its .... In section 6 we give veri cation benchmarks, and we last conclude.

The Legnaro Francium MOT: e cient detection ...
sensitive detection system based on a CCD camera and on subtraction of stray ...... written as a 6 6 matrix: H = ~. 0. BBBBBBBBBBBB@ 0 0 A A 0 0. 0 !b. 0 0 C C.

What is Power? Discuss different types of Power ... -
Theory Y aligns with the participative management style. b. Employee involvement programs provide intrinsic motivation. c. Theory X aligns with the autocratic ...

What Is Communication? Types Of Industry Economic ...
is one that provides community services to outside cities, and helps the overall community to grow, such as factories. On the other hand, a nonbasic industry is one that does not generate money from outside the community and provides service to basic

Efficient Enumeration of Phylogenetically Informative ...
Gibbs, R., Kent, W., Miller, W., Haussler, D.: Evolutionarily conserved elements in vertebrate, insect, worm, and yeast genomes. Genome Research 15(8) (2005). 1034–1050. 3. Bejerano, G., Pheasant, M., Makunin, I., Stephen, S., Kent, W., Mattick, J.

Changing Threat Perceptions and the Effi cient Provisioning of ...
†Contact Information: The Gabelli School of Business, Roger Williams ..... 9 I assume there is a simple linear technology converting effort to a level of security (by .... BA* and

The Nine Types of Coin Collectors - Apple
ceptions, (compare the Preservationist, the Researcher and .... internet. He is driven by the hope of getting his treasures off an unwitting private person for very ...

The Nine Types of Coin Collectors - Apple
I want to make a good profit from my coin purchases. → Read on ... I want to possess everything that is connected with my area of collecting. .... on the internet.

what is operating system and its types pdf
Page 1 of 1. File: What is operating system and its. types pdf. Download now. Click here if your download doesn't start automatically. Page 1 of 1.

what is computer virus and its types pdf
There was a problem previewing this document. Retrying... Download. Connect more apps... Try one of the apps below to open or edit this item.

TYPES OF STOICHIOMETRY.pdf
There was a problem previewing this document. Retrying... Download. Connect more apps... Try one of the apps below to open or edit this item. TYPES OF ...

Types of Intr.pdf
Protected mode. ∗ Real mode. • Software interrupts. ∗ Keyboard services. » int 21H DOS services. » int 16H BIOS services. • Exceptions. ∗ Single-step example.

Types of Network.pdf
There was a problem previewing this document. Retrying... Download. Connect more apps... Try one of the apps below to open or edit this item. Types of ...

Enumeration of singular hypersurfaces on arbitrary ...
Let q ∈ X and v1,...vm be a basis for TXq. Then there exists sections s1,...sm ∈ H0(X, L) such that for all i, j ∈ {1,2...m} si(q)=0,. ∇si|q(vi) = 0 and. ∇si|q(vj) = 0.

Types of Lines.pdf
Dimension lines, leader lines, extension lines, center lines, hidden lines, object lines, section. lines, cutting plane lines, break lines, broken lines, border are ...

Enumerated Types
{SMALL, MEDIUM, LARGE, XL}. • {TALL, VENTI, GRANDE}. • {WINDOWS, MAC_OS, LINUX} ... Structs struct pkmn. { char* name; char* type; int hp;. }; ...

Types of body representation and the sense of ...
Mar 24, 2008 - That is, a map of the body surface can serve as a reference ... that representation is part of the body image or the body schema. Take the ...... Why is one tool (represented visually) included in her representation of her body.

Types of body representation and the sense of ...
Mar 24, 2008 - A lack of access to online representations of the body does not nec- essarily lead to a loss in ...... This paper forms part of a project undertaken towards a PhD at the University of Adelaide. I thank Philip ... MIT press. First, M. B

Ef£cient PDA Synchronization
backup, in case the next synchronization will be performed in slow sync mode. ... cases, the status ¤ags do not reliably convey the differences between the synchronizing systems ..... is transferred in the Palm Database File (PDB) format.

Maximum Likelihood Estimation of Random Coeffi cient Panel Data ...
in large parts due to the fact that classical estimation procedures are diffi cult to ... estimation of Swamy random coeffi cient panel data models feasible, but also ...

Enumerated Types
This Week. • Hexadecimal. • Enumerated Types. • Structs. • Linked Lists. • File I/O ... Data structure composed of a set of structs. • Each struct contains a piece of ...