|
|
@ -18,18 +18,25 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
package jode.obfuscator; |
|
|
|
package jode.obfuscator; |
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
import jode.AssertError; |
|
|
|
import jode.GlobalOptions; |
|
|
|
import jode.GlobalOptions; |
|
|
|
import jode.Obfuscator; |
|
|
|
|
|
|
|
import jode.bytecode.*; |
|
|
|
import jode.bytecode.*; |
|
|
|
import jode.type.Type; |
|
|
|
import jode.type.Type; |
|
|
|
import java.io.*; |
|
|
|
|
|
|
|
import java.util.Vector; |
|
|
|
///#ifdef JDK12
|
|
|
|
import java.util.Enumeration; |
|
|
|
///import java.util.Collections;
|
|
|
|
import java.util.Hashtable; |
|
|
|
///import java.util.Iterator;
|
|
|
|
|
|
|
|
///import java.util.Map;
|
|
|
|
|
|
|
|
///#else
|
|
|
|
|
|
|
|
import jode.util.Collections; |
|
|
|
|
|
|
|
import jode.util.Iterator; |
|
|
|
|
|
|
|
import jode.util.Map; |
|
|
|
|
|
|
|
///#endif
|
|
|
|
|
|
|
|
|
|
|
|
///#ifdef JDK12
|
|
|
|
///#ifdef JDK12
|
|
|
|
///import java.lang.ref.SoftReference;
|
|
|
|
///import java.lang.ref.SoftReference;
|
|
|
|
///#endif
|
|
|
|
///#endif
|
|
|
|
|
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
|
|
|
|
|
|
|
|
public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
ClassIdentifier clazz; |
|
|
|
ClassIdentifier clazz; |
|
|
@ -37,35 +44,18 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
String name; |
|
|
|
String name; |
|
|
|
String type; |
|
|
|
String type; |
|
|
|
|
|
|
|
|
|
|
|
///#ifdef JDK12
|
|
|
|
|
|
|
|
/// /**
|
|
|
|
|
|
|
|
/// * The code analyzer of this method, or null if there isn't any.
|
|
|
|
|
|
|
|
/// */
|
|
|
|
|
|
|
|
/// SoftReference codeAnalyzerRef;
|
|
|
|
|
|
|
|
///#else
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The code analyzer of this method, or null if there isn't any. |
|
|
|
* The code analyzer of this method, or null if there isn't any. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
CodeAnalyzer codeAnalyzer; |
|
|
|
CodeAnalyzer codeAnalyzer; |
|
|
|
///#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public CodeAnalyzer getCodeAnalyzer() { |
|
|
|
public CodeAnalyzer getCodeAnalyzer() { |
|
|
|
///#ifdef JDK12
|
|
|
|
|
|
|
|
/// if (codeAnalyzerRef != null && codeAnalyzerRef.get() != null)
|
|
|
|
|
|
|
|
/// return (CodeAnalyzer) codeAnalyzerRef.get();
|
|
|
|
|
|
|
|
/// CodeAnalyzer codeAnalyzer = null;
|
|
|
|
|
|
|
|
///#else
|
|
|
|
|
|
|
|
if (codeAnalyzer != null) |
|
|
|
if (codeAnalyzer != null) |
|
|
|
return codeAnalyzer; |
|
|
|
return codeAnalyzer; |
|
|
|
///#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BytecodeInfo code = info.getBytecode(); |
|
|
|
BytecodeInfo code = info.getBytecode(); |
|
|
|
if (code != null) { |
|
|
|
if (code != null) |
|
|
|
codeAnalyzer = new ConstantAnalyzer(code, this); |
|
|
|
codeAnalyzer = new ConstantAnalyzer(code, this); |
|
|
|
///#ifdef JDK12
|
|
|
|
|
|
|
|
/// codeAnalyzerRef = new SoftReference(codeAnalyzer);
|
|
|
|
|
|
|
|
///#endif
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return codeAnalyzer; |
|
|
|
return codeAnalyzer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -75,6 +65,18 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
this.type = info.getType(); |
|
|
|
this.type = info.getType(); |
|
|
|
this.clazz = clazz; |
|
|
|
this.clazz = clazz; |
|
|
|
this.info = info; |
|
|
|
this.info = info; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BytecodeInfo bytecode = info.getBytecode(); |
|
|
|
|
|
|
|
if (bytecode != null) { |
|
|
|
|
|
|
|
if ((Main.stripping & Main.STRIP_LVT) != 0) |
|
|
|
|
|
|
|
info.getBytecode().setLocalVariableTable(null); |
|
|
|
|
|
|
|
if ((Main.stripping & Main.STRIP_LNT) != 0) |
|
|
|
|
|
|
|
info.getBytecode().setLineNumberTable(null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Iterator getChilds() { |
|
|
|
|
|
|
|
return Collections.EMPTY_LIST.iterator(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void applyPreserveRule(int preserveRule) { |
|
|
|
public void applyPreserveRule(int preserveRule) { |
|
|
@ -86,7 +88,7 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
|
|
|
|
|
|
|
|
public void setSingleReachable() { |
|
|
|
public void setSingleReachable() { |
|
|
|
super.setSingleReachable(); |
|
|
|
super.setSingleReachable(); |
|
|
|
clazz.bundle.analyzeIdentifier(this); |
|
|
|
Main.getClassBundle().analyzeIdentifier(this); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void analyze() { |
|
|
|
public void analyze() { |
|
|
@ -97,7 +99,8 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
int index = type.indexOf('L'); |
|
|
|
int index = type.indexOf('L'); |
|
|
|
while (index != -1) { |
|
|
|
while (index != -1) { |
|
|
|
int end = type.indexOf(';', index); |
|
|
|
int end = type.indexOf(';', index); |
|
|
|
clazz.bundle.reachableIdentifier(type.substring(index+1, end) |
|
|
|
Main.getClassBundle() |
|
|
|
|
|
|
|
.reachableIdentifier(type.substring(index+1, end) |
|
|
|
, false); |
|
|
|
, false); |
|
|
|
index = type.indexOf('L', end); |
|
|
|
index = type.indexOf('L', end); |
|
|
|
} |
|
|
|
} |
|
|
@ -105,20 +108,21 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
String[] exceptions = info.getExceptions(); |
|
|
|
String[] exceptions = info.getExceptions(); |
|
|
|
if (exceptions != null) { |
|
|
|
if (exceptions != null) { |
|
|
|
for (int i=0; i< exceptions.length; i++) |
|
|
|
for (int i=0; i< exceptions.length; i++) |
|
|
|
clazz.bundle.reachableIdentifier(exceptions[i], false); |
|
|
|
Main.getClassBundle() |
|
|
|
|
|
|
|
.reachableIdentifier(exceptions[i], false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (getCodeAnalyzer() != null) |
|
|
|
if (getCodeAnalyzer() != null) |
|
|
|
getCodeAnalyzer().analyzeCode(); |
|
|
|
getCodeAnalyzer().analyzeCode(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void readTable(Hashtable table) { |
|
|
|
public void readTable(Map table) { |
|
|
|
setAlias((String) table.get(getFullName() + "." + getType())); |
|
|
|
setAlias((String) table.get(getFullName() + "." + getType())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void writeTable(Hashtable table) { |
|
|
|
public void writeTable(Map table) { |
|
|
|
table.put(getFullAlias() |
|
|
|
table.put(getFullAlias() + "." |
|
|
|
+ "." + clazz.bundle.getTypeAlias(getType()), getName()); |
|
|
|
+ Main.getClassBundle().getTypeAlias(getType()), getName()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Identifier getParent() { |
|
|
|
public Identifier getParent() { |
|
|
@ -141,21 +145,8 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
return type; |
|
|
|
return type; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean conflicting(String newAlias, boolean strong) { |
|
|
|
public boolean conflicting(String newAlias) { |
|
|
|
String paramType = getType(); |
|
|
|
return clazz.methodConflicts(this, newAlias); |
|
|
|
if (!strong) { |
|
|
|
|
|
|
|
paramType = paramType.substring(0, paramType.indexOf(')')+1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (clazz.getMethod(newAlias, paramType) != null) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Enumeration enum = clazz.knownSubClasses.elements(); |
|
|
|
|
|
|
|
while (enum.hasMoreElements()) { |
|
|
|
|
|
|
|
ClassIdentifier ci = (ClassIdentifier) enum.nextElement(); |
|
|
|
|
|
|
|
if (ci.hasMethod(newAlias, paramType)) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
@ -176,14 +167,14 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
("doTransformation called on transformed method"); |
|
|
|
("doTransformation called on transformed method"); |
|
|
|
wasTransformed = true; |
|
|
|
wasTransformed = true; |
|
|
|
info.setName(getAlias()); |
|
|
|
info.setName(getAlias()); |
|
|
|
info.setType(clazz.bundle.getTypeAlias(type)); |
|
|
|
info.setType(Main.getClassBundle().getTypeAlias(type)); |
|
|
|
if (getCodeAnalyzer() != null) { |
|
|
|
if (getCodeAnalyzer() != null) { |
|
|
|
BytecodeInfo strippedBytecode = getCodeAnalyzer().stripCode(); |
|
|
|
BytecodeInfo strippedBytecode = getCodeAnalyzer().stripCode(); |
|
|
|
// strippedBytecode.dumpCode(GlobalOptions.err);
|
|
|
|
// strippedBytecode.dumpCode(GlobalOptions.err);
|
|
|
|
|
|
|
|
|
|
|
|
/* XXX This should be in a if (Obfuscator.distributeLocals) */ |
|
|
|
/* XXX This should be in a if (Obfuscator.distributeLocals) */ |
|
|
|
LocalOptimizer localOpt = new LocalOptimizer(strippedBytecode, |
|
|
|
LocalOptimizer localOpt = new LocalOptimizer(this, |
|
|
|
info); |
|
|
|
strippedBytecode); |
|
|
|
localOpt.calcLocalInfo(); |
|
|
|
localOpt.calcLocalInfo(); |
|
|
|
if ((GlobalOptions.debuggingFlags |
|
|
|
if ((GlobalOptions.debuggingFlags |
|
|
|
& GlobalOptions.DEBUG_LOCALS) != 0) { |
|
|
|
& GlobalOptions.DEBUG_LOCALS) != 0) { |
|
|
@ -211,8 +202,8 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
case opc_invokestatic: |
|
|
|
case opc_invokestatic: |
|
|
|
case opc_invokeinterface: |
|
|
|
case opc_invokeinterface: |
|
|
|
case opc_invokevirtual: { |
|
|
|
case opc_invokevirtual: { |
|
|
|
instr.objData = clazz.bundle.getReferenceAlias |
|
|
|
instr.objData = Main.getClassBundle() |
|
|
|
((Reference) instr.objData); |
|
|
|
.getReferenceAlias((Reference) instr.objData); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
@ -220,16 +211,16 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
case opc_putfield: |
|
|
|
case opc_putfield: |
|
|
|
case opc_getstatic: |
|
|
|
case opc_getstatic: |
|
|
|
case opc_getfield: { |
|
|
|
case opc_getfield: { |
|
|
|
instr.objData = clazz.bundle.getReferenceAlias |
|
|
|
instr.objData = Main.getClassBundle() |
|
|
|
((Reference) instr.objData); |
|
|
|
.getReferenceAlias((Reference) instr.objData); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case opc_new: |
|
|
|
case opc_new: |
|
|
|
case opc_checkcast: |
|
|
|
case opc_checkcast: |
|
|
|
case opc_instanceof: |
|
|
|
case opc_instanceof: |
|
|
|
case opc_multianewarray: { |
|
|
|
case opc_multianewarray: { |
|
|
|
instr.objData = clazz.bundle.getTypeAlias |
|
|
|
instr.objData = Main.getClassBundle() |
|
|
|
((String) instr.objData); |
|
|
|
.getTypeAlias((String) instr.objData); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -238,8 +229,8 @@ public class MethodIdentifier extends Identifier implements Opcodes { |
|
|
|
Handler[] handlers = strippedBytecode.getExceptionHandlers(); |
|
|
|
Handler[] handlers = strippedBytecode.getExceptionHandlers(); |
|
|
|
for (int i=0; i< handlers.length; i++) { |
|
|
|
for (int i=0; i< handlers.length; i++) { |
|
|
|
if (handlers[i].type != null) { |
|
|
|
if (handlers[i].type != null) { |
|
|
|
ClassIdentifier ci = |
|
|
|
ClassIdentifier ci = Main.getClassBundle() |
|
|
|
clazz.bundle.getClassIdentifier(handlers[i].type); |
|
|
|
.getClassIdentifier(handlers[i].type); |
|
|
|
if (ci != null) |
|
|
|
if (ci != null) |
|
|
|
handlers[i].type = ci.getFullAlias(); |
|
|
|
handlers[i].type = ci.getFullAlias(); |
|
|
|
} |
|
|
|
} |
|
|
|