From 4be005617b3b8c3578cca07c5d085d12916f0d1d Mon Sep 17 00:00:00 2001 From: lclc98 Date: Thu, 30 Jun 2016 00:49:21 +1000 Subject: Json format (#2) * Added new format * Fixed bug * Updated Version --- src/cuchaz/enigma/bytecode/CheckCastIterator.java | 127 ----- src/cuchaz/enigma/bytecode/ClassProtectifier.java | 51 -- src/cuchaz/enigma/bytecode/ClassPublifier.java | 51 -- src/cuchaz/enigma/bytecode/ClassRenamer.java | 544 --------------------- src/cuchaz/enigma/bytecode/ClassTranslator.java | 157 ------ src/cuchaz/enigma/bytecode/ConstPoolEditor.java | 263 ---------- src/cuchaz/enigma/bytecode/InfoType.java | 317 ------------ src/cuchaz/enigma/bytecode/InnerClassWriter.java | 132 ----- .../enigma/bytecode/LocalVariableRenamer.java | 123 ----- .../enigma/bytecode/MethodParameterWriter.java | 70 --- .../enigma/bytecode/MethodParametersAttribute.java | 86 ---- .../bytecode/accessors/ClassInfoAccessor.java | 55 --- .../bytecode/accessors/ConstInfoAccessor.java | 156 ------ .../accessors/InvokeDynamicInfoAccessor.java | 74 --- .../bytecode/accessors/MemberRefInfoAccessor.java | 74 --- .../accessors/MethodHandleInfoAccessor.java | 74 --- .../bytecode/accessors/MethodTypeInfoAccessor.java | 55 --- .../accessors/NameAndTypeInfoAccessor.java | 74 --- .../bytecode/accessors/StringInfoAccessor.java | 55 --- .../bytecode/accessors/Utf8InfoAccessor.java | 28 -- 20 files changed, 2566 deletions(-) delete mode 100644 src/cuchaz/enigma/bytecode/CheckCastIterator.java delete mode 100644 src/cuchaz/enigma/bytecode/ClassProtectifier.java delete mode 100644 src/cuchaz/enigma/bytecode/ClassPublifier.java delete mode 100644 src/cuchaz/enigma/bytecode/ClassRenamer.java delete mode 100644 src/cuchaz/enigma/bytecode/ClassTranslator.java delete mode 100644 src/cuchaz/enigma/bytecode/ConstPoolEditor.java delete mode 100644 src/cuchaz/enigma/bytecode/InfoType.java delete mode 100644 src/cuchaz/enigma/bytecode/InnerClassWriter.java delete mode 100644 src/cuchaz/enigma/bytecode/LocalVariableRenamer.java delete mode 100644 src/cuchaz/enigma/bytecode/MethodParameterWriter.java delete mode 100644 src/cuchaz/enigma/bytecode/MethodParametersAttribute.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java delete mode 100644 src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java (limited to 'src/cuchaz/enigma/bytecode') diff --git a/src/cuchaz/enigma/bytecode/CheckCastIterator.java b/src/cuchaz/enigma/bytecode/CheckCastIterator.java deleted file mode 100644 index 517b9d6..0000000 --- a/src/cuchaz/enigma/bytecode/CheckCastIterator.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode; - -import java.util.Iterator; - -import javassist.bytecode.BadBytecode; -import javassist.bytecode.CodeAttribute; -import javassist.bytecode.CodeIterator; -import javassist.bytecode.ConstPool; -import javassist.bytecode.Descriptor; -import javassist.bytecode.Opcode; -import cuchaz.enigma.bytecode.CheckCastIterator.CheckCast; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.MethodEntry; -import cuchaz.enigma.mapping.Signature; - -public class CheckCastIterator implements Iterator { - - public static class CheckCast { - - public String className; - public MethodEntry prevMethodEntry; - - public CheckCast(String className, MethodEntry prevMethodEntry) { - this.className = className; - this.prevMethodEntry = prevMethodEntry; - } - } - - private ConstPool m_constants; - private CodeAttribute m_attribute; - private CodeIterator m_iter; - private CheckCast m_next; - - public CheckCastIterator(CodeAttribute codeAttribute) throws BadBytecode { - m_constants = codeAttribute.getConstPool(); - m_attribute = codeAttribute; - m_iter = m_attribute.iterator(); - - m_next = getNext(); - } - - @Override - public boolean hasNext() { - return m_next != null; - } - - @Override - public CheckCast next() { - CheckCast out = m_next; - try { - m_next = getNext(); - } catch (BadBytecode ex) { - throw new Error(ex); - } - return out; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private CheckCast getNext() throws BadBytecode { - int prevPos = 0; - while (m_iter.hasNext()) { - int pos = m_iter.next(); - int opcode = m_iter.byteAt(pos); - switch (opcode) { - case Opcode.CHECKCAST: - - // get the type of this op code (next two bytes are a classinfo index) - MethodEntry prevMethodEntry = getMethodEntry(prevPos); - if (prevMethodEntry != null) { - return new CheckCast(m_constants.getClassInfo(m_iter.s16bitAt(pos + 1)), prevMethodEntry); - } - break; - } - prevPos = pos; - } - return null; - } - - private MethodEntry getMethodEntry(int pos) { - switch (m_iter.byteAt(pos)) { - case Opcode.INVOKEVIRTUAL: - case Opcode.INVOKESTATIC: - case Opcode.INVOKEDYNAMIC: - case Opcode.INVOKESPECIAL: { - int index = m_iter.s16bitAt(pos + 1); - return new MethodEntry( - new ClassEntry(Descriptor.toJvmName(m_constants.getMethodrefClassName(index))), - m_constants.getMethodrefName(index), - new Signature(m_constants.getMethodrefType(index)) - ); - } - - case Opcode.INVOKEINTERFACE: { - int index = m_iter.s16bitAt(pos + 1); - return new MethodEntry( - new ClassEntry(Descriptor.toJvmName(m_constants.getInterfaceMethodrefClassName(index))), - m_constants.getInterfaceMethodrefName(index), - new Signature(m_constants.getInterfaceMethodrefType(index)) - ); - } - } - return null; - } - - public Iterable casts() { - return new Iterable() { - @Override - public Iterator iterator() { - return CheckCastIterator.this; - } - }; - } -} diff --git a/src/cuchaz/enigma/bytecode/ClassProtectifier.java b/src/cuchaz/enigma/bytecode/ClassProtectifier.java deleted file mode 100644 index f1ee4e7..0000000 --- a/src/cuchaz/enigma/bytecode/ClassProtectifier.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode; - -import javassist.CtBehavior; -import javassist.CtClass; -import javassist.CtField; -import javassist.bytecode.AccessFlag; -import javassist.bytecode.InnerClassesAttribute; - - -public class ClassProtectifier { - - public static CtClass protectify(CtClass c) { - - // protectify all the fields - for (CtField field : c.getDeclaredFields()) { - field.setModifiers(protectify(field.getModifiers())); - } - - // protectify all the methods and constructors - for (CtBehavior behavior : c.getDeclaredBehaviors()) { - behavior.setModifiers(protectify(behavior.getModifiers())); - } - - // protectify all the inner classes - InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); - if (attr != null) { - for (int i=0; i { - - private static final long serialVersionUID = 317915213205066168L; - - private ClassNameReplacer m_replacer; - - public ReplacerClassMap(ClassNameReplacer replacer) { - m_replacer = replacer; - } - - @Override - public String get(Object obj) { - if (obj instanceof String) { - return get((String)obj); - } - return null; - } - - public String get(String className) { - return m_replacer.replace(className); - } - } - - public static void renameClasses(CtClass c, final Translator translator) { - renameClasses(c, new ClassNameReplacer() { - @Override - public String replace(String className) { - ClassEntry entry = translator.translateEntry(new ClassEntry(className)); - if (entry != null) { - return entry.getName(); - } - return null; - } - }); - } - - public static void moveAllClassesOutOfDefaultPackage(CtClass c, final String newPackageName) { - renameClasses(c, new ClassNameReplacer() { - @Override - public String replace(String className) { - ClassEntry entry = new ClassEntry(className); - if (entry.isInDefaultPackage()) { - return newPackageName + "/" + entry.getName(); - } - return null; - } - }); - } - - public static void moveAllClassesIntoDefaultPackage(CtClass c, final String oldPackageName) { - renameClasses(c, new ClassNameReplacer() { - @Override - public String replace(String className) { - ClassEntry entry = new ClassEntry(className); - if (entry.getPackageName().equals(oldPackageName)) { - return entry.getSimpleName(); - } - return null; - } - }); - } - - @SuppressWarnings("unchecked") - public static void renameClasses(CtClass c, ClassNameReplacer replacer) { - - // sadly, we can't use CtClass.renameClass() because SignatureAttribute.renameClass() is extremely buggy =( - - ReplacerClassMap map = new ReplacerClassMap(replacer); - ClassFile classFile = c.getClassFile(); - - // rename the constant pool (covers ClassInfo, MethodTypeInfo, and NameAndTypeInfo) - ConstPool constPool = c.getClassFile().getConstPool(); - constPool.renameClass(map); - - // rename class attributes - renameAttributes(classFile.getAttributes(), map, SignatureType.Class); - - // rename methods - for (MethodInfo methodInfo : (List)classFile.getMethods()) { - methodInfo.setDescriptor(Descriptor.rename(methodInfo.getDescriptor(), map)); - renameAttributes(methodInfo.getAttributes(), map, SignatureType.Method); - } - - // rename fields - for (FieldInfo fieldInfo : (List)classFile.getFields()) { - fieldInfo.setDescriptor(Descriptor.rename(fieldInfo.getDescriptor(), map)); - renameAttributes(fieldInfo.getAttributes(), map, SignatureType.Field); - } - - // rename the class name itself last - // NOTE: don't use the map here, because setName() calls the buggy SignatureAttribute.renameClass() - // we only want to replace exactly this class name - String newName = renameClassName(c.getName(), map); - if (newName != null) { - c.setName(newName); - } - - // replace simple names in the InnerClasses attribute too - InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); - if (attr != null) { - for (int i = 0; i < attr.tableLength(); i++) { - - // get the inner class full name (which has already been translated) - ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(attr.innerClass(i))); - - if (attr.innerNameIndex(i) != 0) { - // update the inner name - attr.setInnerNameIndex(i, constPool.addUtf8Info(classEntry.getInnermostClassName())); - } - - /* DEBUG - System.out.println(String.format("\tDEOBF: %s-> ATTR: %s,%s,%s", classEntry, attr.outerClass(i), attr.innerClass(i), attr.innerName(i))); - */ - } - } - } - - @SuppressWarnings("unchecked") - private static void renameAttributes(List attributes, ReplacerClassMap map, SignatureType type) { - try { - - // make the rename class method accessible - Method renameClassMethod = AttributeInfo.class.getDeclaredMethod("renameClass", Map.class); - renameClassMethod.setAccessible(true); - - for (AttributeInfo attribute : attributes) { - if (attribute instanceof SignatureAttribute) { - // this has to be handled specially because SignatureAttribute.renameClass() is buggy as hell - SignatureAttribute signatureAttribute = (SignatureAttribute)attribute; - String newSignature = type.rename(signatureAttribute.getSignature(), map); - if (newSignature != null) { - signatureAttribute.setSignature(newSignature); - } - } else if (attribute instanceof CodeAttribute) { - // code attributes have signature attributes too (indirectly) - CodeAttribute codeAttribute = (CodeAttribute)attribute; - renameAttributes(codeAttribute.getAttributes(), map, type); - } else if (attribute instanceof LocalVariableTypeAttribute) { - // lvt attributes have signature attributes too - LocalVariableTypeAttribute localVariableAttribute = (LocalVariableTypeAttribute)attribute; - renameLocalVariableTypeAttribute(localVariableAttribute, map); - } else { - renameClassMethod.invoke(attribute, map); - } - } - - } catch(NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { - throw new Error("Unable to call javassist methods by reflection!", ex); - } - } - - private static void renameLocalVariableTypeAttribute(LocalVariableTypeAttribute attribute, ReplacerClassMap map) { - - // adapted from LocalVariableAttribute.renameClass() - ConstPool cp = attribute.getConstPool(); - int n = attribute.tableLength(); - byte[] info = attribute.get(); - for (int i = 0; i < n; ++i) { - int pos = i * 10 + 2; - int index = ByteArray.readU16bit(info, pos + 6); - if (index != 0) { - String signature = cp.getUtf8Info(index); - String newSignature = renameLocalVariableSignature(signature, map); - if (newSignature != null) { - ByteArray.write16bit(cp.addUtf8Info(newSignature), info, pos + 6); - } - } - } - } - - private static String renameLocalVariableSignature(String signature, ReplacerClassMap map) { - - // for some reason, signatures with . in them don't count as field signatures - // looks like anonymous classes delimit with . in stead of $ - // convert the . to $, but keep track of how many we replace - // we need to put them back after we translate - int start = signature.lastIndexOf('$') + 1; - int numConverted = 0; - StringBuilder buf = new StringBuilder(signature); - for (int i=buf.length()-1; i>=start; i--) { - char c = buf.charAt(i); - if (c == '.') { - buf.setCharAt(i, '$'); - numConverted++; - } - } - signature = buf.toString(); - - // translate - String newSignature = renameFieldSignature(signature, map); - if (newSignature != null) { - - // put the delimiters back - buf = new StringBuilder(newSignature); - for (int i=buf.length()-1; i>=0 && numConverted > 0; i--) { - char c = buf.charAt(i); - if (c == '$') { - buf.setCharAt(i, '.'); - numConverted--; - } - } - assert(numConverted == 0); - newSignature = buf.toString(); - - return newSignature; - } - - return null; - } - - private static String renameClassSignature(String signature, ReplacerClassMap map) { - try { - ClassSignature type = renameType(SignatureAttribute.toClassSignature(signature), map); - if (type != null) { - return type.encode(); - } - return null; - } catch (BadBytecode ex) { - throw new Error("Can't parse field signature: " + signature); - } - } - - private static String renameFieldSignature(String signature, ReplacerClassMap map) { - try { - ObjectType type = renameType(SignatureAttribute.toFieldSignature(signature), map); - if (type != null) { - return type.encode(); - } - return null; - } catch (BadBytecode ex) { - throw new Error("Can't parse class signature: " + signature); - } - } - - private static String renameMethodSignature(String signature, ReplacerClassMap map) { - try { - MethodSignature type = renameType(SignatureAttribute.toMethodSignature(signature), map); - if (type != null) { - return type.encode(); - } - return null; - } catch (BadBytecode ex) { - throw new Error("Can't parse method signature: " + signature); - } - } - - private static ClassSignature renameType(ClassSignature type, ReplacerClassMap map) { - - TypeParameter[] typeParamTypes = type.getParameters(); - if (typeParamTypes != null) { - typeParamTypes = Arrays.copyOf(typeParamTypes, typeParamTypes.length); - for (int i=0; i m_constructorPool; - - static { - try { - m_getItem = ConstPool.class.getDeclaredMethod("getItem", int.class); - m_getItem.setAccessible(true); - - m_addItem = ConstPool.class.getDeclaredMethod("addItem", Class.forName("javassist.bytecode.ConstInfo")); - m_addItem.setAccessible(true); - - m_addItem0 = ConstPool.class.getDeclaredMethod("addItem0", Class.forName("javassist.bytecode.ConstInfo")); - m_addItem0.setAccessible(true); - - m_items = ConstPool.class.getDeclaredField("items"); - m_items.setAccessible(true); - - m_cache = ConstPool.class.getDeclaredField("itemsCache"); - m_cache.setAccessible(true); - - m_numItems = ConstPool.class.getDeclaredField("numOfItems"); - m_numItems.setAccessible(true); - - m_objects = Class.forName("javassist.bytecode.LongVector").getDeclaredField("objects"); - m_objects.setAccessible(true); - - m_elements = Class.forName("javassist.bytecode.LongVector").getDeclaredField("elements"); - m_elements.setAccessible(true); - - m_methodWritePool = ConstPool.class.getDeclaredMethod("write", DataOutputStream.class); - m_methodWritePool.setAccessible(true); - - m_constructorPool = ConstPool.class.getDeclaredConstructor(DataInputStream.class); - m_constructorPool.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - private ConstPool m_pool; - - public ConstPoolEditor(ConstPool pool) { - m_pool = pool; - } - - public void writePool(DataOutputStream out) { - try { - m_methodWritePool.invoke(m_pool, out); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static ConstPool readPool(DataInputStream in) { - try { - return m_constructorPool.newInstance(in); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public String getMemberrefClassname(int memberrefIndex) { - return Descriptor.toJvmName(m_pool.getClassInfo(m_pool.getMemberClass(memberrefIndex))); - } - - public String getMemberrefName(int memberrefIndex) { - return m_pool.getUtf8Info(m_pool.getNameAndTypeName(m_pool.getMemberNameAndType(memberrefIndex))); - } - - public String getMemberrefType(int memberrefIndex) { - return m_pool.getUtf8Info(m_pool.getNameAndTypeDescriptor(m_pool.getMemberNameAndType(memberrefIndex))); - } - - public ConstInfoAccessor getItem(int index) { - try { - Object entry = m_getItem.invoke(m_pool, index); - if (entry == null) { - return null; - } - return new ConstInfoAccessor(entry); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int addItem(Object item) { - try { - return (Integer)m_addItem.invoke(m_pool, item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int addItemForceNew(Object item) { - try { - return (Integer)m_addItem0.invoke(m_pool, item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - @SuppressWarnings("rawtypes") - public void removeLastItem() { - try { - // remove the item from the cache - HashMap cache = getCache(); - if (cache != null) { - Object item = getItem(m_pool.getSize() - 1); - cache.remove(item); - } - - // remove the actual item - // based off of LongVector.addElement() - Object items = m_items.get(m_pool); - Object[][] objects = (Object[][])m_objects.get(items); - int numElements = (Integer)m_elements.get(items) - 1; - int nth = numElements >> 7; - int offset = numElements & (128 - 1); - objects[nth][offset] = null; - - // decrement the number of items - m_elements.set(items, numElements); - m_numItems.set(m_pool, (Integer)m_numItems.get(m_pool) - 1); - } catch (Exception ex) { - throw new Error(ex); - } - } - - @SuppressWarnings("rawtypes") - public HashMap getCache() { - try { - return (HashMap)m_cache.get(m_pool); - } catch (Exception ex) { - throw new Error(ex); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void changeMemberrefNameAndType(int memberrefIndex, String newName, String newType) { - // NOTE: when changing values, we always need to copy-on-write - try { - // get the memberref item - Object item = getItem(memberrefIndex).getItem(); - - // update the cache - HashMap cache = getCache(); - if (cache != null) { - cache.remove(item); - } - - new MemberRefInfoAccessor(item).setNameAndTypeIndex(m_pool.addNameAndTypeInfo(newName, newType)); - - // update the cache - if (cache != null) { - cache.put(item, item); - } - } catch (Exception ex) { - throw new Error(ex); - } - - // make sure the change worked - assert (newName.equals(getMemberrefName(memberrefIndex))); - assert (newType.equals(getMemberrefType(memberrefIndex))); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void changeClassName(int classNameIndex, String newName) { - // NOTE: when changing values, we always need to copy-on-write - try { - // get the class item - Object item = getItem(classNameIndex).getItem(); - - // update the cache - HashMap cache = getCache(); - if (cache != null) { - cache.remove(item); - } - - // add the new name and repoint the name-and-type to it - new ClassInfoAccessor(item).setNameIndex(m_pool.addUtf8Info(newName)); - - // update the cache - if (cache != null) { - cache.put(item, item); - } - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static ConstPool newConstPool() { - // const pool expects the name of a class to initialize itself - // but we want an empty pool - // so give it a bogus name, and then clear the entries afterwards - ConstPool pool = new ConstPool("a"); - - ConstPoolEditor editor = new ConstPoolEditor(pool); - int size = pool.getSize(); - for (int i = 0; i < size - 1; i++) { - editor.removeLastItem(); - } - - // make sure the pool is actually empty - // although, in this case "empty" means one thing in it - // the JVM spec says index 0 should be reserved - assert (pool.getSize() == 1); - assert (editor.getItem(0) == null); - assert (editor.getItem(1) == null); - assert (editor.getItem(2) == null); - assert (editor.getItem(3) == null); - - // also, clear the cache - editor.getCache().clear(); - - return pool; - } - - public String dump() { - StringBuilder buf = new StringBuilder(); - for (int i = 1; i < m_pool.getSize(); i++) { - buf.append(String.format("%4d", i)); - buf.append(" "); - buf.append(getItem(i).toString()); - buf.append("\n"); - } - return buf.toString(); - } -} diff --git a/src/cuchaz/enigma/bytecode/InfoType.java b/src/cuchaz/enigma/bytecode/InfoType.java deleted file mode 100644 index 08f2b3e..0000000 --- a/src/cuchaz/enigma/bytecode/InfoType.java +++ /dev/null @@ -1,317 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import cuchaz.enigma.bytecode.accessors.ClassInfoAccessor; -import cuchaz.enigma.bytecode.accessors.ConstInfoAccessor; -import cuchaz.enigma.bytecode.accessors.InvokeDynamicInfoAccessor; -import cuchaz.enigma.bytecode.accessors.MemberRefInfoAccessor; -import cuchaz.enigma.bytecode.accessors.MethodHandleInfoAccessor; -import cuchaz.enigma.bytecode.accessors.MethodTypeInfoAccessor; -import cuchaz.enigma.bytecode.accessors.NameAndTypeInfoAccessor; -import cuchaz.enigma.bytecode.accessors.StringInfoAccessor; - -public enum InfoType { - - Utf8Info( 1, 0 ), - IntegerInfo( 3, 0 ), - FloatInfo( 4, 0 ), - LongInfo( 5, 0 ), - DoubleInfo( 6, 0 ), - ClassInfo( 7, 1 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - ClassInfoAccessor accessor = new ClassInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getNameIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - ClassInfoAccessor accessor = new ClassInfoAccessor(entry.getItem()); - accessor.setNameIndex(remapIndex(map, accessor.getNameIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - ClassInfoAccessor accessor = new ClassInfoAccessor(entry.getItem()); - ConstInfoAccessor nameEntry = pool.getItem(accessor.getNameIndex()); - return nameEntry != null && nameEntry.getTag() == Utf8Info.getTag(); - } - }, - StringInfo( 8, 1 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - StringInfoAccessor accessor = new StringInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getStringIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - StringInfoAccessor accessor = new StringInfoAccessor(entry.getItem()); - accessor.setStringIndex(remapIndex(map, accessor.getStringIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - StringInfoAccessor accessor = new StringInfoAccessor(entry.getItem()); - ConstInfoAccessor stringEntry = pool.getItem(accessor.getStringIndex()); - return stringEntry != null && stringEntry.getTag() == Utf8Info.getTag(); - } - }, - FieldRefInfo( 9, 2 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - MemberRefInfoAccessor accessor = new MemberRefInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getClassIndex()); - gatherIndexTree(indices, editor, accessor.getNameAndTypeIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - MemberRefInfoAccessor accessor = new MemberRefInfoAccessor(entry.getItem()); - accessor.setClassIndex(remapIndex(map, accessor.getClassIndex())); - accessor.setNameAndTypeIndex(remapIndex(map, accessor.getNameAndTypeIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - MemberRefInfoAccessor accessor = new MemberRefInfoAccessor(entry.getItem()); - ConstInfoAccessor classEntry = pool.getItem(accessor.getClassIndex()); - ConstInfoAccessor nameAndTypeEntry = pool.getItem(accessor.getNameAndTypeIndex()); - return classEntry != null && classEntry.getTag() == ClassInfo.getTag() && nameAndTypeEntry != null && nameAndTypeEntry.getTag() == NameAndTypeInfo.getTag(); - } - }, - // same as FieldRefInfo - MethodRefInfo( 10, 2 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - FieldRefInfo.gatherIndexTree(indices, editor, entry); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - FieldRefInfo.remapIndices(map, entry); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - return FieldRefInfo.subIndicesAreValid(entry, pool); - } - }, - // same as FieldRefInfo - InterfaceMethodRefInfo( 11, 2 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - FieldRefInfo.gatherIndexTree(indices, editor, entry); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - FieldRefInfo.remapIndices(map, entry); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - return FieldRefInfo.subIndicesAreValid(entry, pool); - } - }, - NameAndTypeInfo( 12, 1 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getNameIndex()); - gatherIndexTree(indices, editor, accessor.getTypeIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor(entry.getItem()); - accessor.setNameIndex(remapIndex(map, accessor.getNameIndex())); - accessor.setTypeIndex(remapIndex(map, accessor.getTypeIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - NameAndTypeInfoAccessor accessor = new NameAndTypeInfoAccessor(entry.getItem()); - ConstInfoAccessor nameEntry = pool.getItem(accessor.getNameIndex()); - ConstInfoAccessor typeEntry = pool.getItem(accessor.getTypeIndex()); - return nameEntry != null && nameEntry.getTag() == Utf8Info.getTag() && typeEntry != null && typeEntry.getTag() == Utf8Info.getTag(); - } - }, - MethodHandleInfo( 15, 3 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getTypeIndex()); - gatherIndexTree(indices, editor, accessor.getMethodRefIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor(entry.getItem()); - accessor.setTypeIndex(remapIndex(map, accessor.getTypeIndex())); - accessor.setMethodRefIndex(remapIndex(map, accessor.getMethodRefIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - MethodHandleInfoAccessor accessor = new MethodHandleInfoAccessor(entry.getItem()); - ConstInfoAccessor typeEntry = pool.getItem(accessor.getTypeIndex()); - ConstInfoAccessor methodRefEntry = pool.getItem(accessor.getMethodRefIndex()); - return typeEntry != null && typeEntry.getTag() == Utf8Info.getTag() && methodRefEntry != null && methodRefEntry.getTag() == MethodRefInfo.getTag(); - } - }, - MethodTypeInfo( 16, 1 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getTypeIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor(entry.getItem()); - accessor.setTypeIndex(remapIndex(map, accessor.getTypeIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - MethodTypeInfoAccessor accessor = new MethodTypeInfoAccessor(entry.getItem()); - ConstInfoAccessor typeEntry = pool.getItem(accessor.getTypeIndex()); - return typeEntry != null && typeEntry.getTag() == Utf8Info.getTag(); - } - }, - InvokeDynamicInfo( 18, 2 ) { - - @Override - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor(entry.getItem()); - gatherIndexTree(indices, editor, accessor.getBootstrapIndex()); - gatherIndexTree(indices, editor, accessor.getNameAndTypeIndex()); - } - - @Override - public void remapIndices(Map map, ConstInfoAccessor entry) { - InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor(entry.getItem()); - accessor.setBootstrapIndex(remapIndex(map, accessor.getBootstrapIndex())); - accessor.setNameAndTypeIndex(remapIndex(map, accessor.getNameAndTypeIndex())); - } - - @Override - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - InvokeDynamicInfoAccessor accessor = new InvokeDynamicInfoAccessor(entry.getItem()); - ConstInfoAccessor bootstrapEntry = pool.getItem(accessor.getBootstrapIndex()); - ConstInfoAccessor nameAndTypeEntry = pool.getItem(accessor.getNameAndTypeIndex()); - return bootstrapEntry != null && bootstrapEntry.getTag() == Utf8Info.getTag() && nameAndTypeEntry != null && nameAndTypeEntry.getTag() == NameAndTypeInfo.getTag(); - } - }; - - private static Map m_types; - - static { - m_types = Maps.newTreeMap(); - for (InfoType type : values()) { - m_types.put(type.getTag(), type); - } - } - - private int m_tag; - private int m_level; - - private InfoType(int tag, int level) { - m_tag = tag; - m_level = level; - } - - public int getTag() { - return m_tag; - } - - public int getLevel() { - return m_level; - } - - public void gatherIndexTree(Collection indices, ConstPoolEditor editor, ConstInfoAccessor entry) { - // by default, do nothing - } - - public void remapIndices(Map map, ConstInfoAccessor entry) { - // by default, do nothing - } - - public boolean subIndicesAreValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - // by default, everything is good - return true; - } - - public boolean selfIndexIsValid(ConstInfoAccessor entry, ConstPoolEditor pool) { - ConstInfoAccessor entryCheck = pool.getItem(entry.getIndex()); - if (entryCheck == null) { - return false; - } - return entryCheck.getItem().equals(entry.getItem()); - } - - public static InfoType getByTag(int tag) { - return m_types.get(tag); - } - - public static List getByLevel(int level) { - List types = Lists.newArrayList(); - for (InfoType type : values()) { - if (type.getLevel() == level) { - types.add(type); - } - } - return types; - } - - public static List getSortedByLevel() { - List types = Lists.newArrayList(); - types.addAll(getByLevel(0)); - types.addAll(getByLevel(1)); - types.addAll(getByLevel(2)); - types.addAll(getByLevel(3)); - return types; - } - - public static void gatherIndexTree(Collection indices, ConstPoolEditor editor, int index) { - // add own index - indices.add(index); - - // recurse - ConstInfoAccessor entry = editor.getItem(index); - entry.getType().gatherIndexTree(indices, editor, entry); - } - - private static int remapIndex(Map map, int index) { - Integer newIndex = map.get(index); - if (newIndex == null) { - newIndex = index; - } - return newIndex; - } -} diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java deleted file mode 100644 index bdb1b5d..0000000 --- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode; - -import java.util.Collection; -import java.util.List; - -import com.google.common.collect.Lists; - -import javassist.CtClass; -import javassist.bytecode.AccessFlag; -import javassist.bytecode.ConstPool; -import javassist.bytecode.EnclosingMethodAttribute; -import javassist.bytecode.InnerClassesAttribute; -import cuchaz.enigma.analysis.JarIndex; -import cuchaz.enigma.mapping.BehaviorEntry; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.EntryFactory; - -public class InnerClassWriter { - - private JarIndex m_index; - - public InnerClassWriter(JarIndex index) { - m_index = index; - } - - public void write(CtClass c) { - - // don't change anything if there's already an attribute there - InnerClassesAttribute oldAttr = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); - if (oldAttr != null) { - // bail! - return; - } - - ClassEntry obfClassEntry = EntryFactory.getClassEntry(c); - List obfClassChain = m_index.getObfClassChain(obfClassEntry); - - boolean isInnerClass = obfClassChain.size() > 1; - if (isInnerClass) { - - // it's an inner class, rename it to the fully qualified name - c.setName(obfClassEntry.buildClassEntry(obfClassChain).getName()); - - BehaviorEntry caller = m_index.getAnonymousClassCaller(obfClassEntry); - if (caller != null) { - - // write the enclosing method attribute - if (caller.getName().equals("")) { - c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName())); - } else { - c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName(), caller.getName(), caller.getSignature().toString())); - } - } - } - - // does this class have any inner classes? - Collection obfInnerClassEntries = m_index.getInnerClasses(obfClassEntry); - - if (isInnerClass || !obfInnerClassEntries.isEmpty()) { - - // create an inner class attribute - InnerClassesAttribute attr = new InnerClassesAttribute(c.getClassFile().getConstPool()); - c.getClassFile().addAttribute(attr); - - // write the ancestry, but not the outermost class - for (int i=1; i extendedObfClassChain = Lists.newArrayList(obfClassChain); - extendedObfClassChain.add(obfInnerClassEntry); - - writeInnerClass(attr, extendedObfClassChain, obfInnerClassEntry); - - // update references to use the fully qualified inner class name - c.replaceClassName(obfInnerClassEntry.getName(), obfInnerClassEntry.buildClassEntry(extendedObfClassChain).getName()); - } - } - } - - private void writeInnerClass(InnerClassesAttribute attr, List obfClassChain, ClassEntry obfClassEntry) { - - // get the new inner class name - ClassEntry obfInnerClassEntry = obfClassEntry.buildClassEntry(obfClassChain); - ClassEntry obfOuterClassEntry = obfInnerClassEntry.getOuterClassEntry(); - - // here's what the JVM spec says about the InnerClasses attribute - // append(inner, parent, 0 if anonymous else simple name, flags); - - // update the attribute with this inner class - ConstPool constPool = attr.getConstPool(); - int innerClassIndex = constPool.addClassInfo(obfInnerClassEntry.getName()); - int parentClassIndex = constPool.addClassInfo(obfOuterClassEntry.getName()); - int innerClassNameIndex = 0; - int accessFlags = AccessFlag.PUBLIC; - // TODO: need to figure out if we can put static or not - if (!m_index.isAnonymousClass(obfClassEntry)) { - innerClassNameIndex = constPool.addUtf8Info(obfInnerClassEntry.getInnermostClassName()); - } - - attr.append(innerClassIndex, parentClassIndex, innerClassNameIndex, accessFlags); - - /* DEBUG - System.out.println(String.format("\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)", - obfClassEntry, - attr.innerClass(attr.tableLength() - 1), - attr.outerClass(attr.tableLength() - 1), - attr.innerName(attr.tableLength() - 1), - Constants.NonePackage + "/" + obfInnerClassName, - obfClassEntry.getName() - )); - */ - } -} diff --git a/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java b/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java deleted file mode 100644 index ae0455f..0000000 --- a/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode; - -import javassist.CtBehavior; -import javassist.CtClass; -import javassist.bytecode.ByteArray; -import javassist.bytecode.CodeAttribute; -import javassist.bytecode.ConstPool; -import javassist.bytecode.LocalVariableAttribute; -import javassist.bytecode.LocalVariableTypeAttribute; -import cuchaz.enigma.mapping.ArgumentEntry; -import cuchaz.enigma.mapping.BehaviorEntry; -import cuchaz.enigma.mapping.EntryFactory; -import cuchaz.enigma.mapping.Translator; - - -public class LocalVariableRenamer { - - private Translator m_translator; - - public LocalVariableRenamer(Translator translator) { - m_translator = translator; - } - - public void rename(CtClass c) { - for (CtBehavior behavior : c.getDeclaredBehaviors()) { - - // if there's a local variable table, just rename everything to v1, v2, v3, ... for now - CodeAttribute codeAttribute = behavior.getMethodInfo().getCodeAttribute(); - if (codeAttribute == null) { - continue; - } - - BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior); - ConstPool constants = c.getClassFile().getConstPool(); - - LocalVariableAttribute table = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag); - if (table != null) { - renameLVT(behaviorEntry, constants, table); - } - - LocalVariableTypeAttribute typeTable = (LocalVariableTypeAttribute)codeAttribute.getAttribute(LocalVariableAttribute.typeTag); - if (typeTable != null) { - renameLVTT(typeTable, table); - } - } - } - - // DEBUG - @SuppressWarnings("unused") - private void dumpTable(LocalVariableAttribute table) { - for (int i=0; i names = new ArrayList(numParams); - for (int i = 0; i < numParams; i++) { - names.add(m_translator.translate(new ArgumentEntry(behaviorEntry, i, ""))); - } - - // save the mappings to the class - MethodParametersAttribute.updateClass(behavior.getMethodInfo(), names); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java deleted file mode 100644 index 512e65a..0000000 --- a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javassist.bytecode.AttributeInfo; -import javassist.bytecode.ConstPool; -import javassist.bytecode.MethodInfo; - -public class MethodParametersAttribute extends AttributeInfo { - - private MethodParametersAttribute(ConstPool pool, List parameterNameIndices) { - super(pool, "MethodParameters", writeStruct(parameterNameIndices)); - } - - public static void updateClass(MethodInfo info, List names) { - - // add the names to the class const pool - ConstPool constPool = info.getConstPool(); - List parameterNameIndices = new ArrayList(); - for (String name : names) { - if (name != null) { - parameterNameIndices.add(constPool.addUtf8Info(name)); - } else { - parameterNameIndices.add(0); - } - } - - // add the attribute to the method - info.addAttribute(new MethodParametersAttribute(constPool, parameterNameIndices)); - } - - private static byte[] writeStruct(List parameterNameIndices) { - // JVM 8 Spec says the struct looks like this: - // http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24 - // uint8 num_params - // for each param: - // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry - // uint16 access_flags -> don't care, just set to 0 - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(buf); - - // NOTE: java hates unsigned integers, so we have to be careful here - // the writeShort(), writeByte() methods will read 16,8 low-order bits from the int argument - // as long as the int argument is in range of the unsigned short/byte type, it will be written as an unsigned short/byte - // if the int is out of range, the byte stream won't look the way we want and weird things will happen - final int SIZEOF_UINT8 = 1; - final int SIZEOF_UINT16 = 2; - final int MAX_UINT8 = (1 << 8) - 1; - final int MAX_UINT16 = (1 << 16) - 1; - - try { - assert (parameterNameIndices.size() >= 0 && parameterNameIndices.size() <= MAX_UINT8); - out.writeByte(parameterNameIndices.size()); - - for (Integer index : parameterNameIndices) { - assert (index >= 0 && index <= MAX_UINT16); - out.writeShort(index); - - // just write 0 for the access flags - out.writeShort(0); - } - - out.close(); - byte[] data = buf.toByteArray(); - assert (data.length == SIZEOF_UINT8 + parameterNameIndices.size() * (SIZEOF_UINT16 + SIZEOF_UINT16)); - return data; - } catch (IOException ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java deleted file mode 100644 index 9072c29..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class ClassInfoAccessor { - - private static Class m_class; - private static Field m_nameIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.ClassInfo"); - m_nameIndex = m_class.getDeclaredField("name"); - m_nameIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public ClassInfoAccessor(Object item) { - m_item = item; - } - - public int getNameIndex() { - try { - return (Integer)m_nameIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setNameIndex(int val) { - try { - m_nameIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java deleted file mode 100644 index ede0473..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import cuchaz.enigma.bytecode.InfoType; - -public class ConstInfoAccessor { - - private static Class m_class; - private static Field m_index; - private static Method m_getTag; - - static { - try { - m_class = Class.forName("javassist.bytecode.ConstInfo"); - m_index = m_class.getDeclaredField("index"); - m_index.setAccessible(true); - m_getTag = m_class.getMethod("getTag"); - m_getTag.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - private Object m_item; - - public ConstInfoAccessor(Object item) { - if (item == null) { - throw new IllegalArgumentException("item cannot be null!"); - } - m_item = item; - } - - public ConstInfoAccessor(DataInputStream in) throws IOException { - try { - // read the entry - String className = in.readUTF(); - int oldIndex = in.readInt(); - - // NOTE: ConstInfo instances write a type id (a "tag"), but they don't read it back - // so we have to read it here - in.readByte(); - - Constructor constructor = Class.forName(className).getConstructor(DataInputStream.class, int.class); - constructor.setAccessible(true); - m_item = constructor.newInstance(in, oldIndex); - } catch (IOException ex) { - throw ex; - } catch (Exception ex) { - throw new Error(ex); - } - } - - public Object getItem() { - return m_item; - } - - public int getIndex() { - try { - return (Integer)m_index.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setIndex(int val) { - try { - m_index.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int getTag() { - try { - return (Integer)m_getTag.invoke(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public ConstInfoAccessor copy() { - return new ConstInfoAccessor(copyItem()); - } - - public Object copyItem() { - // I don't know of a simpler way to copy one of these silly things... - try { - // serialize the item - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(buf); - write(out); - - // deserialize the item - DataInputStream in = new DataInputStream(new ByteArrayInputStream(buf.toByteArray())); - Object item = new ConstInfoAccessor(in).getItem(); - in.close(); - - return item; - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void write(DataOutputStream out) throws IOException { - try { - out.writeUTF(m_item.getClass().getName()); - out.writeInt(getIndex()); - - Method method = m_item.getClass().getMethod("write", DataOutputStream.class); - method.setAccessible(true); - method.invoke(m_item, out); - } catch (IOException ex) { - throw ex; - } catch (Exception ex) { - throw new Error(ex); - } - } - - @Override - public String toString() { - try { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - PrintWriter out = new PrintWriter(buf); - Method print = m_item.getClass().getMethod("print", PrintWriter.class); - print.setAccessible(true); - print.invoke(m_item, out); - out.close(); - return buf.toString().replace("\n", ""); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public InfoType getType() { - return InfoType.getByTag(getTag()); - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java deleted file mode 100644 index 82af0b9..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class InvokeDynamicInfoAccessor { - - private static Class m_class; - private static Field m_bootstrapIndex; - private static Field m_nameAndTypeIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.InvokeDynamicInfo"); - m_bootstrapIndex = m_class.getDeclaredField("bootstrap"); - m_bootstrapIndex.setAccessible(true); - m_nameAndTypeIndex = m_class.getDeclaredField("nameAndType"); - m_nameAndTypeIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public InvokeDynamicInfoAccessor(Object item) { - m_item = item; - } - - public int getBootstrapIndex() { - try { - return (Integer)m_bootstrapIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setBootstrapIndex(int val) { - try { - m_bootstrapIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int getNameAndTypeIndex() { - try { - return (Integer)m_nameAndTypeIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setNameAndTypeIndex(int val) { - try { - m_nameAndTypeIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java deleted file mode 100644 index 71ee5b7..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class MemberRefInfoAccessor { - - private static Class m_class; - private static Field m_classIndex; - private static Field m_nameAndTypeIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.MemberrefInfo"); - m_classIndex = m_class.getDeclaredField("classIndex"); - m_classIndex.setAccessible(true); - m_nameAndTypeIndex = m_class.getDeclaredField("nameAndTypeIndex"); - m_nameAndTypeIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public MemberRefInfoAccessor(Object item) { - m_item = item; - } - - public int getClassIndex() { - try { - return (Integer)m_classIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setClassIndex(int val) { - try { - m_classIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int getNameAndTypeIndex() { - try { - return (Integer)m_nameAndTypeIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setNameAndTypeIndex(int val) { - try { - m_nameAndTypeIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java deleted file mode 100644 index 172b0c5..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class MethodHandleInfoAccessor { - - private static Class m_class; - private static Field m_kindIndex; - private static Field m_indexIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.MethodHandleInfo"); - m_kindIndex = m_class.getDeclaredField("refKind"); - m_kindIndex.setAccessible(true); - m_indexIndex = m_class.getDeclaredField("refIndex"); - m_indexIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public MethodHandleInfoAccessor(Object item) { - m_item = item; - } - - public int getTypeIndex() { - try { - return (Integer)m_kindIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setTypeIndex(int val) { - try { - m_kindIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int getMethodRefIndex() { - try { - return (Integer)m_indexIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setMethodRefIndex(int val) { - try { - m_indexIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java deleted file mode 100644 index 0099a84..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class MethodTypeInfoAccessor { - - private static Class m_class; - private static Field m_descriptorIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.MethodTypeInfo"); - m_descriptorIndex = m_class.getDeclaredField("descriptor"); - m_descriptorIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public MethodTypeInfoAccessor(Object item) { - m_item = item; - } - - public int getTypeIndex() { - try { - return (Integer)m_descriptorIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setTypeIndex(int val) { - try { - m_descriptorIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java deleted file mode 100644 index 3ecc129..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class NameAndTypeInfoAccessor { - - private static Class m_class; - private static Field m_nameIndex; - private static Field m_typeIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.NameAndTypeInfo"); - m_nameIndex = m_class.getDeclaredField("memberName"); - m_nameIndex.setAccessible(true); - m_typeIndex = m_class.getDeclaredField("typeDescriptor"); - m_typeIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public NameAndTypeInfoAccessor(Object item) { - m_item = item; - } - - public int getNameIndex() { - try { - return (Integer)m_nameIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setNameIndex(int val) { - try { - m_nameIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public int getTypeIndex() { - try { - return (Integer)m_typeIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setTypeIndex(int val) { - try { - m_typeIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java deleted file mode 100644 index f150612..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -import java.lang.reflect.Field; - -public class StringInfoAccessor { - - private static Class m_class; - private static Field m_stringIndex; - - static { - try { - m_class = Class.forName("javassist.bytecode.StringInfo"); - m_stringIndex = m_class.getDeclaredField("string"); - m_stringIndex.setAccessible(true); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } - - private Object m_item; - - public StringInfoAccessor(Object item) { - m_item = item; - } - - public int getStringIndex() { - try { - return (Integer)m_stringIndex.get(m_item); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public void setStringIndex(int val) { - try { - m_stringIndex.set(m_item, val); - } catch (Exception ex) { - throw new Error(ex); - } - } -} diff --git a/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java deleted file mode 100644 index 38e8ff9..0000000 --- a/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.bytecode.accessors; - -public class Utf8InfoAccessor { - - private static Class m_class; - - static { - try { - m_class = Class.forName("javassist.bytecode.Utf8Info"); - } catch (Exception ex) { - throw new Error(ex); - } - } - - public static boolean isType(ConstInfoAccessor accessor) { - return m_class.isAssignableFrom(accessor.getItem().getClass()); - } -} -- cgit v1.2.3