Modular Interpretive Decompilation of Low-Level Code by Partial - - PowerPoint PPT Presentation

modular interpretive decompilation of low level code by
SMART_READER_LITE
LIVE PREVIEW

Modular Interpretive Decompilation of Low-Level Code by Partial - - PowerPoint PPT Presentation

Modular Interpretive Decompilation of Low-Level Code by Partial Evaluation Elvira Albert 1 joint work with omez-Zamalloa 1 and Germ an Puebla 2 Miguel G (1) Complutense University of Madrid (Spain) (2) Technical University of Madrid (Spain)


slide-1
SLIDE 1

Modular Interpretive Decompilation of Low-Level Code by Partial Evaluation

Elvira Albert1 joint work with Miguel G´

  • mez-Zamalloa1 and Germ´

an Puebla2 (1) Complutense University of Madrid (Spain) (2) Technical University of Madrid (Spain) Beijing, September 2008

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 1 / 15

slide-2
SLIDE 2

Introduction Motivation

Introduction

Motivation

Low-level code ⇒ Intermediate representations Mobile environments: only low-level code available. Analysis tools unavoidably more complicated.

◮ unstructured control flow, ◮ use of operand stack, ◮ use of heap, etc. Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 2 / 15

slide-3
SLIDE 3

Introduction Motivation

Introduction

Motivation

Low-level code ⇒ Intermediate representations Mobile environments: only low-level code available. Analysis tools unavoidably more complicated.

◮ unstructured control flow, ◮ use of operand stack, ◮ use of heap, etc.

Decompiling to intermediate representations:

◮ abstracts away particular language features. ◮ simplifies development of analyzers, model checkers, etc. ◮ variants: clause-based, BoogiePL, Soot, etc. Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 2 / 15

slide-4
SLIDE 4

Introduction Motivation

Introduction

Motivation

Low-level code ⇒ Intermediate representations Mobile environments: only low-level code available. Analysis tools unavoidably more complicated.

◮ unstructured control flow, ◮ use of operand stack, ◮ use of heap, etc.

Decompiling to intermediate representations:

◮ abstracts away particular language features. ◮ simplifies development of analyzers, model checkers, etc. ◮ variants: clause-based, BoogiePL, Soot, etc.

High-level (declarative) languages Convenient intermediate representation:

◮ iterative constructs (loops) ⇒ recursion. ◮ all variables in local scope of methods represented uniformly.

Advanced tools (for declarative) languages re-used.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 2 / 15

slide-5
SLIDE 5

Introduction Interpretive Decompilation

Introduction

Interpretive Decompilation

Most of the approaches develop hand-written decompilers. Appealing alternative: interpretive decompilation PE allows specializing a program w.r.t. some part of its input.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 3 / 15

slide-6
SLIDE 6

Introduction Interpretive Decompilation

Introduction

Interpretive Decompilation

Most of the approaches develop hand-written decompilers. Appealing alternative: interpretive decompilation PE allows specializing a program w.r.t. some part of its input.

Definition (1st Futamura Projection)

A program P written in LS can be compiled into another language LO by specializing an interpreter for LS written in LO w.r.t. P.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 3 / 15

slide-7
SLIDE 7

First Futamura Projection Partial Evaluation and the Interpretive Approach

First Futamura Projection

Partial Evaluation and the Interpretive Approach

p(in1, in2) = output

✲ ✓ ✒ ✏ ✑ data (in2) dynamic = programs = data ✞ ✝ ☎ ✆ ✲ ✲✎ ✍ ☞ ✌

  • utput

p pin1 ❄ ❄ ❄ ✛ ✚ ✘ ✙ program specialized ✲ ✗ ✖ ✔ ✕ program ✗ ✖ ✔ ✕ data static (in1) evaluator(mix) partial

[[p]] [in1, in2] = [[ [[mix]] [p, in1] ]] [in2]

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 4 / 15

slide-8
SLIDE 8

First Futamura Projection Partial Evaluation and the Interpretive Approach

First Futamura Projection

Partial Evaluation and the Interpretive Approach

p(in1, in2) = output

✲ ✓ ✒ ✏ ✑ data (in2) dynamic = programs = data ✞ ✝ ☎ ✆ ✲ ✲✎ ✍ ☞ ✌

  • utput

bytecode pin1 ❄ ❄ ❄ ✛ ✚ ✘ ✙ program specialized ✲ ✗ ✖ ✔ ✕ interp(LP) ✗ ✖ ✔ ✕ data static (in1) evaluator(mix) partial

[[bc interp]] [in1, in2] = [[ [[mix]] [bc interp, in1] ]] [in2]

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 4 / 15

slide-9
SLIDE 9

First Futamura Projection Partial Evaluation and the Interpretive Approach

First Futamura Projection

Partial Evaluation and the Interpretive Approach

p(in1, in2) = output

✲ ✓ ✒ ✏ ✑ data (in2) dynamic = programs = data ✞ ✝ ☎ ✆ ✲ ✲✎ ✍ ☞ ✌

  • utput

bytecode pin1 ❄ ❄ ❄ ✛ ✚ ✘ ✙ program specialized ✲ ✗ ✖ ✔ ✕ interp(LP) ✗ ✖ ✔ ✕ (in1) program bytecode evaluator(mix) partial

[[bc interp]] [in1, in2] = [[ [[mix]] [bc interp, in1] ]] [in2]

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 4 / 15

slide-10
SLIDE 10

First Futamura Projection Partial Evaluation and the Interpretive Approach

First Futamura Projection

Partial Evaluation and the Interpretive Approach

p(in1, in2) = output

✲ ✓ ✒ ✏ ✑ args (in2) input = programs = data ✞ ✝ ☎ ✆ ✲ ✲✎ ✍ ☞ ✌

  • utput

bytecode pin1 ❄ ❄ ❄ ✛ ✚ ✘ ✙ program specialized ✲ ✗ ✖ ✔ ✕ interp(LP) ✗ ✖ ✔ ✕ (in1) program bytecode evaluator(mix) partial

[[bc interp]] [in1, in2] = [[ [[mix]] [bc interp, in1] ]] [in2]

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 4 / 15

slide-11
SLIDE 11

First Futamura Projection Partial Evaluation and the Interpretive Approach

First Futamura Projection

Partial Evaluation and the Interpretive Approach

p(in1, in2) = output

✲ ✓ ✒ ✏ ✑ args (in2) input = programs = data ✞ ✝ ☎ ✆ ✲ ✲✎ ✍ ☞ ✌

  • utput

bytecode pin1 ❄ ❄ ❄ ✛ ✚ ✘ ✙ program(LP) decompiled ✲ ✗ ✖ ✔ ✕ interp(LP) ✗ ✖ ✔ ✕ (in1) program bytecode evaluator(mix) partial

[[bc interp]] [in1, in2] = [[ [[mix]] [bc interp, in1] ]] [in2]

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 4 / 15

slide-12
SLIDE 12

An Example of Interpretive Decompilation

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;}

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 5 / 15

slide-13
SLIDE 13

An Example of Interpretive Decompilation

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 5 / 15

slide-14
SLIDE 14

An Example of Interpretive Decompilation

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return

bytecode interpreter

main(Method,InArgs,Top) :- build s0(InArgs,S0), execute(S0,Sf), Sf = st( ,[Top| ], )). execute(S1,Sf) :- S1 = st(PC, , )), bytecode(PC,Inst, ), step(Inst,S1,S2) , execute(S2,Sf). ...... step(push(X),S1,S2) :- S1 = st(PC,S,L)), next(PC,PC2), S2 = st(PC2,[X|S],L)). step(store(X),S1,S2) :- S1 = st(PC,[I|S],LV)), next(PC,PC2), localVar update(LV,X,I,LV2), S2 = st(PC2,S,LV2)). .............

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 5 / 15

slide-15
SLIDE 15

An Example of Interpretive Decompilation

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return

bytecode interpreter

main(Method,InArgs,Top) :- build s0(InArgs,S0), execute(S0,Sf), Sf = st( ,[Top| ], )). execute(S1,Sf) :- S1 = st(PC, , )), bytecode(PC,Inst, ), step(Inst,S1,S2) , execute(S2,Sf). ...... step(push(X),S1,S2) :- S1 = st(PC,S,L)), next(PC,PC2), S2 = st(PC2,[X|S],L)). step(store(X),S1,S2) :- S1 = st(PC,[I|S],LV)), next(PC,PC2), localVar update(LV,X,I,LV2), S2 = st(PC2,S,LV2)). ............. Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z). exec 1(Y,0,Y). exec 1(Y,R,Z) :- R \= 0, R’ is Y rem R, exec 1(R,R’,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 5 / 15

slide-16
SLIDE 16

Contributions in Interpretive Decompilation

Contributions in Interpretive Decompilation

Advantages w.r.t. dedicated (de-)compilers: flexibility: interpreter easier to modify; more reliable: easier to trust that the semantics preserved; easier to maintain: new changes easily reflected in interpreter; easier to implement: provided a partial evaluator is available.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 6 / 15

slide-17
SLIDE 17

Contributions in Interpretive Decompilation

Contributions in Interpretive Decompilation

Advantages w.r.t. dedicated (de-)compilers: flexibility: interpreter easier to modify; more reliable: easier to trust that the semantics preserved; easier to maintain: new changes easily reflected in interpreter; easier to implement: provided a partial evaluator is available. Only proofs-of-concept in interpretive decompilation: e.g. in [PADL’07] we decompile a subset of Java Bytecode to Prolog. Open issues we have answered in this work:

◮ Scalability: first modular decompilation scheme by PE ◮ Structure preservation: of the original program ◮ Quality: equivalent to hand-written decompilers Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 6 / 15

slide-18
SLIDE 18

Conclusions and Future Work

Conclusions and Future Work

We have provided mechanisms to positively answer these issues:

◮ Method optimality: Code for each method is decompiled only once ⇒

Big-step interpreter and PE annotations.

◮ Block optimality: Code for each instruction is emitted and evaluated at

most once ⇒ PE annotations and pre-analysis.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 7 / 15

slide-19
SLIDE 19

Conclusions and Future Work

Conclusions and Future Work

We have provided mechanisms to positively answer these issues:

◮ Method optimality: Code for each method is decompiled only once ⇒

Big-step interpreter and PE annotations.

◮ Block optimality: Code for each instruction is emitted and evaluated at

most once ⇒ PE annotations and pre-analysis.

Implemented an interpretive decompiler of Java Bytecode to Prolog.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 7 / 15

slide-20
SLIDE 20

Conclusions and Future Work

Conclusions and Future Work

We have provided mechanisms to positively answer these issues:

◮ Method optimality: Code for each method is decompiled only once ⇒

Big-step interpreter and PE annotations.

◮ Block optimality: Code for each instruction is emitted and evaluated at

most once ⇒ PE annotations and pre-analysis.

Implemented an interpretive decompiler of Java Bytecode to Prolog. Future work: Special handling for the heap, exploit instrumented decompilation, improve efficiency, applications, etc.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 7 / 15

slide-21
SLIDE 21

Question to SCAM Audience

Question to SCAM Audience

Are we happy with hand-written decompilers or we would like more flexible approaches?

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 8 / 15

slide-22
SLIDE 22

Contributions Contribution 1

Contributions

Contribution 1

Modular decompilation: decompile a method at a time First modular decompilation scheme by PE:

◮ compositional treatment to method invocation ⇒ consider a big-step

interpreter;

◮ “residualize” calls in decompiled program, we automatically generate

program annotations for this purpose;

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 9 / 15

slide-23
SLIDE 23

Contributions Contribution 1

Contributions

Contribution 1

Modular decompilation: decompile a method at a time First modular decompilation scheme by PE:

◮ compositional treatment to method invocation ⇒ consider a big-step

interpreter;

◮ “residualize” calls in decompiled program, we automatically generate

program annotations for this purpose;

Proposition (modular optimality)

We decompile the code corresponding to each method in Pbc exactly once.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 9 / 15

slide-24
SLIDE 24

Decompilation of Low-level Code Contribution 2

Decompilation of Low-level Code

Contribution 2

Is possible to obtain by interpretive decompilation programs whose quality is equivalent to dedicated decompilers? Idea: since decompilers first build a CFG for the method, study how a similar notion can be used for controlling PE of the interpreter Block-level decompilation produce a rule for each block in the CFG.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 10 / 15

slide-25
SLIDE 25

Decompilation of Low-level Code Contribution 2

Decompilation of Low-level Code

Contribution 2

Is possible to obtain by interpretive decompilation programs whose quality is equivalent to dedicated decompilers? Idea: since decompilers first build a CFG for the method, study how a similar notion can be used for controlling PE of the interpreter Block-level decompilation produce a rule for each block in the CFG.

Proposition (block optimality)

1

residual code for each bytecode instruction emitted once;

2

each bytecode instruction evaluated at most once;

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 10 / 15

slide-26
SLIDE 26

Conclusions and Future Work

Conclusions and Future Work

Open issues: scalability, structure preservation, quality ... We have provided mechanisms to positively answer these issues:

◮ Method optimality: Code for each method is decompiled only once ⇒

Big-step semantics and PE annotations.

◮ Block optimality: Code for each instruction is emitted and evaluated at

most once ⇒ PE annotations and pre-analysis.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 11 / 15

slide-27
SLIDE 27

Conclusions and Future Work

Conclusions and Future Work

Open issues: scalability, structure preservation, quality ... We have provided mechanisms to positively answer these issues:

◮ Method optimality: Code for each method is decompiled only once ⇒

Big-step semantics and PE annotations.

◮ Block optimality: Code for each instruction is emitted and evaluated at

most once ⇒ PE annotations and pre-analysis.

Implemented an interpretive decompiler of Java Bytecode to Prolog. Average improvements: 10 times faster decompilations and 5 times smaller decompiled program sizes (even we get ∞ gains).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 11 / 15

slide-28
SLIDE 28

Conclusions and Future Work

Conclusions and Future Work

Open issues: scalability, structure preservation, quality ... We have provided mechanisms to positively answer these issues:

◮ Method optimality: Code for each method is decompiled only once ⇒

Big-step semantics and PE annotations.

◮ Block optimality: Code for each instruction is emitted and evaluated at

most once ⇒ PE annotations and pre-analysis.

Implemented an interpretive decompiler of Java Bytecode to Prolog. Average improvements: 10 times faster decompilations and 5 times smaller decompiled program sizes (even we get ∞ gains). Future work: Special handling for the heap, exploit instrumented decompilation, improve efficiency, applications, etc.

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 11 / 15

slide-29
SLIDE 29

Experimental Evaluation (JOlden benchmarks suite)

Experimental Evaluation (JOlden benchmarks suite)

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 12 / 15

slide-30
SLIDE 30

Intraprocedural Decompilation Lbc -bytecode Language and Interpreter

Intraprocedural Decompilation

We consider the Lbc-bytecode language (Lbc ⊂ Java bytecode).

Inst ::= push(x) | load(v) | store(v) | add | sub | mul | div | rem | neg | if ⋄ (pc) | if0 ⋄ (pc) | goto(pc) | return

State ≡ PC, OpStack, LocalVars

The Lbc-bytecode interpreter

main(Method,InArgs,Top) :- build s0(InArgs,S0), execute(S0,Sf), Sf = st( ,[Top| ], )). execute(S,S) :- S = st(PC,[ Top| ], )), bytecode(PC,return, ). execute(S1,Sf) :- S1 = st(PC, , )), bytecode(PC,Inst, ), step(Inst,S1,S2), execute(S2,Sf). step(push(X),S1,S2) :- S1 = st(PC,S,L)), next(PC,PC2), S2 = st(PC2,[X|S],L)). step(store(X),S1,S2) :- S1 = st(PC,[I|S],LV)), next(PC,PC2), localVar update(LV,X,I,LV2), S2 = st(PC2,S,LV2)). step(goto(PC),S1,S2) :- S1 = st( ,S,LV)), S2 = st(PC,S,LV)).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 13 / 15

slide-31
SLIDE 31

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-32
SLIDE 32

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z) Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-33
SLIDE 33

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)

Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-34
SLIDE 34

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-35
SLIDE 35

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • exec(st(11, [], [X, 0, 0]), Sf)
  • true

Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-36
SLIDE 36

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • exec(st(11, [], [X, 0, 0]), Sf)
  • true

Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-37
SLIDE 37

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

true Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-38
SLIDE 38

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

{R is X rem Y }

true exec(st(10, [], [Y, R, R]), Sf) Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-39
SLIDE 39

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

{R is X rem Y }

true exec(st(10, [], [Y, R, R]), Sf)

  • exec(st(0, [], [Y, R, R]), Sf)

Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-40
SLIDE 40

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

{R is X rem Y }

true exec(st(10, [], [Y, R, R]), Sf)

  • exec(st(0, [], [Y, R, R]), Sf)

Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-41
SLIDE 41

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees exec(st(0, [], [Y, R, R]), Sf) Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-42
SLIDE 42

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees exec(st(0, [], [Y, R, R]), Sf)

  • exec(st(1, [R], [Y, R, R]), Sf)

{R=0}

  • {R=0}
  • exec(st(12, [], [Y, 0, 0]), Sf)
  • exec(st(2, [], [Y, R, R]), Sf)

{R′ is Y rem R}

true exec(st(10, [], [R, R′, Z]), Sf)

  • exec(st(0, [], [R, R′, Z]), Sf)

Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-43
SLIDE 43

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees exec(st(0, [], [Y, R, R]), Sf)

  • exec(st(1, [R], [Y, R, R]), Sf)

{R=0}

  • {R=0}
  • exec(st(12, [], [Y, 0, 0]), Sf)
  • exec(st(2, [], [Y, R, R]), Sf)

{R′ is Y rem R}

true exec(st(10, [], [R, R′, Z]), Sf)

  • exec(st(0, [], [R, R′, Z]), Sf)

Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z). exec 1(Y,0,Y). exec 1(Y,R,Z) :- R \= 0, R’ is Y rem R, exec 1(R,R’,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 14 / 15

slide-44
SLIDE 44

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-45
SLIDE 45

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z) Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-46
SLIDE 46

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)

Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-47
SLIDE 47

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-48
SLIDE 48

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • exec(st(11, [], [X, 0, 0]), Sf)
  • true

Decompiled code

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-49
SLIDE 49

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • exec(st(11, [], [X, 0, 0]), Sf)
  • true

Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-50
SLIDE 50

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

true Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-51
SLIDE 51

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

{R is X rem Y }

true exec(st(10, [], [Y, R, R]), Sf) Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-52
SLIDE 52

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

{R is X rem Y }

true exec(st(10, [], [Y, R, R]), Sf)

  • exec(st(0, [], [Y, R, R]), Sf)

Decompiled code main(gcd,[X,0],X).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-53
SLIDE 53

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees main(gcd, [X, Y], Z)

  • exec(st(0, [], [X, Y, 0]), Sf)
  • exec(st(1, [Y], [X, Y, 0]), Sf)

{Y =0}

  • {Y =0}
  • exec(st(11, [], [X, 0, 0]), Sf)
  • exec(st(2, [], [X, Y, 0]), Sf)

{R is X rem Y }

true exec(st(10, [], [Y, R, R]), Sf)

  • exec(st(0, [], [Y, R, R]), Sf)

Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-54
SLIDE 54

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees exec(st(0, [], [Y, R, R]), Sf) Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-55
SLIDE 55

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees exec(st(0, [], [Y, R, R]), Sf)

  • exec(st(1, [R], [Y, R, R]), Sf)

{R=0}

  • {R=0}
  • exec(st(12, [], [Y, 0, 0]), Sf)
  • exec(st(2, [], [Y, R, R]), Sf)

{R′ is Y rem R}

true exec(st(10, [], [R, R′, Z]), Sf)

  • exec(st(0, [], [R, R′, Z]), Sf)

Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15

slide-56
SLIDE 56

Intraprocedural Decompilation Example 1

Example 1: Source code int gcd(int x,int y){ int res; while (y != 0){ res = x mod y; x = y; y = res;} return x;} Lbc-bytecode 0:load(1) 1:if0eq(11) 2:load(0) 3:load(1) 4:rem 5:store(2) 6:load(1) 7:store(0) 8:load(2) 9:store(1) 10:goto(0) 11:load(0) 12:return Unfolding trees exec(st(0, [], [Y, R, R]), Sf)

  • exec(st(1, [R], [Y, R, R]), Sf)

{R=0}

  • {R=0}
  • exec(st(12, [], [Y, 0, 0]), Sf)
  • exec(st(2, [], [Y, R, R]), Sf)

{R′ is Y rem R}

true exec(st(10, [], [R, R′, Z]), Sf)

  • exec(st(0, [], [R, R′, Z]), Sf)

Decompiled code main(gcd,[X,0],X). main(gcd,[X,Y],Z) :- Y \= 0, R is X rem Y, exec 1(Y,R,Z). exec 1(Y,0,Y). exec 1(Y,R,Z) :- R \= 0, R’ is Y rem R, exec 1(R,R’,Z).

Elvira Albert (UCM) Interpretive Decomp. of Low-Level Code Beijing, September 2008 15 / 15