From 22cac8f1a25c7d34a94bc5e00c56c0532509071f Mon Sep 17 00:00:00 2001 From: Cuchaz Date: Mon, 30 Mar 2015 22:00:54 -0400 Subject: add publifier --- src/cuchaz/enigma/CommandMain.java | 10 ++++ src/cuchaz/enigma/Deobfuscator.java | 75 +++++++++++++------------- src/cuchaz/enigma/bytecode/ClassPublifier.java | 41 ++++++++++++++ 3 files changed, 89 insertions(+), 37 deletions(-) create mode 100644 src/cuchaz/enigma/bytecode/ClassPublifier.java (limited to 'src/cuchaz') diff --git a/src/cuchaz/enigma/CommandMain.java b/src/cuchaz/enigma/CommandMain.java index 74c01913..41528fef 100644 --- a/src/cuchaz/enigma/CommandMain.java +++ b/src/cuchaz/enigma/CommandMain.java @@ -58,6 +58,8 @@ public class CommandMain { decompile(args); } else if (command.equalsIgnoreCase("protectify")) { protectify(args); + } else if (command.equalsIgnoreCase("publify")) { + publify(args); } else { throw new IllegalArgumentException("Command not recognized: " + command); } @@ -103,6 +105,14 @@ public class CommandMain { deobfuscator.protectifyJar(fileJarOut, new ConsoleProgressListener()); } + private static void publify(String[] args) + throws Exception { + File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)); + File fileJarOut = getWritableFile(getArg(args, 2, "out jar", true)); + Deobfuscator deobfuscator = getDeobfuscator(null, new JarFile(fileJarIn)); + deobfuscator.publifyJar(fileJarOut, new ConsoleProgressListener()); + } + private static Deobfuscator getDeobfuscator(File fileMappings, JarFile jar) throws Exception { System.out.println("Reading jar..."); diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index a7d8a671..d9ded878 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java @@ -46,6 +46,7 @@ import cuchaz.enigma.analysis.SourceIndex; import cuchaz.enigma.analysis.SourceIndexVisitor; import cuchaz.enigma.analysis.Token; import cuchaz.enigma.bytecode.ClassProtectifier; +import cuchaz.enigma.bytecode.ClassPublifier; import cuchaz.enigma.mapping.ArgumentEntry; import cuchaz.enigma.mapping.BehaviorEntry; import cuchaz.enigma.mapping.ClassEntry; @@ -321,48 +322,48 @@ public class Deobfuscator { } public void writeJar(File out, ProgressListener progress) { - try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { - if (progress != null) { - progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Translating classes..."); + final TranslatingTypeLoader loader = new TranslatingTypeLoader( + m_jar, + m_jarIndex, + getTranslator(TranslationDirection.Obfuscating), + getTranslator(TranslationDirection.Deobfuscating) + ); + transformJar(out, progress, new ClassTransformer() { + + @Override + public CtClass transform(CtClass c) throws Exception { + return loader.transformClass(c); } - - // prep the loader - TranslatingTypeLoader loader = new TranslatingTypeLoader( - m_jar, - m_jarIndex, - getTranslator(TranslationDirection.Obfuscating), - getTranslator(TranslationDirection.Deobfuscating) - ); - - int i = 0; - for (CtClass c : JarClassIterator.classes(m_jar)) { - if (progress != null) { - progress.onProgress(i++, c.getName()); - } - - try { - c = loader.transformClass(c); - outJar.putNextEntry(new JarEntry(c.getName().replace('.', '/') + ".class")); - outJar.write(c.toBytecode()); - outJar.closeEntry(); - } catch (Throwable t) { - throw new Error("Unable to deobfuscate class " + c.getName(), t); - } + }); + } + + public void protectifyJar(File out, ProgressListener progress) { + transformJar(out, progress, new ClassTransformer() { + + @Override + public CtClass transform(CtClass c) throws Exception { + return ClassProtectifier.protectify(c); } - if (progress != null) { - progress.onProgress(i, "Done!"); + }); + } + + public void publifyJar(File out, ProgressListener progress) { + transformJar(out, progress, new ClassTransformer() { + + @Override + public CtClass transform(CtClass c) throws Exception { + return ClassPublifier.publify(c); } - - outJar.close(); - } catch (IOException ex) { - throw new Error("Unable to write to Jar file!"); - } + }); } - public void protectifyJar(File out, ProgressListener progress) { + private interface ClassTransformer { + public CtClass transform(CtClass c) throws Exception; + } + private void transformJar(File out, ProgressListener progress, ClassTransformer transformer) { try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { if (progress != null) { - progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Protectifying classes..."); + progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Transforming classes..."); } int i = 0; @@ -372,12 +373,12 @@ public class Deobfuscator { } try { - c = ClassProtectifier.protectify(c); + c = transformer.transform(c); outJar.putNextEntry(new JarEntry(c.getName().replace('.', '/') + ".class")); outJar.write(c.toBytecode()); outJar.closeEntry(); } catch (Throwable t) { - throw new Error("Unable to protectify class " + c.getName(), t); + throw new Error("Unable to transform class " + c.getName(), t); } } if (progress != null) { diff --git a/src/cuchaz/enigma/bytecode/ClassPublifier.java b/src/cuchaz/enigma/bytecode/ClassPublifier.java new file mode 100644 index 00000000..d8162e46 --- /dev/null +++ b/src/cuchaz/enigma/bytecode/ClassPublifier.java @@ -0,0 +1,41 @@ +package cuchaz.enigma.bytecode; + +import javassist.CtBehavior; +import javassist.CtClass; +import javassist.CtField; +import javassist.bytecode.AccessFlag; +import javassist.bytecode.InnerClassesAttribute; + + +public class ClassPublifier { + + public static CtClass publify(CtClass c) { + + // publify all the fields + for (CtField field : c.getDeclaredFields()) { + field.setModifiers(publify(field.getModifiers())); + } + + // publify all the methods and constructors + for (CtBehavior behavior : c.getDeclaredBehaviors()) { + behavior.setModifiers(publify(behavior.getModifiers())); + } + + // publify all the inner classes + InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); + if (attr != null) { + for (int i=0; i