Start of constant parameter stuff

This commit is contained in:
Adam
2015-07-30 16:39:48 -04:00
parent f27e410f5b
commit 5478fc7385
14 changed files with 227 additions and 23 deletions

View File

@@ -0,0 +1,133 @@
package info.sigterm.deob.deobfuscators;
import info.sigterm.deob.ClassGroup;
import info.sigterm.deob.Deobfuscator;
import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction;
import info.sigterm.deob.attributes.code.instruction.types.PushConstantInstruction;
import info.sigterm.deob.execution.Execution;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.StackContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.map.MultiValueMap;
class ConstantMethodParameter
{
public Method method;
public int paramNum;
public Object value;
}
class MethodGroup
{
public List<Method> methods; // methods that can be invoked
public Collection<Integer> constantParameters; // parameters which are always constant for all invocations
public List<ConstantMethodParameter> cmps = new ArrayList<>(); // cmps for all methods in the group, which hold the values.
}
public class ConstantParameter implements Deobfuscator
{
private MultiValueMap<Method, ConstantMethodParameter> parameters = new MultiValueMap<>();
// methods can be in more than one group because of multiple inheritance with interfaces
private MultiValueMap<Method, MethodGroup> methodGroups = new MultiValueMap<>();
private void findConstantParameter(Execution execution, Method method, InstructionContext invokeCtx)
{
List<StackContext> pops = invokeCtx.getPops();
for (int i = 0; i < method.getDescriptor().size(); ++i)
{
// object is poped first
int offset = method.isStatic() ? 0 : 1;
StackContext ctx = pops.get(offset + i);
if (ctx.getPushed().getInstruction() instanceof PushConstantInstruction)
{
PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction();
if (!(pc.getConstant().getObject() instanceof Integer))
continue;
ConstantMethodParameter cmp = new ConstantMethodParameter();
cmp.method = method;
cmp.paramNum = i;
cmp.value = pc.getConstant().getObject();
parameters.put(method, cmp);
}
}
}
private Collection<Integer> getParametersFor(Method method)
{
Collection<ConstantMethodParameter> params = parameters.getCollection(method);
Collection<Integer> out = new ArrayList<>();
if (params != null)
for (ConstantMethodParameter p : params)
out.add(p.paramNum);
return out;
}
private void findParameters(Execution execution)
{
for (Frame frame : execution.processedFrames)
for (InstructionContext ins : frame.getInstructions())
{
if (!(ins.getInstruction() instanceof InvokeInstruction))
continue;
List<Method> methods = ((InvokeInstruction) ins.getInstruction()).getMethods();
for (Method m : methods)
findConstantParameter(execution, m, ins);
// get common constant indexes from all methods that can possibly be called
Collection<Integer> parameterIndexes = null;
for (Method m : methods)
{
Collection<Integer> idxs = getParametersFor(m);
if (parameterIndexes == null)
parameterIndexes = idxs;
else
parameterIndexes = CollectionUtils.intersection(parameterIndexes, idxs);
}
MethodGroup group = new MethodGroup();
group.methods = methods;
group.constantParameters = parameterIndexes;
// build constant method parameters
for (Method m : methods)
{
Collection<ConstantMethodParameter> params = parameters.getCollection(m);
if (params != null)
group.cmps.addAll(params);
}
// insert
for (Method m : methods)
methodGroups.put(m, group);
}
}
@Override
public void run(ClassGroup group)
{
group.buildClassGraph(); // required for getMethods in the invoke stuff
Execution execution = new Execution(group);
execution.populateInitialMethods();
execution.run();
findParameters(execution);
System.out.println("finished with " + methodGroups.size() + " groups");
}
}