summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/bytecode
diff options
context:
space:
mode:
authorGravatar jeff2014-08-23 23:43:31 -0400
committerGravatar jeff2014-08-23 23:43:31 -0400
commit8fa1741b621644ef84a9395a4c395d4ff3a89207 (patch)
tree9cc054e2636dd13a32950ad68dba212275d33026 /src/cuchaz/enigma/bytecode
parentadded export command with progress bar (diff)
downloadenigma-fork-8fa1741b621644ef84a9395a4c395d4ff3a89207.tar.gz
enigma-fork-8fa1741b621644ef84a9395a4c395d4ff3a89207.tar.xz
enigma-fork-8fa1741b621644ef84a9395a4c395d4ff3a89207.zip
moved all classes from the default package into a package called "default" so they can be properly imported by other classes
Diffstat (limited to 'src/cuchaz/enigma/bytecode')
-rw-r--r--src/cuchaz/enigma/bytecode/ClassRenamer.java115
-rw-r--r--src/cuchaz/enigma/bytecode/ClassTranslator.java64
-rw-r--r--src/cuchaz/enigma/bytecode/InnerClassWriter.java6
3 files changed, 124 insertions, 61 deletions
diff --git a/src/cuchaz/enigma/bytecode/ClassRenamer.java b/src/cuchaz/enigma/bytecode/ClassRenamer.java
new file mode 100644
index 0000000..cba5861
--- /dev/null
+++ b/src/cuchaz/enigma/bytecode/ClassRenamer.java
@@ -0,0 +1,115 @@
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.bytecode;
12
13import java.util.Map;
14import java.util.Set;
15
16import javassist.ClassMap;
17import javassist.CtClass;
18import javassist.bytecode.ConstPool;
19import javassist.bytecode.Descriptor;
20import javassist.bytecode.InnerClassesAttribute;
21
22import com.beust.jcommander.internal.Sets;
23import com.google.common.collect.Maps;
24
25import cuchaz.enigma.mapping.ClassEntry;
26
27public class ClassRenamer
28{
29 public static void renameClasses( CtClass c, Map<ClassEntry,ClassEntry> map )
30 {
31 // build the map used by javassist
32 ClassMap nameMap = new ClassMap();
33 for( Map.Entry<ClassEntry,ClassEntry> entry : map.entrySet() )
34 {
35 nameMap.put( entry.getKey().getName(), entry.getValue().getName() );
36 }
37 c.replaceClassName( nameMap );
38
39 // translate the names in the InnerClasses attribute
40 ConstPool constants = c.getClassFile().getConstPool();
41 InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute( InnerClassesAttribute.tag );
42 if( attr != null )
43 {
44 for( int i=0; i<attr.tableLength(); i++ )
45 {
46 ClassEntry inClassEntry = new ClassEntry( Descriptor.toJvmName( attr.innerClass( i ) ) );
47 ClassEntry outClassEntry = map.get( inClassEntry );
48 attr.setInnerClassIndex( i, constants.addClassInfo( outClassEntry.getName() ) );
49 if( attr.outerClassIndex( i ) != 0 )
50 {
51 attr.setOuterClassIndex( i, constants.addClassInfo( outClassEntry.getOuterClassName() ) );
52 }
53 if( attr.innerNameIndex( i ) != 0 )
54 {
55 attr.setInnerNameIndex( i, constants.addUtf8Info( outClassEntry.getInnerClassName() ) );
56 }
57
58 /* DEBUG
59 System.out.println( String.format( "\tOBF: %s DEOBF: %s-> ATTR: %s,%s,%s",
60 obfClassEntry, deobfClassEntry,
61 attr.outerClass( i ),
62 attr.innerClass( i ),
63 attr.innerName( i )
64 ) );
65 */
66 }
67 }
68 }
69
70 public static Set<ClassEntry> getAllClassEntries( CtClass c )
71 {
72 // get the classes that javassist knows about
73 final Set<ClassEntry> entries = Sets.newHashSet();
74 ClassMap map = new ClassMap( )
75 {
76 @Override
77 public Object get( Object obj )
78 {
79 if( obj instanceof String )
80 {
81 entries.add( new ClassEntry( (String)obj ) );
82 }
83 return null;
84 }
85 private static final long serialVersionUID = -202160293602070641L;
86 };
87 c.replaceClassName( map );
88
89 // also check InnerClassesAttribute
90 InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute( InnerClassesAttribute.tag );
91 if( attr != null )
92 {
93 for( int i=0; i<attr.tableLength(); i++ )
94 {
95 entries.add( new ClassEntry( Descriptor.toJvmName( attr.innerClass( i ) ) ) );
96 }
97 }
98
99 return entries;
100 }
101
102 public static void moveAllClassesOutOfDefaultPackage( CtClass c, String newPackageName )
103 {
104 // rename all classes
105 Map<ClassEntry,ClassEntry> map = Maps.newHashMap();
106 for( ClassEntry classEntry : ClassRenamer.getAllClassEntries( c ) )
107 {
108 if( classEntry.isInDefaultPackage() )
109 {
110 map.put( classEntry, new ClassEntry( newPackageName + "/" + classEntry.getName() ) );
111 }
112 }
113 ClassRenamer.renameClasses( c, map );
114 }
115}
diff --git a/src/cuchaz/enigma/bytecode/ClassTranslator.java b/src/cuchaz/enigma/bytecode/ClassTranslator.java
index 9ce06a5..885b45f 100644
--- a/src/cuchaz/enigma/bytecode/ClassTranslator.java
+++ b/src/cuchaz/enigma/bytecode/ClassTranslator.java
@@ -10,18 +10,16 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.bytecode; 11package cuchaz.enigma.bytecode;
12 12
13import java.util.Set; 13import java.util.Map;
14 14
15import javassist.ClassMap;
16import javassist.CtBehavior; 15import javassist.CtBehavior;
17import javassist.CtClass; 16import javassist.CtClass;
18import javassist.CtField; 17import javassist.CtField;
19import javassist.CtMethod; 18import javassist.CtMethod;
20import javassist.bytecode.ConstPool; 19import javassist.bytecode.ConstPool;
21import javassist.bytecode.Descriptor; 20import javassist.bytecode.Descriptor;
22import javassist.bytecode.InnerClassesAttribute;
23 21
24import com.beust.jcommander.internal.Sets; 22import com.beust.jcommander.internal.Maps;
25 23
26import cuchaz.enigma.mapping.ClassEntry; 24import cuchaz.enigma.mapping.ClassEntry;
27import cuchaz.enigma.mapping.FieldEntry; 25import cuchaz.enigma.mapping.FieldEntry;
@@ -136,61 +134,11 @@ public class ClassTranslator
136 134
137 // translate all the class names referenced in the code 135 // translate all the class names referenced in the code
138 // the above code only changed method/field/reference names and types, but not the class names themselves 136 // the above code only changed method/field/reference names and types, but not the class names themselves
139 Set<ClassEntry> classEntries = getAllClassEntries( c ); 137 Map<ClassEntry,ClassEntry> map = Maps.newHashMap();
140 ClassMap map = new ClassMap(); 138 for( ClassEntry obfClassEntry : ClassRenamer.getAllClassEntries( c ) )
141 for( ClassEntry obfClassEntry : classEntries )
142 { 139 {
143 map.put( obfClassEntry.getName(), m_translator.translateEntry( obfClassEntry ).getName() ); 140 map.put( obfClassEntry, m_translator.translateEntry( obfClassEntry ) );
144 } 141 }
145 c.replaceClassName( map ); 142 ClassRenamer.renameClasses( c, map );
146
147 // translate the names in the InnerClasses attribute
148 InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute( InnerClassesAttribute.tag );
149 if( attr != null )
150 {
151 for( int i=0; i<attr.tableLength(); i++ )
152 {
153 ClassEntry obfClassEntry = new ClassEntry( Descriptor.toJvmName( attr.innerClass( i ) ) );
154 ClassEntry deobfClassEntry = m_translator.translateEntry( obfClassEntry );
155 attr.setInnerClassIndex( i, constants.addClassInfo( deobfClassEntry.getName() ) );
156 if( attr.outerClassIndex( i ) != 0 )
157 {
158 attr.setOuterClassIndex( i, constants.addClassInfo( deobfClassEntry.getOuterClassName() ) );
159 }
160 if( attr.innerNameIndex( i ) != 0 )
161 {
162 attr.setInnerNameIndex( i, constants.addUtf8Info( deobfClassEntry.getInnerClassName() ) );
163 }
164
165 /* DEBUG
166 System.out.println( String.format( "\tOBF: %s DEOBF: %s-> ATTR: %s,%s,%s",
167 obfClassEntry, deobfClassEntry,
168 attr.outerClass( i ),
169 attr.innerClass( i ),
170 attr.innerName( i )
171 ) );
172 */
173 }
174 }
175 }
176
177 private Set<ClassEntry> getAllClassEntries( CtClass c )
178 {
179 final Set<ClassEntry> entries = Sets.newHashSet();
180 ClassMap map = new ClassMap( )
181 {
182 @Override
183 public Object get( Object obj )
184 {
185 if( obj instanceof String )
186 {
187 entries.add( new ClassEntry( (String)obj ) );
188 }
189 return null;
190 }
191 private static final long serialVersionUID = -202160293602070641L;
192 };
193 c.replaceClassName( map );
194 return entries;
195 } 143 }
196} 144}
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
index c412b1a..2fb5fe0 100644
--- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java
+++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
@@ -42,7 +42,7 @@ public class InnerClassWriter
42 else 42 else
43 { 43 {
44 // this is an inner class, rename it to outer$inner 44 // this is an inner class, rename it to outer$inner
45 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfClassName ); 45 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + new ClassEntry( obfClassName ).getSimpleName() );
46 c.setName( obfClassEntry.getName() ); 46 c.setName( obfClassEntry.getName() );
47 } 47 }
48 48
@@ -60,8 +60,8 @@ public class InnerClassWriter
60 c.getClassFile().addAttribute( attr ); 60 c.getClassFile().addAttribute( attr );
61 for( String obfInnerClassName : obfInnerClassNames ) 61 for( String obfInnerClassName : obfInnerClassNames )
62 { 62 {
63 // deobfuscate the class names 63 // get the new inner class name
64 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfInnerClassName ); 64 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + new ClassEntry( obfInnerClassName ).getSimpleName() );
65 65
66 // here's what the JVM spec says about the InnerClasses attribute 66 // here's what the JVM spec says about the InnerClasses attribute
67 // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags ); 67 // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags );