summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar jeff2015-03-19 02:20:32 -0400
committerGravatar jeff2015-03-19 02:20:32 -0400
commit96ba0ab422d7f9747e93461524991cf5ceeb48c4 (patch)
treecd9504acae257575e0a354e79386da67acd796c6 /src
parentAdded tag v0.10 beta for changeset 68f12fd9afb0 (diff)
downloadenigma-fork-96ba0ab422d7f9747e93461524991cf5ceeb48c4.tar.gz
enigma-fork-96ba0ab422d7f9747e93461524991cf5ceeb48c4.tar.xz
enigma-fork-96ba0ab422d7f9747e93461524991cf5ceeb48c4.zip
fix issue with naming method arguments and the local variable tables
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/TranslatingTypeLoader.java2
-rw-r--r--src/cuchaz/enigma/bytecode/LocalVariableRenamer.java70
-rw-r--r--src/cuchaz/enigma/bytecode/MethodParameterWriter.java14
-rw-r--r--src/cuchaz/enigma/bytecode/MethodParametersAttribute.java3
4 files changed, 82 insertions, 7 deletions
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java
index ecd7d64..dce4b85 100644
--- a/src/cuchaz/enigma/TranslatingTypeLoader.java
+++ b/src/cuchaz/enigma/TranslatingTypeLoader.java
@@ -233,7 +233,7 @@ public class TranslatingTypeLoader implements ITypeLoader {
233 // do all kinds of deobfuscating transformations on the class 233 // do all kinds of deobfuscating transformations on the class
234 new BridgeMarker(m_jarIndex).markBridges(c); 234 new BridgeMarker(m_jarIndex).markBridges(c);
235 new MethodParameterWriter(m_deobfuscatingTranslator).writeMethodArguments(c); 235 new MethodParameterWriter(m_deobfuscatingTranslator).writeMethodArguments(c);
236 new LocalVariableRenamer().rename(c); 236 new LocalVariableRenamer(m_deobfuscatingTranslator).rename(c);
237 new ClassTranslator(m_deobfuscatingTranslator).translate(c); 237 new ClassTranslator(m_deobfuscatingTranslator).translate(c);
238 238
239 return c; 239 return c;
diff --git a/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java b/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java
index c87c25b..1179560 100644
--- a/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java
+++ b/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java
@@ -6,9 +6,20 @@ import javassist.bytecode.ByteArray;
6import javassist.bytecode.CodeAttribute; 6import javassist.bytecode.CodeAttribute;
7import javassist.bytecode.ConstPool; 7import javassist.bytecode.ConstPool;
8import javassist.bytecode.LocalVariableAttribute; 8import javassist.bytecode.LocalVariableAttribute;
9import javassist.bytecode.LocalVariableTypeAttribute;
10import cuchaz.enigma.mapping.ArgumentEntry;
11import cuchaz.enigma.mapping.BehaviorEntry;
12import cuchaz.enigma.mapping.EntryFactory;
13import cuchaz.enigma.mapping.Translator;
9 14
10 15
11public class LocalVariableRenamer { 16public class LocalVariableRenamer {
17
18 private Translator m_translator;
19
20 public LocalVariableRenamer(Translator translator) {
21 m_translator = translator;
22 }
12 23
13 public void rename(CtClass c) { 24 public void rename(CtClass c) {
14 for (CtBehavior behavior : c.getDeclaredBehaviors()) { 25 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
@@ -18,18 +29,67 @@ public class LocalVariableRenamer {
18 if (codeAttribute == null) { 29 if (codeAttribute == null) {
19 continue; 30 continue;
20 } 31 }
32
33 BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior);
34 ConstPool constants = c.getClassFile().getConstPool();
35
21 LocalVariableAttribute table = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag); 36 LocalVariableAttribute table = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag);
22 if (table == null) { 37 if (table != null) {
23 continue; 38 renameTable(behaviorEntry, constants, table);
24 } 39 }
25 40
26 ConstPool constants = c.getClassFile().getConstPool(); 41 LocalVariableTypeAttribute typeTable = (LocalVariableTypeAttribute)codeAttribute.getAttribute(LocalVariableAttribute.typeTag);
27 for (int i=0; i<table.tableLength(); i++) { 42 if (typeTable != null) {
28 renameVariable(table, i, constants.addUtf8Info("v" + i)); 43 renameTable(behaviorEntry, constants, typeTable);
29 } 44 }
30 } 45 }
31 } 46 }
32 47
48 // DEBUG
49 @SuppressWarnings("unused")
50 private void dumpTable(LocalVariableAttribute table) {
51 for (int i=0; i<table.tableLength(); i++) {
52 System.out.println(String.format("\t%d (%d): %s %s",
53 i, table.index(i), table.variableName(i), table.descriptor(i)
54 ));
55 }
56 }
57
58 private void renameTable(BehaviorEntry behaviorEntry, ConstPool constants, LocalVariableAttribute table) {
59
60 // skip empty tables
61 if (table.tableLength() <= 0) {
62 return;
63 }
64
65 // where do we start counting variables?
66 int starti = 0;
67 if (table.variableName(0).equals("this")) {
68 // skip the "this" variable
69 starti = 1;
70 }
71
72 // rename method arguments first
73 int numArgs = 0;
74 if (behaviorEntry.getSignature() != null) {
75 numArgs = behaviorEntry.getSignature().getArgumentTypes().size();
76 for (int i=starti; i<starti + numArgs && i<table.tableLength(); i++) {
77 int argi = i - starti;
78 String argName = m_translator.translate(new ArgumentEntry(behaviorEntry, argi, ""));
79 if (argName == null) {
80 argName = "a" + (argi + 1);
81 }
82 renameVariable(table, i, constants.addUtf8Info(argName));
83 }
84 }
85
86 // then rename the rest of the args, if any
87 for (int i=starti + numArgs; i<table.tableLength(); i++) {
88 int firstIndex = table.index(starti + numArgs);
89 renameVariable(table, i, constants.addUtf8Info("v" + (table.index(i) - firstIndex + 1)));
90 }
91 }
92
33 private void renameVariable(LocalVariableAttribute table, int i, int stringId) { 93 private void renameVariable(LocalVariableAttribute table, int i, int stringId) {
34 // based off of LocalVariableAttribute.nameIndex() 94 // based off of LocalVariableAttribute.nameIndex()
35 ByteArray.write16bit(stringId, table.get(), i*10 + 6); 95 ByteArray.write16bit(stringId, table.get(), i*10 + 6);
diff --git a/src/cuchaz/enigma/bytecode/MethodParameterWriter.java b/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
index f64ca02..87c9196 100644
--- a/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
+++ b/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
@@ -15,6 +15,8 @@ import java.util.List;
15 15
16import javassist.CtBehavior; 16import javassist.CtBehavior;
17import javassist.CtClass; 17import javassist.CtClass;
18import javassist.bytecode.CodeAttribute;
19import javassist.bytecode.LocalVariableAttribute;
18import cuchaz.enigma.mapping.ArgumentEntry; 20import cuchaz.enigma.mapping.ArgumentEntry;
19import cuchaz.enigma.mapping.BehaviorEntry; 21import cuchaz.enigma.mapping.BehaviorEntry;
20import cuchaz.enigma.mapping.EntryFactory; 22import cuchaz.enigma.mapping.EntryFactory;
@@ -33,6 +35,15 @@ public class MethodParameterWriter {
33 35
34 // Procyon will read method arguments from the "MethodParameters" attribute, so write those 36 // Procyon will read method arguments from the "MethodParameters" attribute, so write those
35 for (CtBehavior behavior : c.getDeclaredBehaviors()) { 37 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
38
39 // if there's a local variable table here, don't write a MethodParameters attribute
40 // let the local variable writer deal with it instead
41 // procyon starts doing really weird things if we give it both attributes
42 CodeAttribute codeAttribute = behavior.getMethodInfo().getCodeAttribute();
43 if (codeAttribute != null && codeAttribute.getAttribute(LocalVariableAttribute.tag) != null) {
44 continue;
45 }
46
36 BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior); 47 BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior);
37 48
38 // get the number of arguments 49 // get the number of arguments
@@ -53,6 +64,9 @@ public class MethodParameterWriter {
53 } 64 }
54 65
55 // save the mappings to the class 66 // save the mappings to the class
67 for (String name : names) {
68 System.out.println("\t" + name);
69 }
56 MethodParametersAttribute.updateClass(behavior.getMethodInfo(), names); 70 MethodParametersAttribute.updateClass(behavior.getMethodInfo(), names);
57 } 71 }
58 } 72 }
diff --git a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
index bf95956..27f5b9b 100644
--- a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
+++ b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
@@ -27,6 +27,7 @@ public class MethodParametersAttribute extends AttributeInfo {
27 } 27 }
28 28
29 public static void updateClass(MethodInfo info, List<String> names) { 29 public static void updateClass(MethodInfo info, List<String> names) {
30
30 // add the names to the class const pool 31 // add the names to the class const pool
31 ConstPool constPool = info.getConstPool(); 32 ConstPool constPool = info.getConstPool();
32 List<Integer> parameterNameIndices = new ArrayList<Integer>(); 33 List<Integer> parameterNameIndices = new ArrayList<Integer>();
@@ -44,7 +45,7 @@ public class MethodParametersAttribute extends AttributeInfo {
44 45
45 private static byte[] writeStruct(List<Integer> parameterNameIndices) { 46 private static byte[] writeStruct(List<Integer> parameterNameIndices) {
46 // JVM 8 Spec says the struct looks like this: 47 // JVM 8 Spec says the struct looks like this:
47 // http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jvms-fr-diffs.pdf 48 // http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24
48 // uint8 num_params 49 // uint8 num_params
49 // for each param: 50 // for each param:
50 // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry 51 // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry