diff options
Diffstat (limited to 'src/cuchaz/enigma/analysis/JarIndex.java')
| -rw-r--r-- | src/cuchaz/enigma/analysis/JarIndex.java | 102 |
1 files changed, 73 insertions, 29 deletions
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java index b51428a..9f309ce 100644 --- a/src/cuchaz/enigma/analysis/JarIndex.java +++ b/src/cuchaz/enigma/analysis/JarIndex.java | |||
| @@ -42,6 +42,7 @@ import com.google.common.collect.Sets; | |||
| 42 | 42 | ||
| 43 | import cuchaz.enigma.Constants; | 43 | import cuchaz.enigma.Constants; |
| 44 | import cuchaz.enigma.bytecode.ClassRenamer; | 44 | import cuchaz.enigma.bytecode.ClassRenamer; |
| 45 | import cuchaz.enigma.mapping.ArgumentEntry; | ||
| 45 | import cuchaz.enigma.mapping.BehaviorEntry; | 46 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 46 | import cuchaz.enigma.mapping.ClassEntry; | 47 | import cuchaz.enigma.mapping.ClassEntry; |
| 47 | import cuchaz.enigma.mapping.ConstructorEntry; | 48 | import cuchaz.enigma.mapping.ConstructorEntry; |
| @@ -264,7 +265,15 @@ public class JarIndex | |||
| 264 | call.getMethodName(), | 265 | call.getMethodName(), |
| 265 | call.getSignature() | 266 | call.getSignature() |
| 266 | ); | 267 | ); |
| 267 | calledMethodEntry = resolveMethodClass( calledMethodEntry ); | 268 | ClassEntry resolvedClassEntry = resolveEntryClass( calledMethodEntry ); |
| 269 | if( resolvedClassEntry != null && !resolvedClassEntry.equals( calledMethodEntry.getClassEntry() ) ) | ||
| 270 | { | ||
| 271 | calledMethodEntry = new MethodEntry( | ||
| 272 | resolvedClassEntry, | ||
| 273 | call.getMethodName(), | ||
| 274 | call.getSignature() | ||
| 275 | ); | ||
| 276 | } | ||
| 268 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( | 277 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( |
| 269 | calledMethodEntry, | 278 | calledMethodEntry, |
| 270 | behaviorEntry | 279 | behaviorEntry |
| @@ -280,6 +289,14 @@ public class JarIndex | |||
| 280 | new ClassEntry( className ), | 289 | new ClassEntry( className ), |
| 281 | call.getFieldName() | 290 | call.getFieldName() |
| 282 | ); | 291 | ); |
| 292 | ClassEntry resolvedClassEntry = resolveEntryClass( calledFieldEntry ); | ||
| 293 | if( resolvedClassEntry != null && !resolvedClassEntry.equals( calledFieldEntry.getClassEntry() ) ) | ||
| 294 | { | ||
| 295 | calledFieldEntry = new FieldEntry( | ||
| 296 | resolvedClassEntry, | ||
| 297 | call.getFieldName() | ||
| 298 | ); | ||
| 299 | } | ||
| 283 | EntryReference<FieldEntry,BehaviorEntry> reference = new EntryReference<FieldEntry,BehaviorEntry>( | 300 | EntryReference<FieldEntry,BehaviorEntry> reference = new EntryReference<FieldEntry,BehaviorEntry>( |
| 284 | calledFieldEntry, | 301 | calledFieldEntry, |
| 285 | behaviorEntry | 302 | behaviorEntry |
| @@ -355,30 +372,26 @@ public class JarIndex | |||
| 355 | throw new IllegalArgumentException( "behavior must be a method or a constructor!" ); | 372 | throw new IllegalArgumentException( "behavior must be a method or a constructor!" ); |
| 356 | } | 373 | } |
| 357 | } | 374 | } |
| 358 | 375 | ||
| 359 | private MethodEntry resolveMethodClass( MethodEntry methodEntry ) | 376 | public ClassEntry resolveEntryClass( Entry obfEntry ) |
| 360 | { | 377 | { |
| 361 | // this entry could refer to a method on a class where the method is not actually implemented | 378 | // this entry could refer to a method on a class where the method is not actually implemented |
| 362 | // travel up the inheritance tree to find the closest implementation | 379 | // travel up the inheritance tree to find the closest implementation |
| 363 | while( !isMethodImplemented( methodEntry ) ) | 380 | while( !containsObfEntry( obfEntry ) ) |
| 364 | { | 381 | { |
| 365 | // is there a parent class? | 382 | // is there a parent class? |
| 366 | String superclassName = m_translationIndex.getSuperclassName( methodEntry.getClassName() ); | 383 | String superclassName = m_translationIndex.getSuperclassName( obfEntry.getClassName() ); |
| 367 | if( superclassName == null ) | 384 | if( superclassName == null ) |
| 368 | { | 385 | { |
| 369 | // this is probably a method from a class in a library | 386 | // this is probably a method from a class in a library |
| 370 | // we can't trace the implementation up any higher unless we index the library | 387 | // we can't trace the implementation up any higher unless we index the library |
| 371 | return methodEntry; | 388 | return null; |
| 372 | } | 389 | } |
| 373 | 390 | ||
| 374 | // move up to the parent class | 391 | // move up to the parent class |
| 375 | methodEntry = new MethodEntry( | 392 | obfEntry = obfEntry.cloneToNewClass( new ClassEntry( superclassName ) ); |
| 376 | new ClassEntry( superclassName ), | ||
| 377 | methodEntry.getName(), | ||
| 378 | methodEntry.getSignature() | ||
| 379 | ); | ||
| 380 | } | 393 | } |
| 381 | return methodEntry; | 394 | return obfEntry.getClassEntry(); |
| 382 | } | 395 | } |
| 383 | 396 | ||
| 384 | private CtMethod getBridgedMethod( CtMethod method ) | 397 | private CtMethod getBridgedMethod( CtMethod method ) |
| @@ -704,16 +717,6 @@ public class JarIndex | |||
| 704 | return m_fieldClasses.get( fieldEntry ); | 717 | return m_fieldClasses.get( fieldEntry ); |
| 705 | } | 718 | } |
| 706 | 719 | ||
| 707 | public boolean isMethodImplemented( MethodEntry methodEntry ) | ||
| 708 | { | ||
| 709 | Collection<MethodEntry> implementations = m_methodImplementations.get( methodEntry.getClassName() ); | ||
| 710 | if( implementations == null ) | ||
| 711 | { | ||
| 712 | return false; | ||
| 713 | } | ||
| 714 | return implementations.contains( methodEntry ); | ||
| 715 | } | ||
| 716 | |||
| 717 | public ClassInheritanceTreeNode getClassInheritance( Translator deobfuscatingTranslator, ClassEntry obfClassEntry ) | 720 | public ClassInheritanceTreeNode getClassInheritance( Translator deobfuscatingTranslator, ClassEntry obfClassEntry ) |
| 718 | { | 721 | { |
| 719 | // get the root node | 722 | // get the root node |
| @@ -751,7 +754,7 @@ public class JarIndex | |||
| 751 | obfMethodEntry.getName(), | 754 | obfMethodEntry.getName(), |
| 752 | obfMethodEntry.getSignature() | 755 | obfMethodEntry.getSignature() |
| 753 | ); | 756 | ); |
| 754 | if( isMethodImplemented( ancestorMethodEntry ) ) | 757 | if( containsObfBehavior( ancestorMethodEntry ) ) |
| 755 | { | 758 | { |
| 756 | baseImplementationClassName = ancestorClassName; | 759 | baseImplementationClassName = ancestorClassName; |
| 757 | } | 760 | } |
| @@ -766,7 +769,7 @@ public class JarIndex | |||
| 766 | MethodInheritanceTreeNode rootNode = new MethodInheritanceTreeNode( | 769 | MethodInheritanceTreeNode rootNode = new MethodInheritanceTreeNode( |
| 767 | deobfuscatingTranslator, | 770 | deobfuscatingTranslator, |
| 768 | methodEntry, | 771 | methodEntry, |
| 769 | isMethodImplemented( methodEntry ) | 772 | containsObfBehavior( methodEntry ) |
| 770 | ); | 773 | ); |
| 771 | 774 | ||
| 772 | // expand the full tree | 775 | // expand the full tree |
| @@ -796,7 +799,7 @@ public class JarIndex | |||
| 796 | obfMethodEntry.getName(), | 799 | obfMethodEntry.getName(), |
| 797 | obfMethodEntry.getSignature() | 800 | obfMethodEntry.getSignature() |
| 798 | ); | 801 | ); |
| 799 | if( isMethodImplemented( methodInterface ) ) | 802 | if( containsObfBehavior( methodInterface ) ) |
| 800 | { | 803 | { |
| 801 | methodInterfaces.add( methodInterface ); | 804 | methodInterfaces.add( methodInterface ); |
| 802 | } | 805 | } |
| @@ -827,7 +830,7 @@ public class JarIndex | |||
| 827 | private void getRelatedMethodImplementations( Set<MethodEntry> methodEntries, MethodInheritanceTreeNode node ) | 830 | private void getRelatedMethodImplementations( Set<MethodEntry> methodEntries, MethodInheritanceTreeNode node ) |
| 828 | { | 831 | { |
| 829 | MethodEntry methodEntry = node.getMethodEntry(); | 832 | MethodEntry methodEntry = node.getMethodEntry(); |
| 830 | if( isMethodImplemented( methodEntry ) ) | 833 | if( containsObfBehavior( methodEntry ) ) |
| 831 | { | 834 | { |
| 832 | // collect the entry | 835 | // collect the entry |
| 833 | methodEntries.add( methodEntry ); | 836 | methodEntries.add( methodEntry ); |
| @@ -850,7 +853,7 @@ public class JarIndex | |||
| 850 | private void getRelatedMethodImplementations( Set<MethodEntry> methodEntries, MethodImplementationsTreeNode node ) | 853 | private void getRelatedMethodImplementations( Set<MethodEntry> methodEntries, MethodImplementationsTreeNode node ) |
| 851 | { | 854 | { |
| 852 | MethodEntry methodEntry = node.getMethodEntry(); | 855 | MethodEntry methodEntry = node.getMethodEntry(); |
| 853 | if( isMethodImplemented( methodEntry ) ) | 856 | if( containsObfBehavior( methodEntry ) ) |
| 854 | { | 857 | { |
| 855 | // collect the entry | 858 | // collect the entry |
| 856 | methodEntries.add( methodEntry ); | 859 | methodEntries.add( methodEntry ); |
| @@ -969,8 +972,49 @@ public class JarIndex | |||
| 969 | return m_access.containsKey( obfFieldEntry ); | 972 | return m_access.containsKey( obfFieldEntry ); |
| 970 | } | 973 | } |
| 971 | 974 | ||
| 972 | public boolean containsObfMethod( MethodEntry obfMethodEntry ) | 975 | public boolean containsObfBehavior( BehaviorEntry obfBehaviorEntry ) |
| 976 | { | ||
| 977 | return m_access.containsKey( obfBehaviorEntry ); | ||
| 978 | } | ||
| 979 | |||
| 980 | public boolean containsObfArgument( ArgumentEntry obfArgumentEntry ) | ||
| 981 | { | ||
| 982 | // check the behavior | ||
| 983 | if( !containsObfBehavior( obfArgumentEntry.getBehaviorEntry() ) ) | ||
| 984 | { | ||
| 985 | return false; | ||
| 986 | } | ||
| 987 | |||
| 988 | // check the argument | ||
| 989 | if( obfArgumentEntry.getIndex() >= Descriptor.numOfParameters( obfArgumentEntry.getBehaviorEntry().getSignature() ) ) | ||
| 990 | { | ||
| 991 | return false; | ||
| 992 | } | ||
| 993 | |||
| 994 | return true; | ||
| 995 | } | ||
| 996 | |||
| 997 | public boolean containsObfEntry( Entry obfEntry ) | ||
| 973 | { | 998 | { |
| 974 | return m_access.containsKey( obfMethodEntry ); | 999 | if( obfEntry instanceof ClassEntry ) |
| 1000 | { | ||
| 1001 | return containsObfClass( (ClassEntry)obfEntry ); | ||
| 1002 | } | ||
| 1003 | else if( obfEntry instanceof FieldEntry ) | ||
| 1004 | { | ||
| 1005 | return containsObfField( (FieldEntry)obfEntry ); | ||
| 1006 | } | ||
| 1007 | else if( obfEntry instanceof BehaviorEntry ) | ||
| 1008 | { | ||
| 1009 | return containsObfBehavior( (BehaviorEntry)obfEntry ); | ||
| 1010 | } | ||
| 1011 | else if( obfEntry instanceof ArgumentEntry ) | ||
| 1012 | { | ||
| 1013 | return containsObfArgument( (ArgumentEntry)obfEntry ); | ||
| 1014 | } | ||
| 1015 | else | ||
| 1016 | { | ||
| 1017 | throw new Error( "Entry type not supported: " + obfEntry.getClass().getName() ); | ||
| 1018 | } | ||
| 975 | } | 1019 | } |
| 976 | } | 1020 | } |