From 0d21d49d2de7bba32e12f98e822312a3598ce778 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 5 May 2015 13:36:54 -0400 Subject: [PATCH] Can detect unused parameters --- src/main/java/info/sigterm/deob/Deob.java | 45 +++++++++++++++++++ src/main/java/info/sigterm/deob/Method.java | 37 +++++++++++++++ .../deob/attributes/code/Instructions.java | 5 +++ .../info/sigterm/deob/pool/NameAndType.java | 8 ++++ 4 files changed, 95 insertions(+) diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index 771dad7f38..440a8be1d9 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -1,6 +1,9 @@ package info.sigterm.deob; import info.sigterm.deob.execution.Execution; +import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.attributes.code.Instruction; +import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -10,6 +13,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Enumeration; +import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; @@ -39,6 +43,7 @@ public class Deob group.buildCallGraph(); checkCallGraph(group); + checkParameters(group); //execute(group); @@ -89,4 +94,44 @@ public class Deob } System.out.println("Removed " + i + " methods"); } + + private static boolean parameterUsed(int num, List lv) + { + if (lv.isEmpty()) + return false; + + // these instructions aren't in order so we can't do this + //LVTInstruction ins = (LVTInstruction) lv.get(0); + //return !ins.store(); + return true; + } + + private static void checkParameters(ClassGroup group) + { + int count = 0; + for (ClassFile cf : group.getClasses()) + { + for (Method m : new ArrayList<>(cf.getMethods().getMethods())) + { + int start = m.isStatic() ? 0 : 1; + NameAndType nat = m.getNameAndType(); + int numParams = start + nat.getNumberOfArgs(); + + for (int i = start; i < numParams; ++i) + { + List lv = m.findLVTInstructionsForVariable(i); + + if (lv == null) + continue; + + if (!parameterUsed(i, lv)) + { + System.out.println("Not used param " + i + " of " + cf.getName() + " " + m.getName() + " static: " + m.isStatic()); + ++count; + } + } + } + } + System.out.println("Detected " + count + " unused parameters"); + } } diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index 707d5d9d4b..b4180b4a44 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -4,7 +4,9 @@ import info.sigterm.deob.attributes.AttributeType; import info.sigterm.deob.attributes.Attributes; import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.code.Instruction; +import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import info.sigterm.deob.callgraph.Node; +import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.pool.UTF8; import java.io.DataInputStream; @@ -15,6 +17,8 @@ import java.util.List; public class Method { + public static final int ACC_STATIC = 0x8; + private Methods methods; private short accessFlags; @@ -65,6 +69,17 @@ public class Method UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(descriptorIndex); return u.getValue(); } + + public NameAndType getNameAndType() + { + // this isn't really from the pool .. + return new NameAndType(methods.getClassFile().getPool(), nameIndex, descriptorIndex); + } + + public boolean isStatic() + { + return (accessFlags & ACC_STATIC) != 0; + } public Code getCode() { @@ -129,4 +144,26 @@ public class Method callsTo.add(node); method.callsFrom.add(node); } + + @SuppressWarnings("unchecked") + public List findLVTInstructionsForVariable(int index) + { + List list = new ArrayList<>(); + + if (getCode() == null) + return null; + + for (Instruction ins : getCode().getInstructions().getInstructions()) + if (ins instanceof LVTInstruction) + { + LVTInstruction lv = (LVTInstruction) ins; + + if (lv.getVariableIndex() != index) + continue; + + list.add((T) ins); + } + + return list; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java index 1d19ffa23a..aa6ed37024 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -50,6 +50,11 @@ public class Instructions buildJumpGraph(); } + public List getInstructions() + { + return instructions; + } + public void write(DataOutputStream out) throws IOException { ByteArrayOutputStream b = new ByteArrayOutputStream(); diff --git a/src/main/java/info/sigterm/deob/pool/NameAndType.java b/src/main/java/info/sigterm/deob/pool/NameAndType.java index 034514e6c7..2f69d4b116 100644 --- a/src/main/java/info/sigterm/deob/pool/NameAndType.java +++ b/src/main/java/info/sigterm/deob/pool/NameAndType.java @@ -22,6 +22,14 @@ public class NameAndType extends PoolEntry nameIndex = is.readUnsignedShort(); descriptorIndex = is.readUnsignedShort(); } + + public NameAndType(ConstantPool pool, int name, int type) + { + super(pool, ConstantType.NAME_AND_TYPE); + + this.nameIndex = name; + this.descriptorIndex = type; + } public java.lang.String getName() {