diff options
Diffstat (limited to 'src/cuchaz/enigma/analysis/JarIndex.java')
| -rw-r--r-- | src/cuchaz/enigma/analysis/JarIndex.java | 107 |
1 files changed, 87 insertions, 20 deletions
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; | |||
| 27 | import javassist.ClassPool; | 27 | import javassist.ClassPool; |
| 28 | import javassist.CtBehavior; | 28 | import javassist.CtBehavior; |
| 29 | import javassist.CtClass; | 29 | import javassist.CtClass; |
| 30 | import javassist.CtConstructor; | ||
| 31 | import javassist.CtMethod; | ||
| 30 | import javassist.NotFoundException; | 32 | import javassist.NotFoundException; |
| 31 | import javassist.bytecode.Descriptor; | 33 | import javassist.bytecode.Descriptor; |
| 34 | import javassist.expr.ConstructorCall; | ||
| 32 | import javassist.expr.ExprEditor; | 35 | import javassist.expr.ExprEditor; |
| 36 | import javassist.expr.FieldAccess; | ||
| 33 | import javassist.expr.MethodCall; | 37 | import javassist.expr.MethodCall; |
| 38 | import javassist.expr.NewExpr; | ||
| 34 | 39 | ||
| 35 | import com.google.common.collect.HashMultimap; | 40 | import com.google.common.collect.HashMultimap; |
| 41 | import com.google.common.collect.Lists; | ||
| 36 | import com.google.common.collect.Multimap; | 42 | import com.google.common.collect.Multimap; |
| 37 | import com.google.common.collect.Sets; | 43 | import com.google.common.collect.Sets; |
| 38 | 44 | ||
| 39 | import cuchaz.enigma.Constants; | 45 | import cuchaz.enigma.Constants; |
| 40 | import cuchaz.enigma.mapping.ClassEntry; | 46 | import cuchaz.enigma.mapping.ClassEntry; |
| 47 | import cuchaz.enigma.mapping.ConstructorEntry; | ||
| 48 | import cuchaz.enigma.mapping.Entry; | ||
| 49 | import cuchaz.enigma.mapping.FieldEntry; | ||
| 41 | import cuchaz.enigma.mapping.MethodEntry; | 50 | import cuchaz.enigma.mapping.MethodEntry; |
| 42 | import cuchaz.enigma.mapping.Translator; | 51 | import 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 ) |