diff options
| author | 2015-02-08 21:29:25 -0500 | |
|---|---|---|
| committer | 2015-02-08 21:29:25 -0500 | |
| commit | ed9b5cdfc648e86fd463bfa8d86b94c41671e14c (patch) | |
| tree | 2619bbc7e04dfa3b82f8dfd3b1d31f529766cd4b /src/cuchaz/enigma/bytecode/InnerClassWriter.java | |
| download | enigma-fork-ed9b5cdfc648e86fd463bfa8d86b94c41671e14c.tar.gz enigma-fork-ed9b5cdfc648e86fd463bfa8d86b94c41671e14c.tar.xz enigma-fork-ed9b5cdfc648e86fd463bfa8d86b94c41671e14c.zip | |
switch all classes to new signature/type system
Diffstat (limited to 'src/cuchaz/enigma/bytecode/InnerClassWriter.java')
| -rw-r--r-- | src/cuchaz/enigma/bytecode/InnerClassWriter.java | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java new file mode 100644 index 0000000..817500b --- /dev/null +++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java | |||
| @@ -0,0 +1,102 @@ | |||
| 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.bytecode; | ||
| 12 | |||
| 13 | import java.util.Collection; | ||
| 14 | |||
| 15 | import javassist.CtClass; | ||
| 16 | import javassist.bytecode.AccessFlag; | ||
| 17 | import javassist.bytecode.ConstPool; | ||
| 18 | import javassist.bytecode.Descriptor; | ||
| 19 | import javassist.bytecode.EnclosingMethodAttribute; | ||
| 20 | import javassist.bytecode.InnerClassesAttribute; | ||
| 21 | import cuchaz.enigma.Constants; | ||
| 22 | import cuchaz.enigma.analysis.JarIndex; | ||
| 23 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 24 | import cuchaz.enigma.mapping.ClassEntry; | ||
| 25 | |||
| 26 | public class InnerClassWriter { | ||
| 27 | |||
| 28 | private JarIndex m_jarIndex; | ||
| 29 | |||
| 30 | public InnerClassWriter(JarIndex jarIndex) { | ||
| 31 | m_jarIndex = jarIndex; | ||
| 32 | } | ||
| 33 | |||
| 34 | public void write(CtClass c) { | ||
| 35 | |||
| 36 | // is this an inner or outer class? | ||
| 37 | String obfInnerClassName = new ClassEntry(Descriptor.toJvmName(c.getName())).getSimpleName(); | ||
| 38 | String obfOuterClassName = m_jarIndex.getOuterClass(obfInnerClassName); | ||
| 39 | if (obfOuterClassName == null) { | ||
| 40 | // this is an outer class | ||
| 41 | obfOuterClassName = Descriptor.toJvmName(c.getName()); | ||
| 42 | } else { | ||
| 43 | // this is an inner class, rename it to outer$inner | ||
| 44 | ClassEntry obfClassEntry = new ClassEntry(obfOuterClassName + "$" + obfInnerClassName); | ||
| 45 | c.setName(obfClassEntry.getName()); | ||
| 46 | |||
| 47 | BehaviorEntry caller = m_jarIndex.getAnonymousClassCaller(obfInnerClassName); | ||
| 48 | if (caller != null) { | ||
| 49 | // write the enclosing method attribute | ||
| 50 | if (caller.getName().equals("<clinit>")) { | ||
| 51 | c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName())); | ||
| 52 | } else { | ||
| 53 | c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName(), caller.getName(), caller.getSignature().toString())); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | // write the inner classes if needed | ||
| 59 | Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses(obfOuterClassName); | ||
| 60 | if (obfInnerClassNames != null && !obfInnerClassNames.isEmpty()) { | ||
| 61 | writeInnerClasses(c, obfOuterClassName, obfInnerClassNames); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | private void writeInnerClasses(CtClass c, String obfOuterClassName, Collection<String> obfInnerClassNames) { | ||
| 66 | InnerClassesAttribute attr = new InnerClassesAttribute(c.getClassFile().getConstPool()); | ||
| 67 | c.getClassFile().addAttribute(attr); | ||
| 68 | for (String obfInnerClassName : obfInnerClassNames) { | ||
| 69 | // get the new inner class name | ||
| 70 | ClassEntry obfClassEntry = new ClassEntry(obfOuterClassName + "$" + obfInnerClassName); | ||
| 71 | |||
| 72 | // here's what the JVM spec says about the InnerClasses attribute | ||
| 73 | // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags ); | ||
| 74 | |||
| 75 | // update the attribute with this inner class | ||
| 76 | ConstPool constPool = c.getClassFile().getConstPool(); | ||
| 77 | int innerClassIndex = constPool.addClassInfo(obfClassEntry.getName()); | ||
| 78 | int outerClassIndex = 0; | ||
| 79 | int innerClassSimpleNameIndex = 0; | ||
| 80 | if (!m_jarIndex.isAnonymousClass(obfInnerClassName)) { | ||
| 81 | outerClassIndex = constPool.addClassInfo(obfClassEntry.getOuterClassName()); | ||
| 82 | innerClassSimpleNameIndex = constPool.addUtf8Info(obfClassEntry.getInnerClassName()); | ||
| 83 | } | ||
| 84 | |||
| 85 | attr.append(innerClassIndex, outerClassIndex, innerClassSimpleNameIndex, c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER); | ||
| 86 | |||
| 87 | /* DEBUG | ||
| 88 | System.out.println(String.format("\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)", | ||
| 89 | obfClassEntry, | ||
| 90 | attr.outerClass(attr.tableLength() - 1), | ||
| 91 | attr.innerClass(attr.tableLength() - 1), | ||
| 92 | attr.innerName(attr.tableLength() - 1), | ||
| 93 | Constants.NonePackage + "/" + obfInnerClassName, | ||
| 94 | obfClassEntry.getName() | ||
| 95 | )); | ||
| 96 | */ | ||
| 97 | |||
| 98 | // make sure the outer class references only the new inner class names | ||
| 99 | c.replaceClassName(Constants.NonePackage + "/" + obfInnerClassName, obfClassEntry.getName()); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||