diff options
| author | 2015-03-30 22:00:54 -0400 | |
|---|---|---|
| committer | 2015-03-30 22:00:54 -0400 | |
| commit | 22cac8f1a25c7d34a94bc5e00c56c0532509071f (patch) | |
| tree | 7b3784fc8eb4936c54ada9e685d551bf294e620b | |
| parent | fix unintentional compile time transitive dependency on procyon (diff) | |
| download | enigma-22cac8f1a25c7d34a94bc5e00c56c0532509071f.tar.gz enigma-22cac8f1a25c7d34a94bc5e00c56c0532509071f.tar.xz enigma-22cac8f1a25c7d34a94bc5e00c56c0532509071f.zip | |
add publifier
| -rw-r--r-- | src/cuchaz/enigma/CommandMain.java | 10 | ||||
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 75 | ||||
| -rw-r--r-- | src/cuchaz/enigma/bytecode/ClassPublifier.java | 41 |
3 files changed, 89 insertions, 37 deletions
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 { | |||
| 58 | decompile(args); | 58 | decompile(args); |
| 59 | } else if (command.equalsIgnoreCase("protectify")) { | 59 | } else if (command.equalsIgnoreCase("protectify")) { |
| 60 | protectify(args); | 60 | protectify(args); |
| 61 | } else if (command.equalsIgnoreCase("publify")) { | ||
| 62 | publify(args); | ||
| 61 | } else { | 63 | } else { |
| 62 | throw new IllegalArgumentException("Command not recognized: " + command); | 64 | throw new IllegalArgumentException("Command not recognized: " + command); |
| 63 | } | 65 | } |
| @@ -103,6 +105,14 @@ public class CommandMain { | |||
| 103 | deobfuscator.protectifyJar(fileJarOut, new ConsoleProgressListener()); | 105 | deobfuscator.protectifyJar(fileJarOut, new ConsoleProgressListener()); |
| 104 | } | 106 | } |
| 105 | 107 | ||
| 108 | private static void publify(String[] args) | ||
| 109 | throws Exception { | ||
| 110 | File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)); | ||
| 111 | File fileJarOut = getWritableFile(getArg(args, 2, "out jar", true)); | ||
| 112 | Deobfuscator deobfuscator = getDeobfuscator(null, new JarFile(fileJarIn)); | ||
| 113 | deobfuscator.publifyJar(fileJarOut, new ConsoleProgressListener()); | ||
| 114 | } | ||
| 115 | |||
| 106 | private static Deobfuscator getDeobfuscator(File fileMappings, JarFile jar) | 116 | private static Deobfuscator getDeobfuscator(File fileMappings, JarFile jar) |
| 107 | throws Exception { | 117 | throws Exception { |
| 108 | System.out.println("Reading jar..."); | 118 | 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; | |||
| 46 | import cuchaz.enigma.analysis.SourceIndexVisitor; | 46 | import cuchaz.enigma.analysis.SourceIndexVisitor; |
| 47 | import cuchaz.enigma.analysis.Token; | 47 | import cuchaz.enigma.analysis.Token; |
| 48 | import cuchaz.enigma.bytecode.ClassProtectifier; | 48 | import cuchaz.enigma.bytecode.ClassProtectifier; |
| 49 | import cuchaz.enigma.bytecode.ClassPublifier; | ||
| 49 | import cuchaz.enigma.mapping.ArgumentEntry; | 50 | import cuchaz.enigma.mapping.ArgumentEntry; |
| 50 | import cuchaz.enigma.mapping.BehaviorEntry; | 51 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 51 | import cuchaz.enigma.mapping.ClassEntry; | 52 | import cuchaz.enigma.mapping.ClassEntry; |
| @@ -321,48 +322,48 @@ public class Deobfuscator { | |||
| 321 | } | 322 | } |
| 322 | 323 | ||
| 323 | public void writeJar(File out, ProgressListener progress) { | 324 | public void writeJar(File out, ProgressListener progress) { |
| 324 | try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { | 325 | final TranslatingTypeLoader loader = new TranslatingTypeLoader( |
| 325 | if (progress != null) { | 326 | m_jar, |
| 326 | progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Translating classes..."); | 327 | m_jarIndex, |
| 328 | getTranslator(TranslationDirection.Obfuscating), | ||
| 329 | getTranslator(TranslationDirection.Deobfuscating) | ||
| 330 | ); | ||
| 331 | transformJar(out, progress, new ClassTransformer() { | ||
| 332 | |||
| 333 | @Override | ||
| 334 | public CtClass transform(CtClass c) throws Exception { | ||
| 335 | return loader.transformClass(c); | ||
| 327 | } | 336 | } |
| 328 | 337 | }); | |
| 329 | // prep the loader | 338 | } |
| 330 | TranslatingTypeLoader loader = new TranslatingTypeLoader( | 339 | |
| 331 | m_jar, | 340 | public void protectifyJar(File out, ProgressListener progress) { |
| 332 | m_jarIndex, | 341 | transformJar(out, progress, new ClassTransformer() { |
| 333 | getTranslator(TranslationDirection.Obfuscating), | 342 | |
| 334 | getTranslator(TranslationDirection.Deobfuscating) | 343 | @Override |
| 335 | ); | 344 | public CtClass transform(CtClass c) throws Exception { |
| 336 | 345 | return ClassProtectifier.protectify(c); | |
| 337 | int i = 0; | ||
| 338 | for (CtClass c : JarClassIterator.classes(m_jar)) { | ||
| 339 | if (progress != null) { | ||
| 340 | progress.onProgress(i++, c.getName()); | ||
| 341 | } | ||
| 342 | |||
| 343 | try { | ||
| 344 | c = loader.transformClass(c); | ||
| 345 | outJar.putNextEntry(new JarEntry(c.getName().replace('.', '/') + ".class")); | ||
| 346 | outJar.write(c.toBytecode()); | ||
| 347 | outJar.closeEntry(); | ||
| 348 | } catch (Throwable t) { | ||
| 349 | throw new Error("Unable to deobfuscate class " + c.getName(), t); | ||
| 350 | } | ||
| 351 | } | 346 | } |
| 352 | if (progress != null) { | 347 | }); |
| 353 | progress.onProgress(i, "Done!"); | 348 | } |
| 349 | |||
| 350 | public void publifyJar(File out, ProgressListener progress) { | ||
| 351 | transformJar(out, progress, new ClassTransformer() { | ||
| 352 | |||
| 353 | @Override | ||
| 354 | public CtClass transform(CtClass c) throws Exception { | ||
| 355 | return ClassPublifier.publify(c); | ||
| 354 | } | 356 | } |
| 355 | 357 | }); | |
| 356 | outJar.close(); | ||
| 357 | } catch (IOException ex) { | ||
| 358 | throw new Error("Unable to write to Jar file!"); | ||
| 359 | } | ||
| 360 | } | 358 | } |
| 361 | 359 | ||
| 362 | public void protectifyJar(File out, ProgressListener progress) { | 360 | private interface ClassTransformer { |
| 361 | public CtClass transform(CtClass c) throws Exception; | ||
| 362 | } | ||
| 363 | private void transformJar(File out, ProgressListener progress, ClassTransformer transformer) { | ||
| 363 | try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { | 364 | try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { |
| 364 | if (progress != null) { | 365 | if (progress != null) { |
| 365 | progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Protectifying classes..."); | 366 | progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Transforming classes..."); |
| 366 | } | 367 | } |
| 367 | 368 | ||
| 368 | int i = 0; | 369 | int i = 0; |
| @@ -372,12 +373,12 @@ public class Deobfuscator { | |||
| 372 | } | 373 | } |
| 373 | 374 | ||
| 374 | try { | 375 | try { |
| 375 | c = ClassProtectifier.protectify(c); | 376 | c = transformer.transform(c); |
| 376 | outJar.putNextEntry(new JarEntry(c.getName().replace('.', '/') + ".class")); | 377 | outJar.putNextEntry(new JarEntry(c.getName().replace('.', '/') + ".class")); |
| 377 | outJar.write(c.toBytecode()); | 378 | outJar.write(c.toBytecode()); |
| 378 | outJar.closeEntry(); | 379 | outJar.closeEntry(); |
| 379 | } catch (Throwable t) { | 380 | } catch (Throwable t) { |
| 380 | throw new Error("Unable to protectify class " + c.getName(), t); | 381 | throw new Error("Unable to transform class " + c.getName(), t); |
| 381 | } | 382 | } |
| 382 | } | 383 | } |
| 383 | if (progress != null) { | 384 | 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 @@ | |||
| 1 | package cuchaz.enigma.bytecode; | ||
| 2 | |||
| 3 | import javassist.CtBehavior; | ||
| 4 | import javassist.CtClass; | ||
| 5 | import javassist.CtField; | ||
| 6 | import javassist.bytecode.AccessFlag; | ||
| 7 | import javassist.bytecode.InnerClassesAttribute; | ||
| 8 | |||
| 9 | |||
| 10 | public class ClassPublifier { | ||
| 11 | |||
| 12 | public static CtClass publify(CtClass c) { | ||
| 13 | |||
| 14 | // publify all the fields | ||
| 15 | for (CtField field : c.getDeclaredFields()) { | ||
| 16 | field.setModifiers(publify(field.getModifiers())); | ||
| 17 | } | ||
| 18 | |||
| 19 | // publify all the methods and constructors | ||
| 20 | for (CtBehavior behavior : c.getDeclaredBehaviors()) { | ||
| 21 | behavior.setModifiers(publify(behavior.getModifiers())); | ||
| 22 | } | ||
| 23 | |||
| 24 | // publify all the inner classes | ||
| 25 | InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute(InnerClassesAttribute.tag); | ||
| 26 | if (attr != null) { | ||
| 27 | for (int i=0; i<attr.tableLength(); i++) { | ||
| 28 | attr.setAccessFlags(i, publify(attr.accessFlags(i))); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | return c; | ||
| 33 | } | ||
| 34 | |||
| 35 | private static int publify(int flags) { | ||
| 36 | if (AccessFlag.isPrivate(flags) || AccessFlag.isProtected(flags)) { | ||
| 37 | flags = AccessFlag.setPublic(flags); | ||
| 38 | } | ||
| 39 | return flags; | ||
| 40 | } | ||
| 41 | } | ||