summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
diff options
context:
space:
mode:
authorGravatar Thog2017-05-16 00:24:29 +0200
committerGravatar Thog2017-05-16 00:24:29 +0200
commitb280104d2f926ab74772cef2bf1602663cefa312 (patch)
treed130c86a30ec5df37b3a9c4bab576e971ae2e664 /src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
parentAdd offset for Enum constructor arguments (Fix #58) (diff)
downloadenigma-fork-b280104d2f926ab74772cef2bf1602663cefa312.tar.gz
enigma-fork-b280104d2f926ab74772cef2bf1602663cefa312.tar.xz
enigma-fork-b280104d2f926ab74772cef2bf1602663cefa312.zip
Remove the converter + some reorganization
Diffstat (limited to 'src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java')
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java151
1 files changed, 0 insertions, 151 deletions
diff --git a/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
deleted file mode 100644
index f1c3dd7..0000000
--- a/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
+++ /dev/null
@@ -1,151 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.bytecode;
13
14import com.google.common.collect.Lists;
15import cuchaz.enigma.analysis.JarIndex;
16import cuchaz.enigma.mapping.*;
17import javassist.ClassPool;
18import javassist.CtClass;
19import javassist.NotFoundException;
20import javassist.bytecode.*;
21
22import java.util.Collection;
23import java.util.List;
24
25public class InnerClassWriter {
26
27 private JarIndex index;
28 private Translator deobfuscatorTranslator;
29
30 public InnerClassWriter(JarIndex index, Translator deobfuscatorTranslator) {
31 this.index = index;
32 this.deobfuscatorTranslator = deobfuscatorTranslator;
33 }
34
35 // FIXME: modifier is not applied to inner class
36 public static void changeModifier(CtClass c, InnerClassesAttribute attr, Translator translator) {
37 ClassPool pool = c.getClassPool();
38 for (int i = 0; i < attr.tableLength(); i++) {
39
40 String innerName = attr.innerClass(i);
41 // get the inner class full name (which has already been translated)
42 ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(innerName));
43 try {
44 CtClass innerClass = pool.get(innerName);
45 Mappings.EntryModifier modifier = translator.getModifier(classEntry);
46 if (modifier != null && modifier != Mappings.EntryModifier.UNCHANGED)
47 ClassRenamer.applyModifier(innerClass, modifier);
48 } catch (NotFoundException e) {
49 // This shouldn't be possible in theory
50 //e.printStackTrace();
51 }
52 }
53 }
54
55 public void write(CtClass c) {
56
57 // don't change anything if there's already an attribute there
58 InnerClassesAttribute oldAttr = (InnerClassesAttribute) c.getClassFile().getAttribute(InnerClassesAttribute.tag);
59 if (oldAttr != null) {
60 // bail!
61 return;
62 }
63
64 ClassEntry obfClassEntry = EntryFactory.getClassEntry(c);
65 List<ClassEntry> obfClassChain = this.index.getObfClassChain(obfClassEntry);
66
67 boolean isInnerClass = obfClassChain.size() > 1;
68 if (isInnerClass) {
69
70 // it's an inner class, rename it to the fully qualified name
71 c.setName(obfClassEntry.buildClassEntry(obfClassChain).getName());
72
73 BehaviorEntry caller = this.index.getAnonymousClassCaller(obfClassEntry);
74 if (caller != null) {
75
76 // write the enclosing method attribute
77 if (caller.getName().equals("<clinit>")) {
78 c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName()));
79 } else {
80 c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName(), caller.getName(), caller.getSignature().toString()));
81 }
82 }
83 }
84
85 // does this class have any inner classes?
86 Collection<ClassEntry> obfInnerClassEntries = this.index.getInnerClasses(obfClassEntry);
87
88 if (isInnerClass || !obfInnerClassEntries.isEmpty()) {
89
90 // create an inner class attribute
91 InnerClassesAttribute attr = new InnerClassesAttribute(c.getClassFile().getConstPool());
92 c.getClassFile().addAttribute(attr);
93
94 // write the ancestry, but not the outermost class
95 for (int i = 1; i < obfClassChain.size(); i++) {
96 ClassEntry obfInnerClassEntry = obfClassChain.get(i);
97 writeInnerClass(attr, obfClassChain, obfInnerClassEntry);
98
99 // update references to use the fully qualified inner class name
100 c.replaceClassName(obfInnerClassEntry.getName(), obfInnerClassEntry.buildClassEntry(obfClassChain).getName());
101 }
102
103 // write the inner classes
104 for (ClassEntry obfInnerClassEntry : obfInnerClassEntries) {
105
106 // extend the class chain
107 List<ClassEntry> extendedObfClassChain = Lists.newArrayList(obfClassChain);
108 extendedObfClassChain.add(obfInnerClassEntry);
109
110 writeInnerClass(attr, extendedObfClassChain, obfInnerClassEntry);
111
112 // update references to use the fully qualified inner class name
113 c.replaceClassName(obfInnerClassEntry.getName(), obfInnerClassEntry.buildClassEntry(extendedObfClassChain).getName());
114 }
115 }
116 }
117
118 private void writeInnerClass(InnerClassesAttribute attr, List<ClassEntry> obfClassChain, ClassEntry obfClassEntry) {
119
120 // get the new inner class name
121 ClassEntry obfInnerClassEntry = obfClassEntry.buildClassEntry(obfClassChain);
122 ClassEntry obfOuterClassEntry = obfInnerClassEntry.getOuterClassEntry();
123
124 // here's what the JVM spec says about the InnerClasses attribute
125 // append(inner, parent, 0 if anonymous else simple name, flags);
126
127 // update the attribute with this inner class
128 ConstPool constPool = attr.getConstPool();
129 int innerClassIndex = constPool.addClassInfo(obfInnerClassEntry.getName());
130 int parentClassIndex = constPool.addClassInfo(obfOuterClassEntry.getName());
131 int innerClassNameIndex = 0;
132 int accessFlags = AccessFlag.PUBLIC;
133 // TODO: need to figure out if we can put static or not
134 if (!this.index.isAnonymousClass(obfClassEntry)) {
135 innerClassNameIndex = constPool.addUtf8Info(obfInnerClassEntry.getInnermostClassName());
136 }
137
138 attr.append(innerClassIndex, parentClassIndex, innerClassNameIndex, accessFlags);
139
140 /* DEBUG
141 System.out.println(String.format("\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)",
142 obfClassEntry,
143 attr.innerClass(attr.tableLength() - 1),
144 attr.outerClass(attr.tableLength() - 1),
145 attr.innerName(attr.tableLength() - 1),
146 Constants.NonePackage + "/" + obfInnerClassName,
147 obfClassEntry.getName()
148 ));
149 */
150 }
151}