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