From 227ccb35a48529724ecf28c94a9156af2f699481 Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Sat, 19 May 2018 20:00:12 +0200 Subject: More bytecode translation --- .../translators/TranslationAnnotationVisitor.java | 13 +-- .../translators/TranslationClassVisitor.java | 26 ++--- .../translators/TranslationMethodVisitor.java | 81 ++++++++++++-- .../translators/TranslationSignatureVisitor.java | 122 +++++++++++++++++++++ 4 files changed, 208 insertions(+), 34 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java (limited to 'src/main/java/cuchaz/enigma/bytecode') diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java index 177691b..7cc3771 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationAnnotationVisitor.java @@ -6,7 +6,6 @@ import cuchaz.enigma.mapping.TypeDescriptor; import cuchaz.enigma.mapping.entry.ClassEntry; import cuchaz.enigma.mapping.entry.FieldDefEntry; import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Type; public class TranslationAnnotationVisitor extends AnnotationVisitor { private final Translator translator; @@ -20,12 +19,12 @@ public class TranslationAnnotationVisitor extends AnnotationVisitor { @Override public void visit(String name, Object value) { - if (value instanceof Type) { - Type type = (Type) value; - super.visit(name, translator.getTranslatedType(type)); - } else { - super.visit(name, value); - } + super.visit(name, translator.getTranslatedValue(value)); + } + + @Override + public AnnotationVisitor visitArray(String name) { + return this; } @Override diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java index dcc221e..89772db 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationClassVisitor.java @@ -19,11 +19,7 @@ import cuchaz.enigma.mapping.TypeDescriptor; import cuchaz.enigma.mapping.entry.*; import org.objectweb.asm.*; -import java.util.regex.Pattern; - public class TranslationClassVisitor extends ClassVisitor { - private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*"); - private final Translator translator; private final JarIndex jarIndex; private final ReferencedEntryPool entryPool; @@ -39,9 +35,6 @@ public class TranslationClassVisitor extends ClassVisitor { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - if (signature != null && OBJECT_PATTERN.matcher(signature).matches()) { - signature = signature.replaceAll(":Ljava/lang/Object;:", "::"); - } obfClassEntry = new ClassDefEntry(name, new AccessFlags(access)); ClassDefEntry entry = translator.getTranslatedClassDef(obfClassEntry); ClassEntry superEntry = translator.getTranslatedClass(entryPool.getClass(superName)); @@ -49,14 +42,16 @@ public class TranslationClassVisitor extends ClassVisitor { for (int i = 0; i < interfaces.length; i++) { translatedInterfaces[i] = translator.getTranslatedClass(entryPool.getClass(interfaces[i])).getName(); } - super.visit(version, entry.getAccess().getFlags(), entry.getName(), signature, superEntry.getName(), translatedInterfaces); + String translatedSignature = translator.getTranslatedSignature(signature, false, api); + super.visit(version, entry.getAccess().getFlags(), entry.getName(), translatedSignature, superEntry.getName(), translatedInterfaces); } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { FieldDefEntry entry = new FieldDefEntry(obfClassEntry, name, new TypeDescriptor(desc), new AccessFlags(access)); FieldDefEntry translatedEntry = translator.getTranslatedFieldDef(entry); - FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, value); + String translatedSignature = translator.getTranslatedSignature(signature, true, api); + FieldVisitor fv = super.visitField(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedSignature, value); return new TranslationFieldVisitor(translator, translatedEntry, api, fv); } @@ -71,19 +66,18 @@ public class TranslationClassVisitor extends ClassVisitor { for (int i = 0; i < exceptions.length; i++) { translatedExceptions[i] = translator.getTranslatedClass(entryPool.getClass(exceptions[i])).getName(); } - MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), signature, translatedExceptions); + String translatedSignature = translator.getTranslatedSignature(signature, false, api); + MethodVisitor mv = super.visitMethod(translatedEntry.getAccess().getFlags(), translatedEntry.getName(), translatedEntry.getDesc().toString(), translatedSignature, translatedExceptions); return new TranslationMethodVisitor(translator, translatedEntry, api, mv); } @Override public void visitOuterClass(String owner, String name, String desc) { - ClassEntry ownerEntry = translator.getTranslatedClass(entryPool.getClass(owner)); - String translatedDesc = desc != null ? translator.getTranslatedTypeDesc(new TypeDescriptor(desc)).toString() : desc; - if (name != null) { - ClassEntry entry = translator.getTranslatedClass(entryPool.getClass(name)); - super.visitOuterClass(ownerEntry.getName(), entry.getName(), translatedDesc); + if (desc != null) { + MethodEntry translatedEntry = translator.getTranslatedMethod(new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc))); + super.visitOuterClass(translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString()); } else { - super.visitOuterClass(ownerEntry.getName(), name, translatedDesc); + super.visitOuterClass(owner, name, desc); } } diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java index c729962..cce91db 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationMethodVisitor.java @@ -1,6 +1,8 @@ package cuchaz.enigma.bytecode.translators; -import cuchaz.enigma.mapping.*; +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.Translator; +import cuchaz.enigma.mapping.TypeDescriptor; import cuchaz.enigma.mapping.entry.*; import org.objectweb.asm.*; @@ -20,22 +22,35 @@ public class TranslationMethodVisitor extends MethodVisitor { public void visitFieldInsn(int opcode, String owner, String name, String desc) { FieldEntry entry = new FieldEntry(new ClassEntry(owner), name, new TypeDescriptor(desc)); FieldEntry translatedEntry = translator.getTranslatedField(entry); - if (translatedEntry != null) { - super.visitFieldInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString()); - } else { - super.visitFieldInsn(opcode, owner, name, desc); - } + super.visitFieldInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString()); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { MethodEntry entry = new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc)); MethodEntry translatedEntry = translator.getTranslatedMethod(entry); - if (translatedEntry != null) { - super.visitMethodInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString(), itf); - } else { - super.visitMethodInsn(opcode, owner, name, desc, itf); + super.visitMethodInsn(opcode, translatedEntry.getClassName(), translatedEntry.getName(), translatedEntry.getDesc().toString(), itf); + } + + @Override + public void visitFrame(int type, int localCount, Object[] locals, int stackCount, Object[] stack) { + Object[] translatedLocals = this.getTranslatedFrame(locals, localCount); + Object[] translatedStack = this.getTranslatedFrame(stack, stackCount); + super.visitFrame(type, localCount, translatedLocals, stackCount, translatedStack); + } + + private Object[] getTranslatedFrame(Object[] array, int count) { + if (array == null) { + return null; } + for (int i = 0; i < count; i++) { + Object object = array[i]; + if (object instanceof String) { + ClassEntry entry = new ClassEntry((String) object); + array[i] = translator.getTranslatedClass(entry).getName(); + } + } + return array; } @Override @@ -45,6 +60,13 @@ public class TranslationMethodVisitor extends MethodVisitor { return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av); } + @Override + public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { + TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc)); + AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible); + return new TranslationAnnotationVisitor(translator, typeDesc.getTypeEntry(), api, av); + } + @Override public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { TypeDescriptor typeDesc = translator.getTranslatedTypeDesc(new TypeDescriptor(desc)); @@ -80,6 +102,43 @@ public class TranslationMethodVisitor extends MethodVisitor { } translatedName = nameBuilder.toString(); } - super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), signature, start, end, index); + String translatedSignature = translator.getTranslatedSignature(signature, true, api); + super.visitLocalVariable(translatedName, translatedEntry.getDesc().toString(), translatedSignature, start, end, index); + } + + @Override + public void visitTypeInsn(int opcode, String type) { + ClassEntry translatedEntry = translator.getTranslatedClass(new ClassEntry(type)); + super.visitTypeInsn(opcode, translatedEntry.getName()); + } + + @Override + public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { + MethodDescriptor translatedMethodDesc = translator.getTranslatedMethodDesc(new MethodDescriptor(desc)); + Object[] translatedBsmArgs = new Object[bsmArgs.length]; + for (int i = 0; i < bsmArgs.length; i++) { + translatedBsmArgs[i] = translator.getTranslatedValue(bsmArgs[i]); + } + super.visitInvokeDynamicInsn(name, translatedMethodDesc.toString(), translator.getTranslatedHandle(bsm), translatedBsmArgs); + } + + @Override + public void visitLdcInsn(Object cst) { + super.visitLdcInsn(translator.getTranslatedValue(cst)); + } + + @Override + public void visitMultiANewArrayInsn(String desc, int dims) { + super.visitMultiANewArrayInsn(translator.getTranslatedTypeDesc(new TypeDescriptor(desc)).toString(), dims); + } + + @Override + public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { + if (type != null) { + ClassEntry translatedEntry = translator.getTranslatedClass(new ClassEntry(type)); + super.visitTryCatchBlock(start, end, handler, translatedEntry.getName()); + } else { + super.visitTryCatchBlock(start, end, handler, type); + } } } diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java new file mode 100644 index 0000000..e1dcea5 --- /dev/null +++ b/src/main/java/cuchaz/enigma/bytecode/translators/TranslationSignatureVisitor.java @@ -0,0 +1,122 @@ +package cuchaz.enigma.bytecode.translators; + +import cuchaz.enigma.mapping.Translator; +import cuchaz.enigma.mapping.entry.ClassEntry; +import org.objectweb.asm.signature.SignatureVisitor; + +import java.util.Stack; + +public class TranslationSignatureVisitor extends SignatureVisitor { + private final Translator translator; + + private final SignatureVisitor sv; + private final Stack classes = new Stack<>(); + + public TranslationSignatureVisitor(Translator translator, int api, SignatureVisitor sv) { + super(api); + this.translator = translator; + this.sv = sv; + } + + @Override + public void visitClassType(String name) { + ClassEntry entry = new ClassEntry(name); + ClassEntry translatedEntry = this.translator.getTranslatedClass(entry); + this.classes.push(entry); + this.sv.visitClassType(translatedEntry.getName()); + } + + @Override + public void visitInnerClassType(String name) { + ClassEntry outerEntry = this.classes.pop(); + ClassEntry entry = new ClassEntry(outerEntry + "$" + name); + this.classes.push(entry); + String translatedEntry = this.translator.getTranslatedClass(entry).getName(); + this.sv.visitInnerClassType(translatedEntry.substring(translatedEntry.lastIndexOf('$') + 1)); + } + + @Override + public void visitFormalTypeParameter(String name) { + this.sv.visitFormalTypeParameter(name); + } + + @Override + public void visitTypeVariable(String name) { + this.sv.visitTypeVariable(name); + } + + @Override + public SignatureVisitor visitArrayType() { + this.sv.visitArrayType(); + return this; + } + + @Override + public void visitBaseType(char descriptor) { + this.sv.visitBaseType(descriptor); + } + + @Override + public SignatureVisitor visitClassBound() { + this.sv.visitClassBound(); + return this; + } + + @Override + public SignatureVisitor visitExceptionType() { + this.sv.visitExceptionType(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + this.sv.visitInterface(); + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + this.sv.visitInterfaceBound(); + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + this.sv.visitParameterType(); + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + this.sv.visitReturnType(); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + this.sv.visitSuperclass(); + return this; + } + + @Override + public void visitTypeArgument() { + this.sv.visitTypeArgument(); + } + + @Override + public SignatureVisitor visitTypeArgument(char wildcard) { + this.sv.visitTypeArgument(wildcard); + return this; + } + + @Override + public void visitEnd() { + this.sv.visitEnd(); + this.classes.pop(); + } + + @Override + public String toString() { + return this.sv.toString(); + } +} -- cgit v1.2.3