From 1526cea2a5391cd0d3c43a269c7432b274e5cabd Mon Sep 17 00:00:00 2001 From: Graham Date: Tue, 24 Mar 2020 21:40:46 +0000 Subject: [PATCH] Annotate variables in catch statements with @Pc --- .../java/decompiler/code/cfg/ControlFlowGraph.java | 4 ++-- .../java/decompiler/code/cfg/ExceptionRangeCFG.java | 8 +++++++- .../decompiler/modules/decompiler/DomHelper.java | 2 +- .../decompiler/modules/decompiler/StatEdge.java | 8 +++++++- .../deobfuscator/ExceptionDeobfuscator.java | 2 +- .../modules/decompiler/stats/CatchAllStatement.java | 13 ++++++++++--- .../modules/decompiler/stats/CatchStatement.java | 4 ++-- .../modules/decompiler/stats/Statement.java | 2 +- 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java index 08223cf..5f9068a 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java @@ -358,7 +358,7 @@ public class ControlFlowGraph implements CodeConstants { block.addSuccessorException(handle); } - ExceptionRangeCFG range = new ExceptionRangeCFG(protectedRange, handle, handler.exceptionClass == null + ExceptionRangeCFG range = new ExceptionRangeCFG(protectedRange, handle, handler.handler, handler.exceptionClass == null ? null : Collections.singletonList(handler.exceptionClass)); mapRanges.put(key, range); @@ -654,7 +654,7 @@ public class ControlFlowGraph implements CodeConstants { if (setBoth.size() == lstRange.size()) { lstNewRange = new ArrayList<>(); ExceptionRangeCFG newRange = new ExceptionRangeCFG(lstNewRange, - mapNewNodes.get(range.getHandler().id), range.getExceptionTypes()); + mapNewNodes.get(range.getHandler().id), range.getHandlerBytecodeOffset(), range.getExceptionTypes()); exceptions.add(newRange); } else { diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java b/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java index ce143aa..3c0abe4 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java @@ -10,11 +10,13 @@ import java.util.stream.Collectors; public class ExceptionRangeCFG { private final List protectedRange; // FIXME: replace with set private BasicBlock handler; + private int handlerBytecodeOffset; private List exceptionTypes; - public ExceptionRangeCFG(List protectedRange, BasicBlock handler, List exceptionType) { + public ExceptionRangeCFG(List protectedRange, BasicBlock handler, int handlerBytecodeOffset, List exceptionType) { this.protectedRange = protectedRange; this.handler = handler; + this.handlerBytecodeOffset = handlerBytecodeOffset; if (exceptionType != null) { this.exceptionTypes = new ArrayList<>(exceptionType); @@ -54,6 +56,10 @@ public class ExceptionRangeCFG { this.handler = handler; } + public int getHandlerBytecodeOffset() { + return handlerBytecodeOffset; + } + public List getProtectedRange() { return protectedRange; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java index 2c5e3eb..23a5c7b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java @@ -77,7 +77,7 @@ public class DomHelper { ExceptionRangeCFG range = graph.getExceptionRange(succex, block); if (!range.isCircular()) { - stat.addSuccessor(new StatEdge(stat, stsuccex, range.getExceptionTypes())); + stat.addSuccessor(new StatEdge(stat, stsuccex, range.getHandlerBytecodeOffset(), range.getExceptionTypes())); } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java index c481c0a..0d6b281 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java @@ -26,6 +26,7 @@ public class StatEdge { private Statement source; private Statement destination; + private int destinationBytecodeOffset = -1; private List exceptions; @@ -46,8 +47,9 @@ public class StatEdge { this.destination = destination; } - public StatEdge(Statement source, Statement destination, List exceptions) { + public StatEdge(Statement source, Statement destination, int destinationBytecodeOffset, List exceptions) { this(TYPE_EXCEPTION, source, destination); + this.destinationBytecodeOffset = destinationBytecodeOffset; if (exceptions != null) { this.exceptions = new ArrayList<>(exceptions); } @@ -77,6 +79,10 @@ public class StatEdge { this.destination = destination; } + public int getDestinationBytecodeOffset() { + return destinationBytecodeOffset; + } + public List getExceptions() { return this.exceptions; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java index 810291d..612ccdc 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java @@ -376,7 +376,7 @@ public class ExceptionDeobfuscator { List lstSubrangeBlocks = getReachableBlocksRestricted(entry, range, engine); if (!lstSubrangeBlocks.isEmpty() && lstSubrangeBlocks.size() < range.getProtectedRange().size()) { // add new range - ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.getHandler(), range.getExceptionTypes()); + ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.getHandler(), range.getHandlerBytecodeOffset(), range.getExceptionTypes()); graph.getExceptions().add(subRange); // shrink the original range range.getProtectedRange().removeAll(lstSubrangeBlocks); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java index 376abe5..680d8b5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java @@ -53,9 +53,16 @@ public class CatchAllStatement extends Statement { } } + int bytecodeOffset = -1; + for (StatEdge edge : head.getSuccessorEdges(StatEdge.TYPE_EXCEPTION)) { + if (edge.getDestination() == handler) { + bytecodeOffset = edge.getDestinationBytecodeOffset(); + } + } + vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Throwable"), - DecompilerContext.getVarProcessor())); + DecompilerContext.getVarProcessor(), -1, bytecodeOffset)); } @@ -165,13 +172,13 @@ public class CatchAllStatement extends Statement { if (this.monitor != null) { cas.monitor = new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), VarType.VARTYPE_INT, - DecompilerContext.getVarProcessor()); + DecompilerContext.getVarProcessor(), -1, -1); } if (!this.vars.isEmpty()) { cas.vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Throwable"), - DecompilerContext.getVarProcessor())); + DecompilerContext.getVarProcessor(), -1, this.vars.get(0).getBytecodeOffset())); } return cas; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java index 652931a..58f6933 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java @@ -45,7 +45,7 @@ public class CatchStatement extends Statement { vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), new VarType(CodeConstants.TYPE_OBJECT, 0, edge.getExceptions().get(0)), // FIXME: for now simply the first type. Should get the first common superclass when possible. - DecompilerContext.getVarProcessor())); + DecompilerContext.getVarProcessor(), -1, edge.getDestinationBytecodeOffset())); } } @@ -187,7 +187,7 @@ public class CatchStatement extends Statement { cs.exctstrings.add(new ArrayList<>(exc)); cs.vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), new VarType(CodeConstants.TYPE_OBJECT, 0, exc.get(0)), - DecompilerContext.getVarProcessor())); + DecompilerContext.getVarProcessor(), -1, this.vars.get(0).getBytecodeOffset())); } return cs; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java index b5e8213..3d7ab62 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java @@ -184,7 +184,7 @@ public class Statement implements IMatchable { if (setHandlers.contains(handler)) { if (!setNodes.containsKey(handler.id)) { - stat.addSuccessor(new StatEdge(stat, handler, edge.getExceptions())); + stat.addSuccessor(new StatEdge(stat, handler, edge.getDestinationBytecodeOffset(), edge.getExceptions())); } } }