29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/VoidElement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | public class VoidElement extends StackElement {
23 | @Override
24 | public StackElement copy() {
25 | return new VoidElement();
26 | }
27 | @Override
28 | public String toString() {
29 | return "Void";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/subjects/Common.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package test.subjects;
21 |
22 | public class Common {
23 | public static void classic(String s, int i, long j) { }
24 | public static void varargs(int... integers) { }
25 | public static void mixed(String s, long j, int... integers) { }
26 | public static void mixed2(double d, int... integers) { }
27 | }
28 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2011 Stephane Godbillon
2 |
3 | BytecodeParser is a java library that can help you statically to parse java
4 | bytecode by extracting as much information as possible. It can also statically
5 | analyze each method's frame, for particular purposes like retrieving the names
6 | of the local variable names given as parameters of a method call (its original
7 | purpose), check if all the frames are reachable, etc.
8 |
9 | BytecodeParser is released under the GNU Lesser General Public License
10 | (LGPL), version 3 (or any later version at your option).
11 |
12 | BytecodeParser is free software: you can redistribute it and/or modify
13 | it under the terms of the GNU Lesser General Public License as published by
14 | the Free Software Foundation, either version 3 of the License, or
15 | (at your option) any later version.
16 |
17 | BytecodeParser is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | GNU Lesser General Public License for more details.
21 |
22 | You should have received a copy of the GNU Lesser General Public License
23 | along with BytecodeParser. If not, see .
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/TOP.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | /**
23 | * A StackElement that is a part of a two-words Element.
24 | * @author Stephane Godbillon
25 | *
26 | */
27 | public class TOP extends StackElement {
28 | @Override
29 | public StackElement copy() {
30 | return new TOP();
31 | }
32 | @Override
33 | public String toString() {
34 | return "TOP";
35 | }
36 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/StackElement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | /**
23 | * A Stack Element.
24 | * @author Stephane Godbillon
25 | *
26 | */
27 | public abstract class StackElement {
28 | /**
29 | * @return a copy of this StackElement.
30 | */
31 | public abstract StackElement copy();
32 | @Override public String toString() {
33 | return this.getClass().toString();
34 | }
35 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/Whatever.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | /**
23 | * A StackElement of something we don't know anything about at compile-time.
24 | * @author Stephane Godbillon
25 | *
26 | */
27 | public class Whatever extends StackElement {
28 | @Override
29 | public StackElement copy() {
30 | return new Whatever();
31 | }
32 | @Override
33 | public String toString() {
34 | return "Whatever";
35 | }
36 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/OpHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import bytecodeparser.analysis.opcodes.Op;
23 |
24 | /**
25 | * A handler for opcodes, used when parsing bytecode with the CodeParser.
26 | * @author Stephane Godbillon
27 | * @see CodeParser#parse(OpHandler)
28 | */
29 | public interface OpHandler {
30 | /**
31 | * Handle the given op at the given index.
32 | * @param op
33 | * @param index
34 | */
35 | void handle(Op op, int index);
36 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/SwitchOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.decoders.DecodedSwitchOpcode;
24 |
25 | /**
26 | * LookupSwitch or TableSwitch opcode.
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class SwitchOpcode extends Op {
31 |
32 | public SwitchOpcode(int code) {
33 | super(code);
34 | }
35 |
36 | @Override
37 | public DecodedSwitchOpcode decode(Context context, int index) {
38 | return new DecodedSwitchOpcode(this, context, index);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/Array.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | /**
23 | * A StackElement that stands for an array.
24 | * @author Stephane Godbillon
25 | *
26 | */
27 | public class Array extends StackElement {
28 | /**
29 | * The signature of this array.
30 | */
31 | public final String signature;
32 | public Array(String signature) {
33 | this.signature = signature;
34 | }
35 | @Override
36 | public Array copy() {
37 | return new Array(signature);
38 | }
39 | @Override
40 | public String toString() {
41 | return "simple array of '" + signature + "'";
42 | }
43 | }
--------------------------------------------------------------------------------
/documentation/api/stylesheet.css:
--------------------------------------------------------------------------------
1 | /* Javadoc style sheet */
2 |
3 | /* Define colors, fonts and other style attributes here to override the defaults */
4 |
5 | /* Page background color */
6 | body { background-color: #FFFFFF; color:#000000 }
7 |
8 | /* Headings */
9 | h1 { font-size: 145% }
10 |
11 | /* Table colors */
12 | .TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */
13 | .TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */
14 | .TableRowColor { background: #FFFFFF; color:#000000 } /* White */
15 |
16 | /* Font used in left-hand frame lists */
17 | .FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
18 | .FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
19 | .FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
20 |
21 | /* Navigation bar fonts and colors */
22 | .NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */
23 | .NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */
24 | .NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;}
25 | .NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;}
26 |
27 | .NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
28 | .NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
29 |
30 |
--------------------------------------------------------------------------------
/documentation/api/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | BytecodeParser API
8 |
9 |
20 |
22 |
23 |
39 |
40 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedBranchOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.opcodes.BasicOpcode;
24 |
25 | /**
26 | * A decoded branch op.
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class DecodedBranchOp extends DecodedBasicOp {
31 | private final int jump;
32 |
33 | public DecodedBranchOp(BasicOpcode op, Context context, int index) {
34 | super(op, context, index);
35 | jump = parameterValues[0];
36 | }
37 |
38 | /**
39 | * @return the index this decoded op will jump to.
40 | */
41 | public int getJump() {
42 | return jump + index;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/documentation/api/bytecodeparser/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | bytecodeparser (BytecodeParser API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | bytecodeparser
20 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ArrayCreationOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedArrayCreationOp;
25 |
26 | /**
27 | * An array creation opcode.
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class ArrayCreationOpcode extends BasicOpcode {
32 | public ArrayCreationOpcode(int code, OpParameterType... opParameterTypes) {
33 | super(code, opParameterTypes);
34 | }
35 | @Override
36 | public DecodedArrayCreationOp decode(Context context, int index) {
37 | return new DecodedArrayCreationOp(this, context, index);
38 | }
39 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ExitOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.analysis.Opcodes.OpParameterType;
23 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
24 |
25 | /**
26 | * An opcode that stands for an exit of the behavior (like a return).
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class ExitOpcode extends BasicOpcode {
31 | public ExitOpcode(int code, OpParameterType... opParameterTypes) {
32 | super(code, opParameterTypes);
33 | }
34 | public ExitOpcode(int code, StackElementLength[] pops, StackElementLength[] pushes, OpParameterType... opParameterTypes) {
35 | super(code, pops, pushes, opParameterTypes);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/documentation/api/bytecodeparser/analysis/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | bytecodeparser.analysis (BytecodeParser API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | bytecodeparser.analysis
20 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | org.sgodbillon
6 | bytecode-parser
7 | 1.0-SNAPSHOT
8 | jar
9 |
10 | bytecode-parser
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 |
19 | javassist
20 | javassist
21 | 3.12.1.GA
22 |
23 |
24 | log4j
25 | log4j
26 | 1.2.17
27 |
28 |
29 | junit
30 | junit
31 | 4.8.2
32 | test
33 |
34 |
35 |
36 |
37 | src
38 | src/test
39 |
40 |
41 |
42 | maven-compiler-plugin
43 | 2.3.2
44 |
45 | 1.6
46 | 1.6
47 |
48 | bytecodeparser/**
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ArrayOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedArrayOp;
25 |
26 | /**
27 | * An opcode that is an operation on an array.
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class ArrayOpcode extends BasicOpcode {
32 | /**
33 | * States if the operation is a read (load -> true) or a write (store -> false).
34 | */
35 | public final boolean isLoad;
36 |
37 | public ArrayOpcode(int code, boolean isLoad, OpParameterType... opParameterTypes) {
38 | super(code, opParameterTypes);
39 | this.isLoad = isLoad;
40 | }
41 |
42 | @Override
43 | public DecodedArrayOp decode(Context context, int index) {
44 | return new DecodedArrayOp(this, context, index);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/ValueFromLocalVariable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | import bytecodeparser.analysis.LocalVariable;
23 |
24 | /**
25 | * A StackElement representing a value that was read from a localVariable (so the value may be known at this time).
26 | * @author Stephane Godbillon
27 | *
28 | */
29 | public class ValueFromLocalVariable extends StackElement {
30 | /**
31 | * The local variable from which this value was read.
32 | */
33 | public final LocalVariable localVariable;
34 | public ValueFromLocalVariable(LocalVariable localVariable) {
35 | this.localVariable = localVariable;
36 | }
37 | @Override
38 | public StackElement copy() {
39 | return new ValueFromLocalVariable(localVariable);
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return "ValueFromLocalVariable '" + (localVariable != null ? localVariable.name : "NONAME") + "'";
45 | }
46 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ConstantPushOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedConstantPushOp;
25 |
26 | /**
27 | * An opcode that stands for a push of a constant onto the stack.
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class ConstantPushOpcode extends BasicOpcode {
32 | public final int baseCode;
33 |
34 | public ConstantPushOpcode(int code, OpParameterType... opParameterTypes) {
35 | this(code, code, opParameterTypes);
36 | }
37 |
38 | public ConstantPushOpcode(int code, int baseCode, OpParameterType... opParameterTypes) {
39 | super(code, opParameterTypes);
40 | this.baseCode = baseCode;
41 | }
42 |
43 | @Override
44 | public DecodedConstantPushOp decode(Context context, int index) {
45 | return new DecodedConstantPushOp(this, context, index);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/MethodInvocationOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import static bytecodeparser.analysis.Opcodes.OpParameterType.U2;
23 | import javassist.bytecode.Opcode;
24 | import bytecodeparser.Context;
25 | import bytecodeparser.analysis.decoders.DecodedMethodInvocationOp;
26 |
27 | /**
28 | * An opcode that stands for a method invocation.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class MethodInvocationOpcode extends Op {
33 | public MethodInvocationOpcode(int code) {
34 | super(code, U2);
35 | }
36 | /**
37 | * States if the invoked method is static or not.
38 | */
39 | public boolean isInstanceMethod() {
40 | return code != Opcode.INVOKESTATIC;
41 | }
42 | @Override
43 | public DecodedMethodInvocationOp decode(Context context, int index) {
44 | try {
45 | return new DecodedMethodInvocationOp(this, context, index);
46 | } catch (Exception e) {
47 | throw new RuntimeException(e);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/documentation/api/overview-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Overview List (BytecodeParser API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedWideOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes;
24 | import bytecodeparser.analysis.opcodes.LocalVariableOpcode;
25 | import bytecodeparser.analysis.opcodes.WideOpcode;
26 | import bytecodeparser.analysis.stack.Stack;
27 |
28 | /**
29 | * A decoded wide local variable operation op.
30 | * @author Stephane Godbillon
31 | *
32 | */
33 | public class DecodedWideOp extends DecodedOp {
34 | /**
35 | * The wrapped decoded local variable opcode.
36 | */
37 | public final DecodedLocalVariableOp wrappedDecodedLocalVariableOp;
38 |
39 | public DecodedWideOp(WideOpcode wide, Context context, int index) {
40 | super(wide, context, index);
41 | wrappedDecodedLocalVariableOp = Opcodes.OPCODES.get(context.iterator.byteAt(index + 1)).as(LocalVariableOpcode.class).decodeWide(context, index);
42 | }
43 |
44 | @Override
45 | public void simulate(Stack stack) {
46 | wrappedDecodedLocalVariableOp.simulate(stack);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/FieldOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import static bytecodeparser.analysis.Opcodes.OpParameterType.U2;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.decoders.DecodedFieldOp;
25 |
26 | /**
27 | * An opcode concerning a field (read, write).
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class FieldOpcode extends Op {
32 | private final DecodedFieldOp decodedOp;
33 |
34 | public FieldOpcode(int code) {
35 | this(code, null);
36 | }
37 | private FieldOpcode(int code, DecodedFieldOp decodedOp) {
38 | super(code, U2);
39 | this.decodedOp = decodedOp;
40 | }
41 | @Override
42 | public FieldOpcode init(Context context, int index) {
43 | return new FieldOpcode(code, decode(context, index));
44 | }
45 | @Override
46 | public DecodedFieldOp decode(Context context, int index) {
47 | if(decodedOp != null)
48 | return decodedOp;
49 | try {
50 | DecodedFieldOp decodedOp = new DecodedFieldOp(this, context, index);
51 | return decodedOp;
52 | } catch (Exception e) {
53 | throw new RuntimeException(e);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/BranchOpCode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import javassist.bytecode.Opcode;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.Opcodes.OpParameterType;
25 | import bytecodeparser.analysis.decoders.DecodedBranchOp;
26 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
27 |
28 | /**
29 | * An opcode that stands for a fork in the bytecode.
30 | * @author Stephane Godbillon
31 | *
32 | */
33 | public class BranchOpCode extends BasicOpcode {
34 | public BranchOpCode(int code, OpParameterType... opParameterTypes) {
35 | super(code, opParameterTypes);
36 | }
37 | public BranchOpCode(int code, StackElementLength[] pops, StackElementLength[] pushes, OpParameterType... opParameterTypes) {
38 | super(code, pops, pushes, opParameterTypes);
39 | }
40 |
41 | @Override
42 | public DecodedBranchOp decode(Context context, int index) {
43 | return new DecodedBranchOp(this, context, index);
44 | }
45 |
46 | /**
47 | * States if this opcode is conditional fork or not.
48 | */
49 | public boolean isConditional() {
50 | return code >= Opcode.IFEQ && code <= Opcode.IF_ACMPNE || code == Opcode.IFNULL || code == Opcode.IFNONNULL;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedBasicOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.opcodes.BasicOpcode;
24 | import bytecodeparser.analysis.stack.Stack;
25 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
26 |
27 | /**
28 | * A decoded basic op.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class DecodedBasicOp extends DecodedOp {
33 | /**
34 | * Pops needed by this decoded op.
35 | */
36 | public final StackElementLength[] pops;
37 | /**
38 | * Pushes needed by this decoded op.
39 | */
40 | public final StackElementLength[] pushes;
41 |
42 | public DecodedBasicOp(BasicOpcode op, Context context, int index) {
43 | super(op, context, index);
44 |
45 | this.pops = op.getPops();
46 | this.pushes = op.getPushes();
47 | }
48 |
49 | @Override
50 | public void simulate(Stack stack) {
51 | Stack.processBasicAlteration(stack, getPops(), getPushes());
52 | }
53 |
54 | /**
55 | * Pops needed by this decoded op.
56 | */
57 | public StackElementLength[] getPops() {
58 | return pops;
59 | }
60 |
61 | /**
62 | * Pushes needed by this decoded op.
63 | */
64 | public StackElementLength[] getPushes() {
65 | return pushes;
66 | }
67 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/MultiMarkerCodeIterator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import java.util.ArrayList;
23 |
24 | import javassist.bytecode.CodeAttribute;
25 | import javassist.bytecode.CodeIterator;
26 |
27 | /**
28 | * A code iterator that tracks more than one mark in the bytecode.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class MultiMarkerCodeIterator extends CodeIterator {
33 | public ArrayList marks = new ArrayList();
34 |
35 | protected MultiMarkerCodeIterator(CodeAttribute ca) {
36 | super(ca);
37 | }
38 |
39 | @Override
40 | protected void updateCursors(int pos, int length) {
41 | super.updateCursors(pos, length);
42 | for(int i = 0; i < marks.size(); i++) {
43 | int mark = marks.get(i);
44 | if(mark > pos)
45 | marks.set(i, mark + length);
46 | }
47 | }
48 |
49 | /**
50 | * Puts a mark on the given index in the bytecode.
51 | * @param index
52 | * @return the id of this mark, in order to get it later.
53 | */
54 | public int putMark(int index) {
55 | marks.add(index);
56 | return marks.size() - 1;
57 | }
58 |
59 | /**
60 | * Gets the index in the bytecode tracked by the mark matching the given mark id.
61 | * @param mark the mark id.
62 | * @return the index of this mark.
63 | */
64 | public int getMark(int mark) {
65 | return marks.get(mark);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/LocalVariableOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.decoders.DecodedLocalVariableOp;
24 |
25 | /**
26 | * An opcode concerning a local variable (read, write).
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class LocalVariableOpcode extends Op {
31 | private final int base;
32 | private final boolean load;
33 |
34 | public LocalVariableOpcode(int code, boolean load) {
35 | this(code, code, load);
36 | }
37 | public LocalVariableOpcode(int code, int base, boolean load) {
38 | super(code);
39 | this.base = base;
40 | this.load = load;
41 | }
42 |
43 | @Override
44 | public DecodedLocalVariableOp decode(Context context, int index) {
45 | return new DecodedLocalVariableOp(this, context, index, false);
46 | }
47 |
48 | public DecodedLocalVariableOp decodeWide(Context context, int index) {
49 | return new DecodedLocalVariableOp(this, context, index, true);
50 | }
51 |
52 | public int getBaseOpcode() {
53 | return base;
54 | }
55 |
56 | /**
57 | * States if this opcode is a read (load -> true) or a write (store -> false).
58 | * @return
59 | */
60 | public boolean isLoad() {
61 | return load;
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return "LocalVariableOp: " + getName();
67 | }
68 | }
--------------------------------------------------------------------------------
/README.textile:
--------------------------------------------------------------------------------
1 | h1. BytecodeParser
2 |
3 | p. BytecodeParser is a java library that can help you statically to parse java bytecode by extracting as much information as possible. It is based upon "javassist":http://www.csg.is.titech.ac.jp/~chiba/javassist/.
4 |
5 | p. It can also statically analyze each method's frame, for particular purposes like retrieving the names of the local variable names given as parameters of a method call (its original purpose), check if all the frames are reachable, etc.
6 |
7 | p. BytecodeParser simulates the stack operations made by the opcodes in the CodeAttribute. It can give you the state of the stack before and after the frame is run.
8 |
9 | p. BytecodeParser is released under the "LGPL, version 3":http://www.gnu.org/licenses/lgpl.html. It is actively developped. You can download the latest version ("v0.3":http://sgodbillon.github.com/BytecodeParser/releases/0.3/bytecodeparser-0.3.jar), explore its capabilities and extend it if you need to.
10 |
11 | h2. How to use it
12 |
13 | p. See the "project's website":http://sgodbillon.github.com/BytecodeParser/ for detailed examples and more information. You can also "browse the API":http://sgodbillon.github.com/BytecodeParser/releases/0.3/api/index.html.
14 |
15 | h2. A small example
16 |
17 | bc. ClassPool cp = new ClassPool();
18 | CtClass ctClass = cp.getCtClass("org.myapp.MyClass");
19 | for(CtMethod method: ctClass.getMethods()) {
20 | StackAnalyzer stackAnalyzer = new StackAnalyzer(method);
21 | for(Frame frame: stackAnalyzer.analyze()) {
22 | // you can get the state of the stack before or after this frame with frame.stackBefore and frame.stackAfter
23 | System.out.println(frame.stackBefore + " => " + frame.stackAfter);
24 | // you can also get some extended information about this frame with frame.decodedOp
25 | if(frame.decodedOp instanceof DecodedMethodInvocationOp) {
26 | DecodedMethodInvocationOp dmio = (DecodedMethodInvocationOp) frame.decodedOp;
27 | MethodParams methodParams = DecodedMethodInvocationOp.resolveParameters(frame);
28 | MethodParam[] params = methodParams.merge();
29 | System.out.println("method '" + dmio.getName() + "' has been called with the following arguments: " + java.util.Arrays.toString(params));
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedArrayOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import java.util.Arrays;
23 |
24 | import bytecodeparser.Context;
25 | import bytecodeparser.analysis.opcodes.ArrayOpcode;
26 | import bytecodeparser.analysis.stack.Constant.IntegerConstant;
27 | import bytecodeparser.analysis.stack.Stack;
28 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
29 | import bytecodeparser.analysis.stack.StackElement;
30 | import bytecodeparser.analysis.stack.TrackableArray;
31 |
32 | /**
33 | * A decoded array operation op.
34 | * @author Stephane Godbillon
35 | *
36 | */
37 | public class DecodedArrayOp extends DecodedBasicOp {
38 | public DecodedArrayOp(ArrayOpcode op, Context context, int index) {
39 | super(op, context, index);
40 | }
41 | @Override
42 | public void simulate(Stack stack) {
43 | if(!this.op.as(ArrayOpcode.class).isLoad) {
44 | StackElementLength[] pops = Arrays.copyOf(getPops(), getPops().length - 1);
45 | StackElement subject = stack.getFromTop(StackElementLength.add(pops));
46 | if(subject instanceof TrackableArray) {
47 | TrackableArray array = (TrackableArray) subject;
48 | StackElement i = stack.getFromTop(StackElementLength.add(array.componentLength));
49 | if(i instanceof IntegerConstant) {
50 | StackElement value = stack.peek(array.componentLength);
51 | array.set(((IntegerConstant) i).getValue(), value);
52 | } else {
53 | array.isDirty = true;
54 | }
55 | }
56 | }
57 | super.simulate(stack);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/documentation/api/bytecodeparser/analysis/opcodes/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | bytecodeparser.analysis.opcodes (BytecodeParser API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | bytecodeparser.analysis.opcodes
20 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/bytecodeparser/CodeParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import javassist.CtBehavior;
23 | import javassist.bytecode.BadBytecode;
24 | import bytecodeparser.analysis.Opcodes;
25 | import bytecodeparser.analysis.opcodes.Op;
26 |
27 | /**
28 | * A basic bytecode parser.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class CodeParser {
33 | /**
34 | * The matching context.
35 | */
36 | public final Context context;
37 | private boolean stop = false;
38 |
39 | public CodeParser(CtBehavior behavior) {
40 | this.context = new Context(behavior);
41 | }
42 | /**
43 | * Parses the bytecode with the given OpHandler.
44 | * @param opHandler
45 | * @throws BadBytecode
46 | * @see {@link OpHandler}
47 | */
48 | public void parse(OpHandler opHandler) throws BadBytecode {
49 | while(context.iterator.hasNext()) {
50 | if(stop)
51 | break;
52 | int index = context.iterator.next();
53 | Op op = Opcodes.OPCODES.get(context.iterator.byteAt(index)).init(context, index);
54 | opHandler.handle(op, index);
55 | }
56 | }
57 |
58 | /**
59 | * Moves the code iterator to the given index.
60 | * @param index
61 | */
62 | public void move(int index) {
63 | stop = false;
64 | context.iterator.move(index);
65 | }
66 |
67 | /**
68 | * Looks the next frame's index.
69 | * @return
70 | */
71 | public int nextIndex() {
72 | return context.iterator.lookAhead();
73 | }
74 |
75 | /**
76 | * Resets the code iterator at the beginning of the bytecode.
77 | */
78 | public void begin() {
79 | stop = false;
80 | context.iterator.begin();
81 | }
82 |
83 | /**
84 | * Stops the parsing.
85 | */
86 | public void stop() {
87 | stop = true;
88 | }
89 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/BasicOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedBasicOp;
25 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
26 |
27 | /**
28 | * A basic op that performs classic push/pops on the stack.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class BasicOpcode extends Op {
33 | protected StackElementLength[] pops, pushes;
34 | public BasicOpcode(int code, OpParameterType... opParameterTypes) {
35 | this(code, new StackElementLength[0], new StackElementLength[0], opParameterTypes);
36 | }
37 | public BasicOpcode(int code, StackElementLength[] pops, StackElementLength[] pushes, OpParameterType... opParameterTypes) {
38 | super(code, opParameterTypes);
39 | this.pops = pops;
40 | this.pushes = pushes;
41 | }
42 | /**
43 | * @return the pops of this opcode.
44 | */
45 | public StackElementLength[] getPops() {
46 | return pops;
47 | }
48 | /**
49 | * @return the pushes of this opcode.
50 | */
51 | public StackElementLength[] getPushes() {
52 | return pushes;
53 | }
54 | @Override
55 | public DecodedBasicOp decode(Context context, int index) {
56 | return new DecodedBasicOp(this, context, index);
57 | }
58 | @Override
59 | public String toString() {
60 | return "BasicOp: " + getName();
61 | }
62 | /**
63 | * Internal use only.
64 | */
65 | public BasicOpcode setPops(StackElementLength... pops) {
66 | if(pops != null)
67 | this.pops = pops;
68 | return this;
69 | }
70 | /**
71 | * Internal use only.
72 | */
73 | public BasicOpcode setPushes(StackElementLength... pushes) {
74 | if(pushes != null)
75 | this.pushes = pushes;
76 | return this;
77 | }
78 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/utils/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.utils;
21 |
22 | import javassist.CtBehavior;
23 | import javassist.bytecode.ConstPool;
24 | import javassist.bytecode.ExceptionTable;
25 | import javassist.bytecode.LineNumberAttribute;
26 | import javassist.bytecode.LocalVariableAttribute;
27 |
28 | public class Utils {
29 | /**
30 | * Gets the LocalVariableAttribute of the behavior.
31 | * @param behavior
32 | * @throws NullPointerException if this behavior has no code attribute.
33 | * @return the LocalVariableAttribute or null if none.
34 | */
35 | public static LocalVariableAttribute getLocalVariableAttribute(CtBehavior behavior) {
36 | return (LocalVariableAttribute) behavior.getMethodInfo().getCodeAttribute().getAttribute("LocalVariableTable");
37 | }
38 |
39 | /**
40 | * Gets the LineNumberAttribute of the behavior.
41 | * @param behavior
42 | * @throws NullPointerException if this behavior has no code attribute.
43 | * @return the LineNumberAttribute or null if none.
44 | */
45 | public static LineNumberAttribute getLineNumberAttribute(CtBehavior behavior) {
46 | return (LineNumberAttribute) behavior.getMethodInfo().getCodeAttribute().getAttribute("LineNumberTable");
47 | }
48 |
49 | /**
50 | * Gets the constpool attribute of this behavior.
51 | * @param behavior
52 | * @return the constpool attribute of this behavior or null if none.
53 | */
54 | public static ConstPool getConstPool(CtBehavior behavior) {
55 | return behavior.getMethodInfo().getConstPool();
56 | }
57 |
58 | public static void debugExceptionTable(ExceptionTable et, ConstPool cp) {
59 | for(int i = 0; i < et.size(); i++) {
60 | System.out.println(et.startPc(i) + " -> " + et.endPc(i) + " : " + et.handlerPc(i) + ", type=" + (et.catchType(i) != 0 ? cp.getClassInfo(et.catchType(i)) : "any"));
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/Op.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes;
24 | import bytecodeparser.analysis.Opcodes.OpParameterType;
25 | import bytecodeparser.analysis.decoders.DecodedOp;
26 |
27 | public abstract class Op {
28 | /**
29 | * The opcode int.
30 | */
31 | public final int code;
32 | protected final OpParameterType[] parameterTypes;
33 | private String name;
34 | public Op(int code, OpParameterType... opParameterTypes) {
35 | this.code = code;
36 | this.parameterTypes = opParameterTypes;
37 | }
38 |
39 | /**
40 | * Decodes this op with a given context.
41 | * @param context
42 | * @param index
43 | * @return the matching decodedOp.
44 | */
45 | public abstract DecodedOp decode(Context context, int index);
46 |
47 | /**
48 | * Should be called before using this object.
49 | * @return this object's copy with some contextual information, if needed.
50 | */
51 | public Op init(Context context, int index) {
52 | return this;
53 | }
54 |
55 | /**
56 | * @return the opcode int.
57 | */
58 | public int getCode() {
59 | return code;
60 | }
61 |
62 | /**
63 | * @return the paramaters types of this op, if any.
64 | */
65 | public OpParameterType[] getParameterTypes() {
66 | return parameterTypes;
67 | }
68 |
69 | /**
70 | * @return the name of this opcode.
71 | */
72 | public String getName() {
73 | if(name == null)
74 | name = Opcodes.findOpName(code);
75 | return name;
76 | }
77 |
78 | /**
79 | * Shortcut for chaining and casting.
80 | * @param specificOpClass
81 | * @return the casted op.
82 | */
83 | @SuppressWarnings(value="unchecked")
84 | public T as(Class specificOpClass) {
85 | return (T) this;
86 | }
87 |
88 | @Override
89 | public String toString() {
90 | return "op: " + getName() + "";
91 | }
92 | }
--------------------------------------------------------------------------------
/documentation/api/bytecodeparser/analysis/decoders/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | bytecodeparser.analysis.decoders (BytecodeParser API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | bytecodeparser.analysis.decoders
20 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/TrackableArray.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | import java.util.Arrays;
23 |
24 | import org.apache.log4j.Logger;
25 |
26 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
27 |
28 | /**
29 | * A trackable Array is an array of known elements at compile time: its content can be "guessed" by the analyzer.
30 | * When this array gets updated with a value that is unknown at compile-time, this value is an instance of WhateverElement.
31 | *
32 | * This is particularly useful to guess the names of the varargs, for example.
33 | *
34 | * If a trackable array contains some elements that cannot be guessed
35 | *
36 | * @author Stephane Godbillon
37 | *
38 | */
39 | public class TrackableArray extends Array {
40 | private static final Logger LOGGER = Logger.getLogger(TrackableArray.class);
41 |
42 | /**
43 | * The StackElements of this array.
44 | */
45 | public final StackElement[] elements;
46 | /**
47 | * The length of each component.
48 | */
49 | public final StackElementLength componentLength;
50 | public boolean isDirty;
51 | public TrackableArray(String signature, int size) {
52 | this(signature, makeNewArray(size), parseSignature(signature));
53 | }
54 | public TrackableArray(String signature, StackElement[] elements, StackElementLength componentLength) {
55 | super(signature);
56 | this.elements = elements;
57 | this.componentLength = componentLength;
58 | }
59 | @Override
60 | public Array copy() {
61 | return this;
62 | }
63 | public TrackableArray set(int i, StackElement element) {
64 | LOGGER.trace("in trackable array, set " + i + " => " + element);
65 | elements[i] = element;
66 | return this;
67 | }
68 | @Override
69 | public String toString() {
70 | return "TrackableArray of '" + signature + "'";
71 | }
72 | private static StackElement[] makeNewArray(int size) {
73 | StackElement[] result = new StackElement[size];
74 | Arrays.fill(result, new VoidElement());
75 | return result;
76 | }
77 |
78 | private static StackElementLength parseSignature(String signature) {
79 | return StackElementLength.ONE;
80 | }
81 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/WideOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.decoders.DecodedLocalVariableOp;
24 | import bytecodeparser.analysis.decoders.DecodedWideOp;
25 | import javassist.bytecode.Opcode;
26 |
27 | /**
28 | * Wide opcode for localvariables (if there is more than 256 local vars in the method's body).
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class WideOpcode extends Op {
33 | private final DecodedWideOp decodedWideOp;
34 |
35 | public WideOpcode() {
36 | this(null);
37 | }
38 |
39 | private WideOpcode(DecodedWideOp decodedWideOp) {
40 | super(Opcode.WIDE);
41 | this.decodedWideOp = decodedWideOp;
42 | }
43 |
44 | @Override
45 | public Op init(Context context, int index) {
46 | return new WideOpcode(new DecodedWideOp(this, context, index));
47 | }
48 |
49 | @Override
50 | public DecodedWideOp decode(Context context, int index) {
51 | if(decodedWideOp != null)
52 | return decodedWideOp;
53 | throw new RuntimeException("must be initialized before !");
54 | }
55 |
56 | /**
57 | * Gets the wrapped localVariable opcode.
58 | * This op MUST be decoded before invoking this method.
59 | * @return the wrapped localVariable op.
60 | * @throws RuntimeException if this op has not been initialized with init(context, index) before.
61 | */
62 | public LocalVariableOpcode getWrappedLocalVariableOpcode() {
63 | if(decodedWideOp != null)
64 | return decodedWideOp.op.as(LocalVariableOpcode.class);
65 | throw new RuntimeException("must be initialized before !");
66 | }
67 |
68 | /**
69 | * Gets the wrapped decoded localVariable opcode.
70 | * This op MUST be decoded before invoking this method.
71 | * @return the wrapped decoded localVariable op.
72 | * @throws RuntimeException if this op has not been initialized with init(context, index) before.
73 | */
74 | public DecodedLocalVariableOp getWrappedDecodedLocalVariableOp() {
75 | if(decodedWideOp != null)
76 | return decodedWideOp.wrappedDecodedLocalVariableOp;
77 | throw new RuntimeException("must be initialized before !");
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/test/subjects/Subject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package test.subjects;
21 |
22 | public class Subject {
23 | public String subj = "subj";
24 | public void say(String smth) {
25 | int i;
26 | i = 15;
27 | int j = 0;
28 | int k = j + i;
29 | try {
30 | System.out.println(k);
31 | } catch(Exception e) {
32 | System.out.println("b");
33 | } finally {
34 | System.out.println("finally");
35 | }
36 | /*if(j == 0)
37 | throw new RuntimeException("yop");*/
38 | smth.length();
39 | for(long l = 0; l < 6; l++) {
40 | String t = "truc" + l;
41 | System.out.println(t);
42 | };i++;
43 | java.util.Date dd = new java.util.Date();
44 | Subject subject = new Subject();
45 | subject.subj = "koko";
46 | try {
47 | dd.toString();
48 | i++;
49 | } catch(RuntimeException e) {
50 | System.out.println(e);
51 | }
52 |
53 | String name = "truc";
54 | String name2 = "truc2";
55 | String[] names = new String[] { "y1", "y2" };
56 | long toto = 398738947098720L;
57 | Object object__ = new Object();
58 | machin("kbce", name2, names, x6(toto), object__);
59 | process(toto, "a", "b");
60 | processStatic("c", "d");
61 | String ff = "ff";
62 | process(toto, ff);
63 | }
64 |
65 | static int hehe = 0;
66 | public static String hello() {
67 | try {
68 | try {
69 | String bidule = "bidule";
70 | System.out.println(bidule);
71 | return bidule;
72 | } catch (RuntimeException e) {
73 | throw new RuntimeException(e);
74 | } catch (Exception e) {
75 | throw new RuntimeException(e);
76 | } finally {
77 | "trc".length();
78 | }
79 | } catch(Exception e) {
80 | throw new RuntimeException(e);
81 | }
82 | }
83 |
84 | public void machin(String coucou, String bidule, String[] chponk, long toto, Object o) {
85 |
86 | }
87 |
88 | public void process(long t, String...strings) {
89 | // blob
90 | }
91 |
92 | public static void processStatic(String...strings) {
93 |
94 | }
95 |
96 | public void truc() {
97 | int i = 0;
98 | i = i + 1;
99 | }
100 |
101 | public long x6(long i) {
102 | return i * 6;
103 | }
104 | /*
105 | read :: 9 -> smth
106 | read :: 11 -> s
107 | write :: 6 -> i
108 | write :: 7 -> j
109 | write :: 8 -> k
110 | write :: 10 -> s
111 | */
112 | }
113 |
--------------------------------------------------------------------------------
/src/bytecodeparser/Context.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import java.util.Map;
23 |
24 | import javassist.CtBehavior;
25 | import javassist.NotFoundException;
26 | import javassist.bytecode.ExceptionTable;
27 | import bytecodeparser.analysis.LocalVariable;
28 |
29 | /**
30 | * A context for parsing bytecode.
31 | * @author Stephane Godbillon
32 | *
33 | */
34 | public class Context {
35 | /**
36 | * The behavior which bytecode is being parsed.
37 | */
38 | public final CtBehavior behavior;
39 | /**
40 | * The bytecode iterator used for parsing.
41 | */
42 | public final MultiMarkerCodeIterator iterator;
43 | /**
44 | * The local variables of the behavior.
45 | */
46 | public final Map localVariables;
47 | /**
48 | * The exception handlers, from the ExceptionTable attribute.
49 | */
50 | public final int[] exceptionHandlers;
51 |
52 | public Context(CtBehavior behavior, MultiMarkerCodeIterator iterator, Map localVariables) {
53 | this.behavior = behavior;
54 | this.iterator = iterator;
55 | this.localVariables = localVariables;
56 | ExceptionTable exceptionTable = this.behavior.getMethodInfo().getCodeAttribute().getExceptionTable();
57 |
58 | if(exceptionTable != null) {
59 | this.exceptionHandlers = new int[exceptionTable.size()];
60 | for(int i = 0; i < exceptionTable.size(); i++) {
61 | exceptionHandlers[i] = exceptionTable.handlerPc(i);
62 | }
63 | } else {
64 | this.exceptionHandlers = new int[0];
65 | }
66 | }
67 |
68 | public Context(CtBehavior behavior, MultiMarkerCodeIterator iterator) {
69 | this(behavior, iterator, findLocalVariables(behavior));
70 | }
71 |
72 | public Context(CtBehavior behavior) {
73 | this(behavior, new MultiMarkerCodeIterator(behavior.getMethodInfo().getCodeAttribute()), findLocalVariables(behavior));
74 | }
75 |
76 | /**
77 | * States if the given index is a start of an exception handler.
78 | * @param index
79 | */
80 | public boolean isStartOfExceptionHandler(int index) {
81 | for(int i = 0; i < exceptionHandlers.length; i++)
82 | if(exceptionHandlers[i] == index)
83 | return true;
84 | return false;
85 | }
86 |
87 | private static Map findLocalVariables(CtBehavior behavior) {
88 | try {
89 | return LocalVariable.findVariables(behavior);
90 | } catch (NotFoundException e) {
91 | throw new RuntimeException("Error while retrieving the behavior's local variables!", e);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedArrayCreationOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import javassist.bytecode.Opcode;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.opcodes.ArrayCreationOpcode;
25 | import bytecodeparser.analysis.stack.Array;
26 | import bytecodeparser.analysis.stack.Constant.IntegerConstant;
27 | import bytecodeparser.analysis.stack.Stack;
28 | import bytecodeparser.analysis.stack.StackElement;
29 | import bytecodeparser.analysis.stack.TrackableArray;
30 | import bytecodeparser.utils.Utils;
31 |
32 | /**
33 | * A decoded array creation op.
34 | * @author Stephane Godbillon
35 | *
36 | */
37 | public class DecodedArrayCreationOp extends DecodedBasicOp {
38 | /**
39 | * The number of dimensions of the created array.
40 | */
41 | public final int dimensions;
42 | /**
43 | * The signature of the created array.
44 | */
45 | public final String signature;
46 |
47 | public DecodedArrayCreationOp(ArrayCreationOpcode op, Context context, int index) {
48 | super(op, context, index);
49 | if(op.getCode() == Opcode.MULTIANEWARRAY)
50 | dimensions = parameterValues[1];
51 | else dimensions = 1;
52 | if(op.getCode() == Opcode.NEWARRAY)
53 | signature = getSignatureForSingleDimensionArrayOfPrimitive(parameterValues[0]);
54 | else signature = Utils.getConstPool(context.behavior).getClassInfo(parameterValues[0]);
55 | }
56 |
57 | @Override
58 | public void simulate(Stack stack) {
59 | int size = -1;
60 | if(dimensions == 1) {
61 | StackElement se = stack.pop();
62 | if(se instanceof IntegerConstant) {
63 | IntegerConstant ic = (IntegerConstant) se;
64 | size = ic.getValue();
65 | }
66 | } else {
67 | for(int i = 0; i < dimensions; i++)
68 | stack.pop();
69 | }
70 | if(size > -1)
71 | stack.push(new TrackableArray(signature, size));
72 | else stack.push(new Array(signature));
73 | }
74 |
75 | private static String getSignatureForSingleDimensionArrayOfPrimitive(int type) {
76 | switch(type) {
77 | case 4: return "[Z";
78 | case 5: return "[C";
79 | case 6: return "[F";
80 | case 7: return "[D";
81 | case 8: return "[B";
82 | case 9: return "[S";
83 | case 10: return "[I";
84 | case 11: return "[J";
85 | default: throw new RuntimeException("unexpected primitive array type! '" + type + "'");
86 | }
87 | }
88 |
89 | @Override
90 | public String toString() {
91 | return "DecodedArrayCreationOp dimensions=" + dimensions + " signature=" + signature;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import javassist.bytecode.CodeIterator;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.Opcodes.OpParameterType;
25 | import bytecodeparser.analysis.opcodes.Op;
26 | import bytecodeparser.analysis.stack.Stack;
27 |
28 | /**
29 | * A decoded Op.
30 | * @author Stephane Godbillon
31 | *
32 | */
33 | public abstract class DecodedOp {
34 | /**
35 | * The context in which this op has been decoded.
36 | */
37 | public final Context context;
38 | /**
39 | * The index at which this op has been decoded.
40 | */
41 | public final int index;
42 | /**
43 | * The op that has been decoded.
44 | */
45 | public final Op op;
46 |
47 | public final OpParameterType[] parameterTypes;
48 | public final int[] parameterValues;
49 |
50 | public DecodedOp(Op op, Context context, int index) {
51 | this(op, context, index, op.getParameterTypes());
52 | }
53 |
54 | public DecodedOp(Op op, Context context, int index, OpParameterType[] parameterTypes) {
55 | this(op, context, index, parameterTypes, decodeValues(parameterTypes, context.iterator, index));
56 | }
57 |
58 | public DecodedOp(Op op, Context context, int index, OpParameterType[] parameterTypes, int[] parameterValues) {
59 | this.context = context;
60 | this.index = index;
61 | this.op = op;
62 | this.parameterTypes = parameterTypes;
63 | this.parameterValues = parameterValues;
64 | }
65 |
66 | public static int[] decodeValues(OpParameterType[] parameterTypes, CodeIterator iterator, int index) {
67 | int[] result = new int[parameterTypes.length];
68 | int nextValIndex = index + 1;
69 | for(int i = 0; i < parameterTypes.length; i++) {
70 | OpParameterType type = parameterTypes[i];
71 | result[i] = decodeValueAt(type, iterator, nextValIndex);
72 | nextValIndex += type.size;
73 | }
74 | return result;
75 | }
76 |
77 | public static int decodeValueAt(OpParameterType type, CodeIterator iterator, int index) {
78 | switch(type) {
79 | case S1:
80 | return iterator.byteAt(index);
81 | case S2:
82 | return iterator.s16bitAt(index);
83 | case S4:
84 | return iterator.s32bitAt(index);
85 | case U1:
86 | return iterator.byteAt(index);
87 | case U2:
88 | return iterator.u16bitAt(index);
89 | case U4:
90 | default:
91 | throw new RuntimeException("unsupported");
92 |
93 | }
94 | }
95 |
96 | /**
97 | * Simulate this op onto the given stack.
98 | * @param stack
99 | */
100 | public abstract void simulate(Stack stack);
101 | }
102 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedFieldOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import static bytecodeparser.analysis.stack.Stack.StackElementLength.DOUBLE;
23 | import static bytecodeparser.analysis.stack.Stack.StackElementLength.ONE;
24 | import javassist.bytecode.Descriptor;
25 | import javassist.bytecode.Opcode;
26 | import bytecodeparser.Context;
27 | import bytecodeparser.analysis.opcodes.FieldOpcode;
28 | import bytecodeparser.analysis.stack.Stack;
29 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
30 |
31 | /**
32 | * A decoded field operation op.
33 | * @author Stephane Godbillon
34 | *
35 | */
36 | public class DecodedFieldOp extends DecodedOp {
37 | protected String descriptor;
38 | protected boolean load;
39 | protected boolean isStatic;
40 | protected StackElementLength stackElementLength;
41 |
42 | public DecodedFieldOp(FieldOpcode fo, Context context, int index) {
43 | super(fo, context, index);
44 | String descriptor = context.behavior.getMethodInfo().getConstPool().getFieldrefType(getMethodRefIndex());
45 | StackElementLength sel = ONE;
46 | if(Descriptor.dataSize(descriptor) == 2)
47 | sel = DOUBLE;
48 | this.stackElementLength = sel;
49 | this.descriptor = descriptor;
50 | this.load = fo.getCode() == Opcode.GETFIELD || fo.getCode() == Opcode.GETSTATIC;
51 | this.isStatic = fo.getCode() == Opcode.GETSTATIC ||fo.getCode() == Opcode.PUTSTATIC;
52 | }
53 |
54 | @Override
55 | public void simulate(Stack stack) {
56 | Stack.processBasicAlteration(stack, getPops(), getPushes());
57 | }
58 |
59 | /**
60 | * @return the methodRef index of this op.
61 | */
62 | public int getMethodRefIndex() {
63 | return parameterValues[0];
64 | }
65 |
66 | /**
67 | * @return the descriptor of the field.
68 | */
69 | public String getDescriptor() {
70 | return descriptor;
71 | }
72 |
73 | /**
74 | * Pops needed by this decoded op.
75 | */
76 | public StackElementLength[] getPops() {
77 | if(isStatic && !load)
78 | return new StackElementLength[] { stackElementLength };
79 | else if(isStatic && load)
80 | return new StackElementLength[0];
81 | else if(!isStatic && !load)
82 | return new StackElementLength[] { stackElementLength, ONE };
83 | else return new StackElementLength[] { ONE };
84 | }
85 |
86 | /**
87 | * Pushes needed by this decoded op.
88 | */
89 | public StackElementLength[] getPushes() {
90 | if(load)
91 | return new StackElementLength[] { stackElementLength };
92 | return new StackElementLength[0];
93 | }
94 |
95 | /**
96 | * States if this op is a read or write operation.
97 | */
98 | public boolean isRead() {
99 | return load;
100 | }
101 | }
--------------------------------------------------------------------------------
/documentation/api/bytecodeparser/analysis/stack/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | bytecodeparser.analysis.stack (BytecodeParser API)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | bytecodeparser.analysis.stack
20 |