Use instruction ctx to see if a jump has already happened. Not sure if it works but it runs.
This commit is contained in:
@@ -59,11 +59,11 @@ public class Deob
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("illegal state exception took " + bdur/1000L + " seconds");
|
||||
|
||||
// // remove constant logically dead parameters
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new ConstantParameter().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("constant param took " + bdur/1000L + " seconds");
|
||||
// remove constant logically dead parameters
|
||||
bstart = System.currentTimeMillis();
|
||||
new ConstantParameter().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("constant param took " + bdur/1000L + " seconds");
|
||||
|
||||
// // remove unhit blocks
|
||||
// bstart = System.currentTimeMillis();
|
||||
|
||||
@@ -29,6 +29,8 @@ public class AThrow extends Instruction
|
||||
StackContext exception = stack.pop();
|
||||
ins.pop(exception);
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
frame.stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,43 +37,20 @@ public class CheckCast extends Instruction
|
||||
|
||||
@Override
|
||||
public void execute(Frame frame)
|
||||
{
|
||||
// jump to instruction handlers that can catch exceptions here
|
||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||
{
|
||||
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||
|
||||
assert startIdx != -1;
|
||||
assert endIdx != -1;
|
||||
assert thisIdx != -1;
|
||||
|
||||
// [start, end)
|
||||
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||
{
|
||||
Frame f = frame.dup();
|
||||
Stack stack = f.getStack();
|
||||
|
||||
InstructionContext ins = new InstructionContext(this, f);
|
||||
|
||||
while (stack.getSize() > 0)
|
||||
{
|
||||
StackContext what = stack.pop();
|
||||
ins.pop(what);
|
||||
}
|
||||
|
||||
// push exception back
|
||||
StackContext exception = new StackContext(ins, new Type("java/lang/Exception"));
|
||||
stack.push(exception);
|
||||
|
||||
ins.push(exception);
|
||||
|
||||
f.addInstructionContext(ins);
|
||||
|
||||
f.jump(e.getHandler());
|
||||
}
|
||||
}
|
||||
{
|
||||
InstructionContext ins = new InstructionContext(this, frame);
|
||||
Stack stack = frame.getStack();
|
||||
|
||||
StackContext value = stack.pop();
|
||||
|
||||
ins.pop(value);
|
||||
|
||||
StackContext ctx = new StackContext(ins, value.getType());
|
||||
stack.push(ctx);
|
||||
|
||||
ins.push(ctx);
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import info.sigterm.deob.attributes.code.InstructionType;
|
||||
import info.sigterm.deob.attributes.code.Instructions;
|
||||
import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction;
|
||||
import info.sigterm.deob.execution.Frame;
|
||||
import info.sigterm.deob.execution.InstructionContext;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -62,9 +63,12 @@ public class Goto extends Instruction implements JumpingInstruction
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame e)
|
||||
public void execute(Frame frame)
|
||||
{
|
||||
e.jump(to);
|
||||
InstructionContext ctx = new InstructionContext(this, frame);
|
||||
frame.addInstructionContext(ctx);
|
||||
|
||||
frame.jump(ctx, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import info.sigterm.deob.attributes.code.InstructionType;
|
||||
import info.sigterm.deob.attributes.code.Instructions;
|
||||
import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction;
|
||||
import info.sigterm.deob.execution.Frame;
|
||||
import info.sigterm.deob.execution.InstructionContext;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -46,9 +47,12 @@ public class GotoW extends Instruction implements JumpingInstruction
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame e)
|
||||
public void execute(Frame frame)
|
||||
{
|
||||
e.jump(to);
|
||||
InstructionContext ctx = new InstructionContext(this, frame);
|
||||
frame.addInstructionContext(ctx);
|
||||
|
||||
frame.jump(ctx, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -63,7 +63,7 @@ public class If extends Instruction implements JumpingInstruction, ComparisonIns
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
Frame other = frame.dup();
|
||||
other.jump(to);
|
||||
other.jump(ins, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -64,7 +64,7 @@ public class If0 extends Instruction implements JumpingInstruction, ComparisonIn
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
Frame other = frame.dup();
|
||||
other.jump(to);
|
||||
other.jump(ins, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -111,10 +111,10 @@ public class LookupSwitch extends Instruction implements JumpingInstruction
|
||||
for (Instruction i : branchi)
|
||||
{
|
||||
Frame other = frame.dup();
|
||||
other.jump(i);
|
||||
other.jump(ins, i);
|
||||
}
|
||||
|
||||
frame.jump(defi);
|
||||
frame.jump(ins, defi);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,8 @@ import info.sigterm.deob.attributes.code.Instruction;
|
||||
import info.sigterm.deob.attributes.code.InstructionType;
|
||||
import info.sigterm.deob.attributes.code.Instructions;
|
||||
import info.sigterm.deob.execution.Frame;
|
||||
import info.sigterm.deob.execution.InstructionContext;
|
||||
import info.sigterm.deob.execution.StackContext;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -17,6 +19,11 @@ public class Pop extends Instruction
|
||||
@Override
|
||||
public void execute(Frame frame)
|
||||
{
|
||||
frame.getStack().pop();
|
||||
InstructionContext ins = new InstructionContext(this, frame);
|
||||
|
||||
StackContext value = frame.getStack().pop();
|
||||
ins.pop(value);
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,10 +107,10 @@ public class TableSwitch extends Instruction implements JumpingInstruction
|
||||
for (Instruction i : branchi)
|
||||
{
|
||||
Frame other = frame.dup();
|
||||
other.jump(i);
|
||||
other.jump(ins, i);
|
||||
}
|
||||
|
||||
frame.jump(defi);
|
||||
frame.jump(ins, defi);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import info.sigterm.deob.attributes.code.InstructionType;
|
||||
import info.sigterm.deob.attributes.code.Instructions;
|
||||
import info.sigterm.deob.attributes.code.instruction.types.ReturnInstruction;
|
||||
import info.sigterm.deob.execution.Frame;
|
||||
import info.sigterm.deob.execution.InstructionContext;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -18,6 +19,9 @@ public class VReturn extends Instruction implements ReturnInstruction
|
||||
@Override
|
||||
public void execute(Frame frame)
|
||||
{
|
||||
InstructionContext ins = new InstructionContext(this, frame);
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
frame.stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import info.sigterm.deob.attributes.code.Instructions;
|
||||
import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction;
|
||||
import info.sigterm.deob.attributes.code.instruction.types.WideInstruction;
|
||||
import info.sigterm.deob.execution.Frame;
|
||||
import info.sigterm.deob.execution.InstructionContext;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -47,9 +48,13 @@ public class Wide extends Instruction implements LVTInstruction
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Frame e)
|
||||
public void execute(Frame frame)
|
||||
{
|
||||
ins.execute(e);
|
||||
InstructionContext ctx = new InstructionContext(this, frame);
|
||||
|
||||
ins.execute(frame);
|
||||
|
||||
frame.addInstructionContext(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -131,7 +131,7 @@ public class ConstantParameter implements Deobfuscator
|
||||
{
|
||||
PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction();
|
||||
|
||||
if (!(pc.getConstant().getObject() instanceof Integer) && (!(pc.getConstant().getObject() instanceof Byte)))
|
||||
if (!(pc.getConstant().getObject() instanceof Number))
|
||||
continue;
|
||||
|
||||
ConstantMethodParameter cmp = new ConstantMethodParameter();
|
||||
|
||||
@@ -13,6 +13,8 @@ import info.sigterm.deob.attributes.code.Instructions;
|
||||
import info.sigterm.deob.attributes.code.instructions.LookupSwitch;
|
||||
import info.sigterm.deob.attributes.code.instructions.TableSwitch;
|
||||
import info.sigterm.deob.pool.NameAndType;
|
||||
import org.apache.commons.collections4.MultiMap;
|
||||
import org.apache.commons.collections4.map.MultiValueMap;
|
||||
|
||||
public class Frame
|
||||
{
|
||||
@@ -23,7 +25,7 @@ public class Frame
|
||||
private Stack stack;
|
||||
private Variables variables;
|
||||
private List<InstructionContext> instructions = new ArrayList<>(); // instructions executed in this frame
|
||||
private Map<Instruction, List<Instruction>> visited; // shared
|
||||
private MultiValueMap<InstructionContext, Instruction> visited = new MultiValueMap<>(); // shared
|
||||
|
||||
public Frame(Execution execution, Method method)
|
||||
{
|
||||
@@ -35,8 +37,6 @@ public class Frame
|
||||
stack = new Stack(code.getMaxStack());
|
||||
variables = new Variables(code.getMaxLocals());
|
||||
|
||||
visited = new HashMap<>();
|
||||
|
||||
// initialize LVT
|
||||
int pos = 0;
|
||||
if (!method.isStatic())
|
||||
@@ -60,7 +60,11 @@ public class Frame
|
||||
this.cur = other.cur;
|
||||
this.stack = new Stack(other.stack);
|
||||
this.variables = new Variables(other.variables);
|
||||
//this.instructions = new ArrayList<>(other.instructions); // deep?
|
||||
this.visited = other.visited;
|
||||
|
||||
// for (InstructionContext ctx : other.instructions)
|
||||
// instructions.add(new InstructionContext(other, ctx));
|
||||
}
|
||||
|
||||
public Frame dup()
|
||||
@@ -160,16 +164,14 @@ public class Frame
|
||||
private void processExceptions(Instruction i)
|
||||
{
|
||||
Code code = method.getCode();
|
||||
InstructionContext ictx = instructions.get(instructions.size() - 1);
|
||||
|
||||
assert ictx.getInstruction() == i;
|
||||
|
||||
for (Exception e : code.getExceptions().getExceptions())
|
||||
{
|
||||
if (e.getStart() == i)
|
||||
{
|
||||
if (hasJumped(i, e.getHandler()))
|
||||
continue;
|
||||
|
||||
doJump(i, e.getHandler());
|
||||
|
||||
Frame f = dup();
|
||||
Stack stack = f.getStack();
|
||||
|
||||
@@ -182,57 +184,33 @@ public class Frame
|
||||
|
||||
ins.push(ctx);
|
||||
|
||||
// at this point maybe cur != i, and f.jump() uses cur, so
|
||||
f.cur = e.getHandler();
|
||||
assert f.executing;
|
||||
f.jump(ictx, e.getHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doJump(Instruction from, Instruction to)
|
||||
private boolean hasJumped(InstructionContext from, Instruction to)
|
||||
{
|
||||
List<Instruction> l = visited.get(from);
|
||||
if (l == null)
|
||||
{
|
||||
List<Instruction> l2 = new ArrayList<>();
|
||||
l2.add(to);
|
||||
visited.put(from, l2);
|
||||
}
|
||||
else
|
||||
{
|
||||
l.add(to);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasJumped(Instruction from, Instruction to)
|
||||
{
|
||||
List<Instruction> i = visited.get(from);
|
||||
Collection<Instruction> i = visited.getCollection(from);
|
||||
if (i != null && i.contains(to))
|
||||
return true;
|
||||
|
||||
if (i == null)
|
||||
{
|
||||
i = new ArrayList<>();
|
||||
visited.put(from, i);
|
||||
}
|
||||
|
||||
i.add(to);
|
||||
visited.put(from, to);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void jump(Instruction to)
|
||||
public void jump(InstructionContext from, Instruction to)
|
||||
{
|
||||
assert to != null;
|
||||
assert to.getInstructions() == method.getCode().getInstructions();
|
||||
assert method.getCode().getInstructions().getInstructions().contains(to);
|
||||
|
||||
if (hasJumped(cur, to))
|
||||
if (hasJumped(from, to))
|
||||
{
|
||||
executing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
doJump(cur, to);
|
||||
cur = to;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import info.sigterm.deob.Method;
|
||||
import info.sigterm.deob.attributes.code.Instruction;
|
||||
import java.util.Objects;
|
||||
|
||||
public class InstructionContext
|
||||
{
|
||||
@@ -77,4 +78,38 @@ public class InstructionContext
|
||||
// start recursively removing
|
||||
ctx.removeStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (!(other instanceof InstructionContext))
|
||||
return false;
|
||||
|
||||
InstructionContext ic = (InstructionContext) other;
|
||||
|
||||
if (ins != ic.ins)
|
||||
return false;
|
||||
|
||||
if (getPops().size() != ic.getPops().size())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < getPops().size(); ++i)
|
||||
{
|
||||
StackContext ours = getPops().get(i),
|
||||
theirs = ic.getPops().get(i);
|
||||
|
||||
if (!ours.getPushed().equals(theirs.getPushed()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 7;
|
||||
hash = 73 * hash + Objects.hashCode(this.ins);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package info.sigterm.deob.execution;
|
||||
|
||||
public class StackContext
|
||||
{
|
||||
private InstructionContext pushed; // instruction which pushed this
|
||||
private InstructionContext popped; // instruction which popped this
|
||||
private Type type; // type of this
|
||||
public InstructionContext pushed; // instruction which pushed this
|
||||
public InstructionContext popped; // instruction which popped this
|
||||
public Type type; // type of this
|
||||
|
||||
public StackContext(InstructionContext pushed, Type type)
|
||||
{
|
||||
@@ -23,7 +23,7 @@ public class StackContext
|
||||
this.pushed = pushed;
|
||||
type = new Type(c.getName());
|
||||
}
|
||||
|
||||
|
||||
public InstructionContext getPushed()
|
||||
{
|
||||
return pushed;
|
||||
|
||||
Reference in New Issue
Block a user