Fix up jump inlining, this causes linear scans of the instructions for a
lot of exceptions and is slow. Need to allow inlining in try blocks?
This commit is contained in:
@@ -45,28 +45,31 @@ public class Deob
|
|||||||
|
|
||||||
// remove except RuntimeException
|
// remove except RuntimeException
|
||||||
new RuntimeExceptions().run(group);
|
new RuntimeExceptions().run(group);
|
||||||
|
// the blocks of runtime exceptions may contain interesting things like other obfuscations we identify later, but now that
|
||||||
|
// it can't be reached by the execution phase, those things become confused. so remove blocks here.
|
||||||
|
//new UnusedBlocks().run(group);
|
||||||
|
|
||||||
// remove unused methods
|
// remove unused methods
|
||||||
new UnusedMethods().run(group);
|
//new UnusedMethods().run(group);
|
||||||
|
|
||||||
// remove illegal state exceptions, frees up some parameters
|
// remove illegal state exceptions, frees up some parameters
|
||||||
new IllegalStateExceptions().run(group);
|
//new IllegalStateExceptions().run(group);
|
||||||
|
|
||||||
// remove code blocks that used to be the runtime exception handlers
|
// remove unhit blocks
|
||||||
new UnusedBlocks().run(group);
|
//new UnusedBlocks().run(group);
|
||||||
|
|
||||||
// remove unused parameters
|
// remove unused parameters
|
||||||
new UnusedParameters().run(group);
|
//new UnusedParameters().run(group);
|
||||||
|
|
||||||
// remove jump obfuscation
|
// remove jump obfuscation
|
||||||
new Jumps().run(group);
|
new Jumps().run(group);
|
||||||
|
|
||||||
// remove unused fields
|
// remove unused fields
|
||||||
new UnusedFields().run(group);
|
//new UnusedFields().run(group);
|
||||||
|
|
||||||
//new ModularArithmeticDeobfuscation().run(group);
|
//new ModularArithmeticDeobfuscation().run(group);
|
||||||
|
|
||||||
new RenameUnique().run(group);
|
//new RenameUnique().run(group);
|
||||||
|
|
||||||
saveJar(group, args[1]);
|
saveJar(group, args[1]);
|
||||||
|
|
||||||
|
|||||||
@@ -87,9 +87,20 @@ public class Instructions
|
|||||||
{
|
{
|
||||||
for (Exception e : code.getExceptions().getExceptions())
|
for (Exception e : code.getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
if (i.getPc() >= e.getStart().getPc() && i.getPc() < e.getEnd().getPc())
|
int startIdx = instructions.indexOf(e.getStart()),
|
||||||
|
endIdx = instructions.indexOf(e.getEnd()),
|
||||||
|
thisIdx = instructions.indexOf(i);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
|
assert endIdx > startIdx;
|
||||||
|
|
||||||
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
block.exceptions.add(e);
|
if (!block.exceptions.contains(e))
|
||||||
|
block.exceptions.add(e);
|
||||||
}
|
}
|
||||||
if (e.getHandler() == i)
|
if (e.getHandler() == i)
|
||||||
{
|
{
|
||||||
@@ -98,28 +109,43 @@ public class Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isException(Instruction i)
|
||||||
|
{
|
||||||
|
for (Exception e : code.getExceptions().getExceptions())
|
||||||
|
if (e.getHandler() == i || e.getStart() == i)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isExceptionEnd(Instruction i)
|
||||||
|
{
|
||||||
|
for (Exception e : code.getExceptions().getExceptions())
|
||||||
|
if (e.getEnd() == i)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void buildBlocks()
|
public void buildBlocks()
|
||||||
{
|
{
|
||||||
clearBlockGraph();
|
clearBlockGraph();
|
||||||
buildJumpGraph();
|
buildJumpGraph();
|
||||||
|
|
||||||
Block current = null;
|
Block current = null;
|
||||||
for (Instruction i : instructions)
|
for (int j = 0; j < instructions.size(); ++j)
|
||||||
{
|
{
|
||||||
if (current == null || !i.from.isEmpty())
|
Instruction i = instructions.get(j),
|
||||||
|
next = j + 1 < instructions.size() ? instructions.get(j + 1) : null;
|
||||||
|
|
||||||
|
if (current == null)
|
||||||
{
|
{
|
||||||
if (current != null)
|
|
||||||
{
|
|
||||||
current.end = current.instructions.get(current.instructions.size() - 1);
|
|
||||||
blocks.add(current);
|
|
||||||
}
|
|
||||||
current = new Block();
|
current = new Block();
|
||||||
current.begin = i;
|
current.begin = i;
|
||||||
findExceptionInfo(current, i);
|
|
||||||
}
|
}
|
||||||
i.block = current;
|
|
||||||
current.instructions.add(i);
|
current.instructions.add(i);
|
||||||
if (i.isTerminal())
|
findExceptionInfo(current, i);
|
||||||
|
|
||||||
|
if (i.isTerminal() || next == null || isException(next) || isExceptionEnd(i) || !next.from.isEmpty())
|
||||||
{
|
{
|
||||||
current.end = i;
|
current.end = i;
|
||||||
blocks.add(current);
|
blocks.add(current);
|
||||||
|
|||||||
@@ -43,11 +43,16 @@ public class AThrow extends Instruction
|
|||||||
// jump to instruction handlers that can catch exceptions here
|
// jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
Instruction start = e.getStart(),
|
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
end = e.getEnd();
|
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
|
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
// [start, end)
|
// [start, end)
|
||||||
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
Frame f = frame.dup();
|
Frame f = frame.dup();
|
||||||
f.jump(e.getHandler());
|
f.jump(e.getHandler());
|
||||||
|
|||||||
@@ -41,11 +41,16 @@ public class CheckCast extends Instruction
|
|||||||
// jump to instruction handlers that can catch exceptions here
|
// jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
Instruction start = e.getStart(),
|
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
end = e.getEnd();
|
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
|
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
// [start, end)
|
// [start, end)
|
||||||
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
Frame f = frame.dup();
|
Frame f = frame.dup();
|
||||||
Stack stack = f.getStack();
|
Stack stack = f.getStack();
|
||||||
|
|||||||
@@ -114,11 +114,16 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
|||||||
// jump to instruction handlers that can catch exceptions here
|
// jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
Instruction start = e.getStart(),
|
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
end = e.getEnd();
|
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
|
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
// [start, end)
|
// [start, end)
|
||||||
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
Frame f = frame.dup();
|
Frame f = frame.dup();
|
||||||
Stack stack = f.getStack();
|
Stack stack = f.getStack();
|
||||||
|
|||||||
@@ -101,11 +101,16 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
|||||||
// jump to instruction handlers that can catch exceptions here
|
// jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
Instruction start = e.getStart(),
|
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
end = e.getEnd();
|
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
|
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
// [start, end)
|
// [start, end)
|
||||||
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
Frame f = frame.dup();
|
Frame f = frame.dup();
|
||||||
Stack stack = f.getStack();
|
Stack stack = f.getStack();
|
||||||
|
|||||||
@@ -98,11 +98,16 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
// jump to instruction handlers that can catch exceptions here
|
// jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
Instruction start = e.getStart(),
|
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
end = e.getEnd();
|
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
|
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
// [start, end)
|
// [start, end)
|
||||||
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
Frame f = frame.dup();
|
Frame f = frame.dup();
|
||||||
Stack stack = f.getStack();
|
Stack stack = f.getStack();
|
||||||
|
|||||||
@@ -112,12 +112,16 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
// jump to instruction handlers that can catch exceptions here
|
// jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
{
|
||||||
Instruction start = e.getStart(),
|
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
end = e.getEnd();
|
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
|
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
|
||||||
|
assert startIdx != -1;
|
||||||
|
assert endIdx != -1;
|
||||||
|
assert thisIdx != -1;
|
||||||
|
|
||||||
// XXX this relies on pc?
|
|
||||||
// [start, end)
|
// [start, end)
|
||||||
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
{
|
||||||
Frame f = frame.dup();
|
Frame f = frame.dup();
|
||||||
Stack stack = f.getStack();
|
Stack stack = f.getStack();
|
||||||
|
|||||||
@@ -56,10 +56,6 @@ public class Jumps implements Deobfuscator
|
|||||||
//ins.clearBlocks();
|
//ins.clearBlocks();
|
||||||
ins.clearJumpGraph();
|
ins.clearJumpGraph();
|
||||||
|
|
||||||
// 'from' goes away and is replaced with block.begin
|
|
||||||
for (Instruction in : ilist)
|
|
||||||
in.replace(from, block.begin);
|
|
||||||
|
|
||||||
// remove instructions
|
// remove instructions
|
||||||
for (Instruction in : block.instructions)
|
for (Instruction in : block.instructions)
|
||||||
{
|
{
|
||||||
@@ -67,13 +63,19 @@ public class Jumps implements Deobfuscator
|
|||||||
assert b;
|
assert b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store pos of from
|
int idx = ilist.indexOf(from);
|
||||||
int index = ilist.indexOf(from);
|
boolean b = ilist.remove(from);
|
||||||
ilist.remove(from);
|
assert b;
|
||||||
|
|
||||||
// insert instructions where 'from' was
|
b = ilist.addAll(idx, block.instructions);
|
||||||
for (Instruction in : block.instructions)
|
assert b;
|
||||||
ilist.add(index++, in);
|
|
||||||
|
// replace from with block.begin
|
||||||
|
for (Instruction ins2 : ilist)
|
||||||
|
ins2.replace(from, block.begin);
|
||||||
|
|
||||||
|
for (info.sigterm.deob.attributes.code.Exception e : m.getCode().getExceptions().getExceptions())
|
||||||
|
e.replace(from, block.begin);
|
||||||
|
|
||||||
continue methods;
|
continue methods;
|
||||||
}
|
}
|
||||||
@@ -93,6 +95,7 @@ public class Jumps implements Deobfuscator
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
i = checkBlockGraphOnce(g);
|
i = checkBlockGraphOnce(g);
|
||||||
|
System.out.println("pass " + i);
|
||||||
count += i;
|
count += i;
|
||||||
++passes;
|
++passes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,12 +53,6 @@ public class UnusedFields implements Deobfuscator
|
|||||||
if (get == 0 && set == 0)
|
if (get == 0 && set == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (get == 0)
|
|
||||||
{
|
|
||||||
System.out.println("Field " + field.getFields().getClassFile().getName() + "." + field.getName() + " is set but not get");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user