Cleanup (warnings; formatting)

master
Roman Shevchenko 6 years ago
parent 5424600265
commit f8ed069d76
  1. 2
      src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java
  2. 56
      src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
  3. 75
      src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java

@ -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 = buildIff(st, ssa)) {
break;
}
// collapse inlined .class property in version 1.4 and before if (changed) {
if (processClass14 && (changed = collapseInlinedClass14(st))) {
break; break;
} }
} }
@ -459,44 +452,45 @@ 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;
} }
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() &&
int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_IPP : FunctionExprent.FUNCTION_IMM; af.getLeft().equals(econd) &&
af.getRight().equals(as.getLeft()) &&
FunctionExprent ret = new FunctionExprent(type, af.getRight(), func.bytecode); (af.getLeft().getExprentUse() & Exprent.MULTIPLE_USES) != 0) {
ret.setImplicitType(VarType.VARTYPE_INT); int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_IPP : FunctionExprent.FUNCTION_IMM;
af.setRight(ret); FunctionExprent ret = new FunctionExprent(type, af.getRight(), func.bytecode);
return true; ret.setImplicitType(VarType.VARTYPE_INT);
}
af.setRight(ret);
return true;
} }
return false; return false;
} }

@ -311,52 +311,52 @@ 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()));
} }
}); });
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;
} }
} }
return !found; return !found;
} }
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);
@ -367,19 +367,22 @@ public class ExceptionDeobfuscator {
return setEntries; return setEntries;
} }
private static boolean splitExceptionRange(ExceptionRangeCFG range, Set<BasicBlock> setEntries, ControlFlowGraph graph, GenericDominatorEngine engine) {
for(BasicBlock entry : setEntries) { private static boolean splitExceptionRange(ExceptionRangeCFG range,
Set<BasicBlock> 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,22 +392,21 @@ 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);
} }
for (Entry<BasicBlock, Set<ExceptionRangeCFG>> ent : mapRanges.entrySet()) { for (Entry<BasicBlock, Set<ExceptionRangeCFG>> ent : mapRanges.entrySet()) {
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();
seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{0}), -1); seq.addInstruction(Instruction.create(CodeConstants.opc_bipush, false, CodeConstants.GROUP_GENERAL, bytecode_version, new int[]{0}), -1);
@ -414,11 +416,11 @@ public class ExceptionDeobfuscator {
dummyBlock.setSeq(seq); dummyBlock.setSeq(seq);
graph.getBlocks().addWithKey(dummyBlock, dummyBlock.id); graph.getBlocks().addWithKey(dummyBlock, dummyBlock.id);
// only exception predecessors from this range considered // only exception predecessors from this range considered
List<BasicBlock> lstPredExceptions = new ArrayList<>(handler.getPredExceptions()); List<BasicBlock> lstPredExceptions = new ArrayList<>(handler.getPredExceptions());
lstPredExceptions.retainAll(range.getProtectedRange()); lstPredExceptions.retainAll(range.getProtectedRange());
// replace predecessors // replace predecessors
for (BasicBlock pred : lstPredExceptions) { for (BasicBlock pred : lstPredExceptions) {
pred.replaceSuccessor(handler, dummyBlock); pred.replaceSuccessor(handler, dummyBlock);
@ -428,20 +430,19 @@ 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);
commonRange.getProtectedRange().add(dummyBlock); commonRange.getProtectedRange().add(dummyBlock);
} }
dummyBlock.addSuccessor(handler); dummyBlock.addSuccessor(handler);
} }
} }
} }
} }
Loading…
Cancel
Save