Cleanup (warnings; formatting)
This commit is contained in:
@@ -107,7 +107,7 @@ public class MethodProcessorRunnable implements Runnable {
|
|||||||
|
|
||||||
if (ExceptionDeobfuscator.hasObfuscatedExceptions(graph)) {
|
if (ExceptionDeobfuscator.hasObfuscatedExceptions(graph)) {
|
||||||
DecompilerContext.getLogger().writeMessage("Heavily obfuscated exception ranges found!", IFernflowerLogger.Severity.WARN);
|
DecompilerContext.getLogger().writeMessage("Heavily obfuscated exception ranges found!", IFernflowerLogger.Severity.WARN);
|
||||||
if(!ExceptionDeobfuscator.handleMultipleEntryExceptionRanges(graph)) {
|
if (!ExceptionDeobfuscator.handleMultipleEntryExceptionRanges(graph)) {
|
||||||
DecompilerContext.getLogger().writeMessage("Found multiple entry exception ranges which could not be splitted", IFernflowerLogger.Severity.WARN);
|
DecompilerContext.getLogger().writeMessage("Found multiple entry exception ranges which could not be splitted", IFernflowerLogger.Severity.WARN);
|
||||||
}
|
}
|
||||||
ExceptionDeobfuscator.insertDummyExceptionHandlerBlocks(graph, cl.getBytecodeVersion());
|
ExceptionDeobfuscator.insertDummyExceptionHandlerBlocks(graph, cl.getBytecodeVersion());
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||||
package org.jetbrains.java.decompiler.modules.decompiler;
|
package org.jetbrains.java.decompiler.modules.decompiler;
|
||||||
|
|
||||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||||
@@ -64,18 +64,11 @@ public class SimplifyExprentsHelper {
|
|||||||
for (Statement st : stat.getStats()) {
|
for (Statement st : stat.getStats()) {
|
||||||
res |= simplifyStackVarsStatement(st, setReorderedIfs, ssa, cl);
|
res |= simplifyStackVarsStatement(st, setReorderedIfs, ssa, cl);
|
||||||
|
|
||||||
// collapse composed if's
|
changed = IfHelper.mergeIfs(st, setReorderedIfs) || // collapse composed if's
|
||||||
if (changed = IfHelper.mergeIfs(st, setReorderedIfs)) {
|
buildIff(st, ssa) || // collapse iff ?: statement
|
||||||
break;
|
processClass14 && collapseInlinedClass14(st); // collapse inlined .class property in version 1.4 and before
|
||||||
}
|
|
||||||
|
|
||||||
// collapse iff ?: statement
|
if (changed) {
|
||||||
if (changed = buildIff(st, ssa)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// collapse inlined .class property in version 1.4 and before
|
|
||||||
if (processClass14 && (changed = collapseInlinedClass14(st))) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,7 +452,6 @@ public class SimplifyExprentsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isIPPorIMM2(Exprent first, Exprent second) {
|
private static boolean isIPPorIMM2(Exprent first, Exprent second) {
|
||||||
|
|
||||||
if (first.type != Exprent.EXPRENT_ASSIGNMENT || second.type != Exprent.EXPRENT_ASSIGNMENT) {
|
if (first.type != Exprent.EXPRENT_ASSIGNMENT || second.type != Exprent.EXPRENT_ASSIGNMENT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -467,26 +459,29 @@ public class SimplifyExprentsHelper {
|
|||||||
AssignmentExprent af = (AssignmentExprent)first;
|
AssignmentExprent af = (AssignmentExprent)first;
|
||||||
AssignmentExprent as = (AssignmentExprent)second;
|
AssignmentExprent as = (AssignmentExprent)second;
|
||||||
|
|
||||||
if(as.getRight().type != Exprent.EXPRENT_FUNCTION) {
|
if (as.getRight().type != Exprent.EXPRENT_FUNCTION) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionExprent func = (FunctionExprent)as.getRight();
|
FunctionExprent func = (FunctionExprent)as.getRight();
|
||||||
|
|
||||||
if(func.getFuncType() != FunctionExprent.FUNCTION_ADD && func.getFuncType() != FunctionExprent.FUNCTION_SUB) {
|
if (func.getFuncType() != FunctionExprent.FUNCTION_ADD && func.getFuncType() != FunctionExprent.FUNCTION_SUB) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exprent econd = func.getLstOperands().get(0);
|
Exprent econd = func.getLstOperands().get(0);
|
||||||
Exprent econst = func.getLstOperands().get(1);
|
Exprent econst = func.getLstOperands().get(1);
|
||||||
|
|
||||||
if(econst.type != Exprent.EXPRENT_CONST && econd.type == Exprent.EXPRENT_CONST && func.getFuncType() == FunctionExprent.FUNCTION_ADD) {
|
if (econst.type != Exprent.EXPRENT_CONST && econd.type == Exprent.EXPRENT_CONST && func.getFuncType() == FunctionExprent.FUNCTION_ADD) {
|
||||||
econd = econst;
|
econd = econst;
|
||||||
econst = func.getLstOperands().get(0);
|
econst = func.getLstOperands().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(econst.type == Exprent.EXPRENT_CONST && ((ConstExprent)econst).hasValueOne()) {
|
if (econst.type == Exprent.EXPRENT_CONST &&
|
||||||
if(af.getLeft().equals(econd) && af.getRight().equals(as.getLeft()) && (af.getLeft().getExprentUse() & Exprent.MULTIPLE_USES) != 0) {
|
((ConstExprent)econst).hasValueOne() &&
|
||||||
|
af.getLeft().equals(econd) &&
|
||||||
|
af.getRight().equals(as.getLeft()) &&
|
||||||
|
(af.getLeft().getExprentUse() & Exprent.MULTIPLE_USES) != 0) {
|
||||||
int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_IPP : FunctionExprent.FUNCTION_IMM;
|
int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_IPP : FunctionExprent.FUNCTION_IMM;
|
||||||
|
|
||||||
FunctionExprent ret = new FunctionExprent(type, af.getRight(), func.bytecode);
|
FunctionExprent ret = new FunctionExprent(type, af.getRight(), func.bytecode);
|
||||||
@@ -495,7 +490,6 @@ public class SimplifyExprentsHelper {
|
|||||||
af.setRight(ret);
|
af.setRight(ret);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,12 +311,13 @@ public class ExceptionDeobfuscator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean handleMultipleEntryExceptionRanges(ControlFlowGraph graph) {
|
public static boolean handleMultipleEntryExceptionRanges(ControlFlowGraph graph) {
|
||||||
|
|
||||||
GenericDominatorEngine engine = new GenericDominatorEngine(new IGraph() {
|
GenericDominatorEngine engine = new GenericDominatorEngine(new IGraph() {
|
||||||
|
@Override
|
||||||
public List<? extends IGraphNode> getReversePostOrderList() {
|
public List<? extends IGraphNode> getReversePostOrderList() {
|
||||||
return graph.getReversePostOrder();
|
return graph.getReversePostOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<? extends IGraphNode> getRoots() {
|
public Set<? extends IGraphNode> getRoots() {
|
||||||
return new HashSet<>(Collections.singletonList(graph.getFirst()));
|
return new HashSet<>(Collections.singletonList(graph.getFirst()));
|
||||||
}
|
}
|
||||||
@@ -324,26 +325,26 @@ public class ExceptionDeobfuscator {
|
|||||||
|
|
||||||
engine.initialize();
|
engine.initialize();
|
||||||
|
|
||||||
boolean found = false;
|
boolean found;
|
||||||
|
|
||||||
while(true) {
|
while (true) {
|
||||||
found = false;
|
found = false;
|
||||||
boolean splitted = false;
|
boolean splitted = false;
|
||||||
|
|
||||||
for(ExceptionRangeCFG range : graph.getExceptions()) {
|
for (ExceptionRangeCFG range : graph.getExceptions()) {
|
||||||
Set<BasicBlock> setEntries = getRangeEntries(range);
|
Set<BasicBlock> setEntries = getRangeEntries(range);
|
||||||
|
|
||||||
if(setEntries.size() > 1) { // multiple-entry protected range
|
if (setEntries.size() > 1) { // multiple-entry protected range
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
if(splitExceptionRange(range, setEntries, graph, engine)) {
|
if (splitExceptionRange(range, setEntries, graph, engine)) {
|
||||||
splitted = true;
|
splitted = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!splitted) {
|
if (!splitted) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,11 +353,10 @@ public class ExceptionDeobfuscator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Set<BasicBlock> getRangeEntries(ExceptionRangeCFG range) {
|
private static Set<BasicBlock> getRangeEntries(ExceptionRangeCFG range) {
|
||||||
|
|
||||||
Set<BasicBlock> setEntries = new HashSet<>();
|
Set<BasicBlock> setEntries = new HashSet<>();
|
||||||
Set<BasicBlock> setRange= new HashSet<>(range.getProtectedRange());
|
Set<BasicBlock> setRange = new HashSet<>(range.getProtectedRange());
|
||||||
|
|
||||||
for(BasicBlock block : range.getProtectedRange()) {
|
for (BasicBlock block : range.getProtectedRange()) {
|
||||||
Set<BasicBlock> setPreds = new HashSet<>(block.getPreds());
|
Set<BasicBlock> setPreds = new HashSet<>(block.getPreds());
|
||||||
setPreds.removeAll(setRange);
|
setPreds.removeAll(setRange);
|
||||||
|
|
||||||
@@ -368,18 +368,21 @@ public class ExceptionDeobfuscator {
|
|||||||
return setEntries;
|
return setEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean splitExceptionRange(ExceptionRangeCFG range, Set<BasicBlock> setEntries, ControlFlowGraph graph, GenericDominatorEngine engine) {
|
private static boolean splitExceptionRange(ExceptionRangeCFG range,
|
||||||
|
Set<BasicBlock> setEntries,
|
||||||
for(BasicBlock entry : setEntries) {
|
ControlFlowGraph graph,
|
||||||
|
GenericDominatorEngine engine) {
|
||||||
|
for (BasicBlock entry : setEntries) {
|
||||||
List<BasicBlock> lstSubrangeBlocks = getReachableBlocksRestricted(entry, range, engine);
|
List<BasicBlock> lstSubrangeBlocks = getReachableBlocksRestricted(entry, range, engine);
|
||||||
if(!lstSubrangeBlocks.isEmpty() && lstSubrangeBlocks.size() < range.getProtectedRange().size()) {
|
if (!lstSubrangeBlocks.isEmpty() && lstSubrangeBlocks.size() < range.getProtectedRange().size()) {
|
||||||
// add new range
|
// add new range
|
||||||
ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.getHandler(), range.getExceptionTypes());
|
ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.getHandler(), range.getExceptionTypes());
|
||||||
graph.getExceptions().add(subRange);
|
graph.getExceptions().add(subRange);
|
||||||
// shrink the original range
|
// shrink the original range
|
||||||
range.getProtectedRange().removeAll(lstSubrangeBlocks);
|
range.getProtectedRange().removeAll(lstSubrangeBlocks);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// should not happen
|
// should not happen
|
||||||
DecompilerContext.getLogger().writeMessage("Inconsistency found while splitting protected range", IFernflowerLogger.Severity.WARN);
|
DecompilerContext.getLogger().writeMessage("Inconsistency found while splitting protected range", IFernflowerLogger.Severity.WARN);
|
||||||
}
|
}
|
||||||
@@ -389,7 +392,6 @@ public class ExceptionDeobfuscator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void insertDummyExceptionHandlerBlocks(ControlFlowGraph graph, int bytecode_version) {
|
public static void insertDummyExceptionHandlerBlocks(ControlFlowGraph graph, int bytecode_version) {
|
||||||
|
|
||||||
Map<BasicBlock, Set<ExceptionRangeCFG>> mapRanges = new HashMap<>();
|
Map<BasicBlock, Set<ExceptionRangeCFG>> mapRanges = new HashMap<>();
|
||||||
for (ExceptionRangeCFG range : graph.getExceptions()) {
|
for (ExceptionRangeCFG range : graph.getExceptions()) {
|
||||||
mapRanges.computeIfAbsent(range.getHandler(), k -> new HashSet<>()).add(range);
|
mapRanges.computeIfAbsent(range.getHandler(), k -> new HashSet<>()).add(range);
|
||||||
@@ -399,11 +401,11 @@ public class ExceptionDeobfuscator {
|
|||||||
BasicBlock handler = ent.getKey();
|
BasicBlock handler = ent.getKey();
|
||||||
Set<ExceptionRangeCFG> ranges = ent.getValue();
|
Set<ExceptionRangeCFG> ranges = ent.getValue();
|
||||||
|
|
||||||
if(ranges.size() == 1) {
|
if (ranges.size() == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ExceptionRangeCFG range : ranges) {
|
for (ExceptionRangeCFG range : ranges) {
|
||||||
|
|
||||||
// add some dummy instructions to prevent optimizing away the empty block
|
// add some dummy instructions to prevent optimizing away the empty block
|
||||||
SimpleInstructionSequence seq = new SimpleInstructionSequence();
|
SimpleInstructionSequence seq = new SimpleInstructionSequence();
|
||||||
@@ -428,11 +430,11 @@ public class ExceptionDeobfuscator {
|
|||||||
range.setHandler(dummyBlock);
|
range.setHandler(dummyBlock);
|
||||||
// add common exception edges
|
// add common exception edges
|
||||||
Set<BasicBlock> commonHandlers = new HashSet<>(handler.getSuccExceptions());
|
Set<BasicBlock> commonHandlers = new HashSet<>(handler.getSuccExceptions());
|
||||||
for(BasicBlock pred : lstPredExceptions) {
|
for (BasicBlock pred : lstPredExceptions) {
|
||||||
commonHandlers.retainAll(pred.getSuccExceptions());
|
commonHandlers.retainAll(pred.getSuccExceptions());
|
||||||
}
|
}
|
||||||
// TODO: more sanity checks?
|
// TODO: more sanity checks?
|
||||||
for(BasicBlock commonHandler : commonHandlers) {
|
for (BasicBlock commonHandler : commonHandlers) {
|
||||||
ExceptionRangeCFG commonRange = graph.getExceptionRange(commonHandler, handler);
|
ExceptionRangeCFG commonRange = graph.getExceptionRange(commonHandler, handler);
|
||||||
|
|
||||||
dummyBlock.addSuccessorException(commonHandler);
|
dummyBlock.addSuccessorException(commonHandler);
|
||||||
@@ -443,5 +445,4 @@ public class ExceptionDeobfuscator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user