summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/analysis
diff options
context:
space:
mode:
authorGravatar jeff2014-08-13 00:22:12 -0400
committerGravatar jeff2014-08-13 00:22:12 -0400
commitcc74d0e62cfdcf14c5918234f69d587d264807ed (patch)
tree7a11bd6af9b7cd2f28c3dbd43a281b4036464f77 /src/cuchaz/enigma/analysis
parentgot simple method call graph working! (diff)
downloadenigma-fork-cc74d0e62cfdcf14c5918234f69d587d264807ed.tar.gz
enigma-fork-cc74d0e62cfdcf14c5918234f69d587d264807ed.tar.xz
enigma-fork-cc74d0e62cfdcf14c5918234f69d587d264807ed.zip
added support for field access searches
added proper detection/handling for constructors
Diffstat (limited to 'src/cuchaz/enigma/analysis')
-rw-r--r--src/cuchaz/enigma/analysis/FieldCallsTreeNode.java82
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java107
-rw-r--r--src/cuchaz/enigma/analysis/MethodCallsTreeNode.java114
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexVisitor.java5
4 files changed, 254 insertions, 54 deletions
diff --git a/src/cuchaz/enigma/analysis/FieldCallsTreeNode.java b/src/cuchaz/enigma/analysis/FieldCallsTreeNode.java
new file mode 100644
index 0000000..0427b3b
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/FieldCallsTreeNode.java
@@ -0,0 +1,82 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.analysis;
12
13import javax.swing.tree.DefaultMutableTreeNode;
14
15import cuchaz.enigma.mapping.ConstructorEntry;
16import cuchaz.enigma.mapping.Entry;
17import cuchaz.enigma.mapping.FieldEntry;
18import cuchaz.enigma.mapping.MethodEntry;
19import cuchaz.enigma.mapping.Translator;
20
21public class FieldCallsTreeNode extends DefaultMutableTreeNode
22{
23 private static final long serialVersionUID = -7934108091928699835L;
24
25 private Translator m_deobfuscatingTranslator;
26 private FieldEntry m_entry;
27
28 public FieldCallsTreeNode( Translator deobfuscatingTranslator, FieldEntry fieldEntry )
29 {
30 m_deobfuscatingTranslator = deobfuscatingTranslator;
31 m_entry = fieldEntry;
32 }
33
34 public FieldEntry getFieldEntry( )
35 {
36 return m_entry;
37 }
38
39 @Override
40 public String toString( )
41 {
42 String className = m_deobfuscatingTranslator.translateClass( m_entry.getClassName() );
43 if( className == null )
44 {
45 className = m_entry.getClassName();
46 }
47
48 String targetName = m_deobfuscatingTranslator.translate( m_entry );
49 if( targetName == null )
50 {
51 targetName = m_entry.getName();
52 }
53 return className + "." + targetName;
54 }
55
56 public void load( JarIndex index, boolean recurse )
57 {
58 // get all the child nodes
59 for( Entry entry : index.getFieldCallers( m_entry ) )
60 {
61 if( entry instanceof MethodEntry )
62 {
63 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (MethodEntry)entry ) );
64 }
65 else if( entry instanceof ConstructorEntry )
66 {
67 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (ConstructorEntry)entry ) );
68 }
69 }
70
71 if( recurse && children != null )
72 {
73 for( Object node : children )
74 {
75 if( node instanceof MethodCallsTreeNode )
76 {
77 ((MethodCallsTreeNode)node).load( index, true );
78 }
79 }
80 }
81 }
82}
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index 06b0173..96bddc1 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -27,17 +27,26 @@ import javassist.CannotCompileException;
27import javassist.ClassPool; 27import javassist.ClassPool;
28import javassist.CtBehavior; 28import javassist.CtBehavior;
29import javassist.CtClass; 29import javassist.CtClass;
30import javassist.CtConstructor;
31import javassist.CtMethod;
30import javassist.NotFoundException; 32import javassist.NotFoundException;
31import javassist.bytecode.Descriptor; 33import javassist.bytecode.Descriptor;
34import javassist.expr.ConstructorCall;
32import javassist.expr.ExprEditor; 35import javassist.expr.ExprEditor;
36import javassist.expr.FieldAccess;
33import javassist.expr.MethodCall; 37import javassist.expr.MethodCall;
38import javassist.expr.NewExpr;
34 39
35import com.google.common.collect.HashMultimap; 40import com.google.common.collect.HashMultimap;
41import com.google.common.collect.Lists;
36import com.google.common.collect.Multimap; 42import com.google.common.collect.Multimap;
37import com.google.common.collect.Sets; 43import com.google.common.collect.Sets;
38 44
39import cuchaz.enigma.Constants; 45import cuchaz.enigma.Constants;
40import cuchaz.enigma.mapping.ClassEntry; 46import cuchaz.enigma.mapping.ClassEntry;
47import cuchaz.enigma.mapping.ConstructorEntry;
48import cuchaz.enigma.mapping.Entry;
49import cuchaz.enigma.mapping.FieldEntry;
41import cuchaz.enigma.mapping.MethodEntry; 50import cuchaz.enigma.mapping.MethodEntry;
42import cuchaz.enigma.mapping.Translator; 51import cuchaz.enigma.mapping.Translator;
43 52
@@ -46,7 +55,8 @@ public class JarIndex
46 private Set<String> m_obfClassNames; 55 private Set<String> m_obfClassNames;
47 private Ancestries m_ancestries; 56 private Ancestries m_ancestries;
48 private Multimap<String,MethodEntry> m_methodImplementations; 57 private Multimap<String,MethodEntry> m_methodImplementations;
49 private Multimap<MethodEntry,MethodEntry> m_methodCalls; 58 private Multimap<Entry,Entry> m_methodCalls;
59 private Multimap<FieldEntry,Entry> m_fieldCalls;
50 60
51 public JarIndex( JarFile jar ) 61 public JarIndex( JarFile jar )
52 { 62 {
@@ -54,6 +64,7 @@ public class JarIndex
54 m_ancestries = new Ancestries(); 64 m_ancestries = new Ancestries();
55 m_methodImplementations = HashMultimap.create(); 65 m_methodImplementations = HashMultimap.create();
56 m_methodCalls = HashMultimap.create(); 66 m_methodCalls = HashMultimap.create();
67 m_fieldCalls = HashMultimap.create();
57 68
58 // read the class names 69 // read the class names
59 Enumeration<JarEntry> enumeration = jar.entries(); 70 Enumeration<JarEntry> enumeration = jar.entries();
@@ -133,14 +144,30 @@ public class JarIndex
133 { 144 {
134 // get the method entry 145 // get the method entry
135 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() ); 146 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() );
136 final MethodEntry methodEntry = new MethodEntry( 147 final Entry thisEntry;
137 new ClassEntry( className ), 148 if( behavior instanceof CtMethod )
138 behavior.getName(), 149 {
139 behavior.getSignature() 150 MethodEntry methodEntry = new MethodEntry(
140 ); 151 new ClassEntry( className ),
141 152 behavior.getName(),
142 // index implementation 153 behavior.getSignature()
143 m_methodImplementations.put( className, methodEntry ); 154 );
155 thisEntry = methodEntry;
156
157 // index implementation
158 m_methodImplementations.put( className, methodEntry );
159 }
160 else if( behavior instanceof CtConstructor )
161 {
162 thisEntry = new ConstructorEntry(
163 new ClassEntry( className ),
164 behavior.getSignature()
165 );
166 }
167 else
168 {
169 throw new IllegalArgumentException( "behavior must be a method or a constructor!" );
170 }
144 171
145 // index method calls 172 // index method calls
146 try 173 try
@@ -150,20 +177,53 @@ public class JarIndex
150 @Override 177 @Override
151 public void edit( MethodCall call ) 178 public void edit( MethodCall call )
152 { 179 {
153 // is this a jar class?
154 String className = Descriptor.toJvmName( call.getClassName() ); 180 String className = Descriptor.toJvmName( call.getClassName() );
155 if( !m_obfClassNames.contains( className ) )
156 {
157 return;
158 }
159
160 // make entry for the called method
161 MethodEntry calledMethodEntry = new MethodEntry( 181 MethodEntry calledMethodEntry = new MethodEntry(
162 new ClassEntry( className ), 182 new ClassEntry( className ),
163 call.getMethodName(), 183 call.getMethodName(),
164 call.getSignature() 184 call.getSignature()
165 ); 185 );
166 m_methodCalls.put( calledMethodEntry, methodEntry ); 186 m_methodCalls.put( calledMethodEntry, thisEntry );
187 }
188
189 @Override
190 public void edit( FieldAccess call )
191 {
192 String className = Descriptor.toJvmName( call.getClassName() );
193 FieldEntry calledFieldEntry = new FieldEntry(
194 new ClassEntry( className ),
195 call.getFieldName()
196 );
197 m_fieldCalls.put( calledFieldEntry, thisEntry );
198 }
199
200 @Override
201 public void edit( ConstructorCall call )
202 {
203 String className = Descriptor.toJvmName( call.getClassName() );
204 ConstructorEntry calledConstructorEntry = new ConstructorEntry(
205 new ClassEntry( className ),
206 call.getSignature()
207 );
208 m_methodCalls.put( calledConstructorEntry, thisEntry );
209 }
210
211 @Override
212 public void edit( NewExpr call )
213 {
214 String className = Descriptor.toJvmName( call.getClassName() );
215 ConstructorEntry calledConstructorEntry = new ConstructorEntry(
216 new ClassEntry( className ),
217 call.getSignature()
218 );
219
220 // TEMP
221 if( className.equals( "bgw" ) )
222 {
223 System.out.println( calledConstructorEntry + " called by " + thisEntry );
224 }
225
226 m_methodCalls.put( calledConstructorEntry, thisEntry );
167 } 227 }
168 } ); 228 } );
169 } 229 }
@@ -202,7 +262,9 @@ public class JarIndex
202 public ClassInheritanceTreeNode getClassInheritance( Translator deobfuscatingTranslator, ClassEntry obfClassEntry ) 262 public ClassInheritanceTreeNode getClassInheritance( Translator deobfuscatingTranslator, ClassEntry obfClassEntry )
203 { 263 {
204 // get the root node 264 // get the root node
205 List<String> ancestry = m_ancestries.getAncestry( obfClassEntry.getName() ); 265 List<String> ancestry = Lists.newArrayList();
266 ancestry.add( obfClassEntry.getName() );
267 ancestry.addAll( m_ancestries.getAncestry( obfClassEntry.getName() ) );
206 ClassInheritanceTreeNode rootNode = new ClassInheritanceTreeNode( deobfuscatingTranslator, ancestry.get( ancestry.size() - 1 ) ); 268 ClassInheritanceTreeNode rootNode = new ClassInheritanceTreeNode( deobfuscatingTranslator, ancestry.get( ancestry.size() - 1 ) );
207 269
208 // expand all children recursively 270 // expand all children recursively
@@ -241,9 +303,14 @@ public class JarIndex
241 return rootNode; 303 return rootNode;
242 } 304 }
243 305
244 public Collection<MethodEntry> getMethodCallers( MethodEntry methodEntry ) 306 public Collection<Entry> getFieldCallers( FieldEntry fieldEntry )
307 {
308 return m_fieldCalls.get( fieldEntry );
309 }
310
311 public Collection<Entry> getMethodCallers( Entry entry )
245 { 312 {
246 return m_methodCalls.get( methodEntry ); 313 return m_methodCalls.get( entry );
247 } 314 }
248 315
249 private String getMethodKey( String name, String signature ) 316 private String getMethodKey( String name, String signature )
diff --git a/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java b/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java
index dedfb2e..b5cf4c3 100644
--- a/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java
+++ b/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java
@@ -10,12 +10,15 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import java.util.List; 13import java.util.Set;
14 14
15import javax.swing.tree.DefaultMutableTreeNode; 15import javax.swing.tree.DefaultMutableTreeNode;
16import javax.swing.tree.TreeNode;
16 17
17import com.google.common.collect.Lists; 18import com.google.common.collect.Sets;
18 19
20import cuchaz.enigma.mapping.ConstructorEntry;
21import cuchaz.enigma.mapping.Entry;
19import cuchaz.enigma.mapping.MethodEntry; 22import cuchaz.enigma.mapping.MethodEntry;
20import cuchaz.enigma.mapping.Translator; 23import cuchaz.enigma.mapping.Translator;
21 24
@@ -24,72 +27,117 @@ public class MethodCallsTreeNode extends DefaultMutableTreeNode
24 private static final long serialVersionUID = -3658163700783307520L; 27 private static final long serialVersionUID = -3658163700783307520L;
25 28
26 private Translator m_deobfuscatingTranslator; 29 private Translator m_deobfuscatingTranslator;
27 private MethodEntry m_entry; 30 private MethodEntry m_methodEntry;
31 private ConstructorEntry m_constructorEntry;
28 32
29 public MethodCallsTreeNode( Translator deobfuscatingTranslator, MethodEntry entry ) 33 public MethodCallsTreeNode( Translator deobfuscatingTranslator, MethodEntry entry )
30 { 34 {
31 m_deobfuscatingTranslator = deobfuscatingTranslator; 35 m_deobfuscatingTranslator = deobfuscatingTranslator;
32 m_entry = entry; 36 m_methodEntry = entry;
37 m_constructorEntry = null;
38 }
39
40 public MethodCallsTreeNode( Translator deobfuscatingTranslator, ConstructorEntry entry )
41 {
42 m_deobfuscatingTranslator = deobfuscatingTranslator;
43 m_methodEntry = null;
44 m_constructorEntry = entry;
33 } 45 }
34 46
35 public MethodEntry getMethodEntry( ) 47 public MethodEntry getMethodEntry( )
36 { 48 {
37 return m_entry; 49 return m_methodEntry;
38 } 50 }
39 51
40 public String getDeobfClassName( ) 52 public ConstructorEntry getConstructorEntry( )
41 { 53 {
42 return m_deobfuscatingTranslator.translateClass( m_entry.getClassName() ); 54 return m_constructorEntry;
43 } 55 }
44 56
45 public String getDeobfMethodName( ) 57 public Entry getEntry( )
46 { 58 {
47 return m_deobfuscatingTranslator.translate( m_entry ); 59 if( m_methodEntry != null )
60 {
61 return m_methodEntry;
62 }
63 else if( m_constructorEntry != null )
64 {
65 return m_constructorEntry;
66 }
67 throw new Error( "Illegal state!" );
48 } 68 }
49 69
50 @Override 70 @Override
51 public String toString( ) 71 public String toString( )
52 { 72 {
53 String className = getDeobfClassName(); 73 if( m_methodEntry != null )
54 if( className == null )
55 { 74 {
56 className = m_entry.getClassName(); 75 String className = m_deobfuscatingTranslator.translateClass( m_methodEntry.getClassName() );
76 if( className == null )
77 {
78 className = m_methodEntry.getClassName();
79 }
80
81 String methodName = m_deobfuscatingTranslator.translate( m_methodEntry );
82 if( methodName == null )
83 {
84 methodName = m_methodEntry.getName();
85 }
86 return className + "." + methodName + "()";
57 } 87 }
58 88 else if( m_constructorEntry != null )
59 String methodName = getDeobfMethodName();
60 if( methodName == null )
61 { 89 {
62 methodName = m_entry.getName(); 90 String className = m_deobfuscatingTranslator.translateClass( m_constructorEntry.getClassName() );
91 if( className == null )
92 {
93 className = m_constructorEntry.getClassName();
94 }
95 return className + "()";
63 } 96 }
64 return className + "." + methodName + "()"; 97 throw new Error( "Illegal state!" );
65 } 98 }
66 99
67 public void load( JarIndex index, boolean recurse ) 100 public void load( JarIndex index, boolean recurse )
68 { 101 {
69 // get all the child nodes 102 // get all the child nodes
70 List<MethodCallsTreeNode> nodes = Lists.newArrayList(); 103 for( Entry entry : index.getMethodCallers( getEntry() ) )
71 for( MethodEntry entry : index.getMethodCallers( m_entry ) )
72 { 104 {
73 nodes.add( new MethodCallsTreeNode( m_deobfuscatingTranslator, entry ) ); 105 if( entry instanceof MethodEntry )
74 } 106 {
75 107 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (MethodEntry)entry ) );
76 // add them to this node 108 }
77 for( MethodCallsTreeNode node : nodes ) 109 else if( entry instanceof ConstructorEntry )
78 { 110 {
79 this.add( node ); 111 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (ConstructorEntry)entry ) );
112 }
80 } 113 }
81 114
82 if( recurse ) 115 if( recurse && children != null )
83 { 116 {
84 for( MethodCallsTreeNode node : nodes ) 117 for( Object child : children )
85 { 118 {
86 // don't recurse into self 119 if( child instanceof MethodCallsTreeNode )
87 if( node.getMethodEntry().equals( m_entry ) )
88 { 120 {
89 continue; 121 MethodCallsTreeNode node = (MethodCallsTreeNode)child;
122
123 // don't recurse into ancestor
124 Set<Entry> ancestors = Sets.newHashSet();
125 TreeNode n = (TreeNode)node;
126 while( n.getParent() != null )
127 {
128 n = n.getParent();
129 if( n instanceof MethodCallsTreeNode )
130 {
131 ancestors.add( ((MethodCallsTreeNode)n).getEntry() );
132 }
133 }
134 if( ancestors.contains( node.getEntry() ) )
135 {
136 continue;
137 }
138
139 node.load( index, true );
90 } 140 }
91
92 node.load( index, true );
93 } 141 }
94 } 142 }
95 } 143 }
diff --git a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
index 0ba5996..6c14ee9 100644
--- a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
+++ b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
@@ -93,6 +93,7 @@ import com.strobel.decompiler.patterns.Pattern;
93 93
94import cuchaz.enigma.mapping.ArgumentEntry; 94import cuchaz.enigma.mapping.ArgumentEntry;
95import cuchaz.enigma.mapping.ClassEntry; 95import cuchaz.enigma.mapping.ClassEntry;
96import cuchaz.enigma.mapping.ConstructorEntry;
96import cuchaz.enigma.mapping.FieldEntry; 97import cuchaz.enigma.mapping.FieldEntry;
97import cuchaz.enigma.mapping.MethodEntry; 98import cuchaz.enigma.mapping.MethodEntry;
98 99
@@ -158,7 +159,9 @@ public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void>
158 public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index ) 159 public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index )
159 { 160 {
160 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); 161 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION );
161 index.add( node.getNameToken(), new ClassEntry( def.getDeclaringType().getInternalName() ) ); 162 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
163 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, def.getSignature() );
164 index.addDeclaration( node.getNameToken(), constructorEntry );
162 165
163 return recurse( node, index ); 166 return recurse( node, index );
164 } 167 }