From 14a7b63707b0d79566743993b48a56890eebea98 Mon Sep 17 00:00:00 2001 From: Skylot <118523+skylot@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:48:27 +0000 Subject: [PATCH] chore: apply common code style --- jadx-core/build.gradle.kts | 2 + .../src/main/java/jadx/api/JadxArgs.java | 2 +- .../core/dex/trycatch/ExceptionHandler.java | 2 +- .../core/dex/trycatch/TryCatchBlockAttr.java | 36 ++- .../java/jadx/core/dex/trycatch/TryEdge.java | 26 +-- .../dex/trycatch/TryEdgeScopeGroupMap.java | 136 +++++------ .../dex/visitors/MethodThrowsVisitor.java | 4 +- .../dex/visitors/finaly/CentralityState.java | 57 ++--- .../visitors/finaly/FinallyExtractInfo.java | 90 ------- .../core/dex/visitors/finaly/InsnsSlice.java | 79 ------- .../visitors/finaly/MarkFinallyVisitor.java | 221 ++++++++---------- .../finaly/SameInstructionsStrategyImpl.java | 33 ++- .../visitors/finaly/TryCatchEdgeBlockMap.java | 95 ++++---- .../traverser/GlobalTraverserSourceState.java | 6 +- .../finaly/traverser/TraverserController.java | 110 ++++----- .../finaly/traverser/TraverserException.java | 2 +- .../DuplicatedTraverserStateFactory.java | 10 +- .../factory/TraverserStateFactory.java | 7 +- .../AbstractActivePathTraverserHandler.java | 2 +- .../AbstractBlockPathTraverserHandler.java | 4 +- .../handlers/BaseBlockTraverserHandler.java | 24 +- ...InstructionActivePathTraverserHandler.java | 26 +-- .../MergePathActivePathTraverserHandler.java | 138 ++++++----- .../PredecessorBlockPathTraverserHandler.java | 24 +- ...cessorMergeActivePathTraverserHandler.java | 106 ++++----- .../AwaitingInsnCompareTraverserState.java | 27 +-- .../traverser/state/ISourceBlockState.java | 2 +- ...fiedScopeWithTerminatorTraverserState.java | 30 +-- .../state/NewBlockTraverserState.java | 27 +-- .../state/NoBlockTraverserState.java | 26 +-- .../RecoveredFromCacheTraverserState.java | 26 +-- .../state/TerminalTraverserState.java | 28 +-- .../state/TraverserActivePathState.java | 181 ++++++-------- .../traverser/state/TraverserBlockInfo.java | 42 ++-- .../state/TraverserGlobalCommonState.java | 18 +- .../traverser/state/TraverserState.java | 31 ++- .../UnknownAdvanceStrategyTraverserState.java | 29 +-- .../ImplicitInsnBlockTraverserVisitor.java | 28 +-- .../PathEndBlockTraverserVisitor.java | 31 ++- .../PredecessorBlockTraverserVisitor.java | 23 +- .../AbstractTraverserComparatorVisitor.java | 2 +- ...uctionBlockComparatorTraverserVisitor.java | 118 +++++----- .../dex/visitors/rename/SourceFileRename.java | 2 +- .../visitors/typeinference/TypeCompare.java | 4 +- .../main/java/jadx/core/utils/BetterName.java | 10 +- .../main/java/jadx/core/utils/ListUtils.java | 8 +- .../java/jadx/core/xmlgen/ResNameUtils.java | 4 +- .../core/xmlgen/ResTableBinaryParser.java | 4 +- .../main/java/jadx/core/xmlgen/ResXmlGen.java | 2 +- .../core/xmlgen/StringFormattedCheck.java | 2 +- .../main/java/jadx/core/xmlgen/XMLChar.java | 8 +- .../jadx/core/xmlgen/entry/EntryConfig.java | 2 +- 52 files changed, 806 insertions(+), 1151 deletions(-) delete mode 100644 jadx-core/src/main/java/jadx/core/dex/visitors/finaly/FinallyExtractInfo.java delete mode 100644 jadx-core/src/main/java/jadx/core/dex/visitors/finaly/InsnsSlice.java diff --git a/jadx-core/build.gradle.kts b/jadx-core/build.gradle.kts index 9b6821ec6..572f438ec 100644 --- a/jadx-core/build.gradle.kts +++ b/jadx-core/build.gradle.kts @@ -54,4 +54,6 @@ tasks.named("test") { // exclude temp tests exclude("**/tmp/*") + + // maxHeapSize = "4g" } diff --git a/jadx-core/src/main/java/jadx/api/JadxArgs.java b/jadx-core/src/main/java/jadx/api/JadxArgs.java index 882a1978b..20b6df608 100644 --- a/jadx-core/src/main/java/jadx/api/JadxArgs.java +++ b/jadx-core/src/main/java/jadx/api/JadxArgs.java @@ -498,7 +498,7 @@ public class JadxArgs implements Closeable { */ @Deprecated public void setUseSourceNameAsClassAlias(boolean useSourceNameAsClassAlias) { - final var useSourceNameAsClassNameAlias = UseSourceNameAsClassNameAlias.create(useSourceNameAsClassAlias); + var useSourceNameAsClassNameAlias = UseSourceNameAsClassNameAlias.create(useSourceNameAsClassAlias); setUseSourceNameAsClassNameAlias(useSourceNameAsClassNameAlias); } diff --git a/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java b/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java index ee7162be3..e0edcb490 100644 --- a/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java @@ -166,7 +166,7 @@ public class ExceptionHandler { LOG.warn("No support yet for finding bottom block of try body with multipe inner trys"); return null; } - final TryCatchBlockAttr searchForTryBody; + TryCatchBlockAttr searchForTryBody; if (handlerTryBlock.getInnerTryBlocks().isEmpty()) { searchForTryBody = handlerTryBlock; } else { diff --git a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlockAttr.java b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlockAttr.java index dfd3fcecd..c108cf366 100644 --- a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlockAttr.java +++ b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlockAttr.java @@ -183,17 +183,15 @@ public class TryCatchBlockAttr implements IJadxAttribute { public void getFallthroughTryEdges(List edges, List exploredBlocks, List exploredTrys) { List mergedHandlers = getMergedHandlers(); - Set searchBlocks = new HashSet<>(); - searchBlocks.addAll(getBlocks()); + Set searchBlocks = new HashSet<>(getBlocks()); for (ExceptionHandler handler : mergedHandlers) { - searchBlocks.removeAll(handler.getBlocks()); + handler.getBlocks().forEach(searchBlocks::remove); } - BlockNode sourceBlock = BlockUtils.getTopBlock(new ArrayList<>(searchBlocks)); - - exploredTrys.add(this); - - exploreTryPath(edges, sourceBlock, searchBlocks, exploredBlocks, exploredTrys); + if (sourceBlock != null) { + exploredTrys.add(this); + exploreTryPath(edges, sourceBlock, searchBlocks, exploredBlocks, exploredTrys); + } } public List getTryEdges() { @@ -221,19 +219,19 @@ public class TryCatchBlockAttr implements IJadxAttribute { exploredBlocks.add(successor); if (successor.contains(AFlag.LOOP_END)) { - final var loopsAttrList = successor.get(AType.LOOP); - final List loops = loopsAttrList.getList(); - final List loopStartBlocks = new LinkedList<>(); - for (final LoopInfo loop : loops) { + var loopsAttrList = successor.get(AType.LOOP); + List loops = loopsAttrList.getList(); + List loopStartBlocks = new LinkedList<>(); + for (LoopInfo loop : loops) { loopStartBlocks.add(loop.getStart()); - final List loopEdges = loop.getExitEdges(); - for (final Edge loopEdge : loopEdges) { + List loopEdges = loop.getExitEdges(); + for (Edge loopEdge : loopEdges) { if (loopEdge.getTarget() == successor) { loopStartBlocks.add(loopEdge.getSource()); } } } - final boolean includesAllLoopStart = ListUtils.allMatch(loopStartBlocks, exploredBlocks::contains); + boolean includesAllLoopStart = ListUtils.allMatch(loopStartBlocks, exploredBlocks::contains); if (!includesAllLoopStart) { edges.add(new TryEdge(blk, successor, TryEdgeType.LOOP_EXIT)); continue; @@ -241,7 +239,7 @@ public class TryCatchBlockAttr implements IJadxAttribute { } boolean isPathToAnySearchBlock = false; - for (final BlockNode searchBlock : searchBlocks) { + for (BlockNode searchBlock : searchBlocks) { if (BlockUtils.isPathExists(successor, searchBlock)) { isPathToAnySearchBlock = true; break; @@ -329,7 +327,7 @@ public class TryCatchBlockAttr implements IJadxAttribute { public List getMergedHandlers() { boolean hasInnerBlocks = !getInnerTryBlocks().isEmpty(); - final List mergedHandlers; + List mergedHandlers; if (hasInnerBlocks) { // collect handlers from this and all inner blocks // (intentionally not using recursive collect for now) @@ -343,7 +341,7 @@ public class TryCatchBlockAttr implements IJadxAttribute { return Collections.unmodifiableList(mergedHandlers); } - public Map getEdgeBlockMap(MethodNode mth) { + public Map getEdgeBlockMap() { List edges = getTryEdges(); Map blockMap = new HashMap<>(); for (TryEdge edge : edges) { @@ -353,7 +351,7 @@ public class TryCatchBlockAttr implements IJadxAttribute { } public TryEdgeScopeGroupMap getExecutionScopeGroups(MethodNode mth) { - Map handlerBlocks = getEdgeBlockMap(mth); + Map handlerBlocks = getEdgeBlockMap(); TryEdgeScopeGroupMap scopeGroups = new TryEdgeScopeGroupMap(mth, this, handlerBlocks.size()); scopeGroups.populateFromEdges(handlerBlocks); diff --git a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdge.java b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdge.java index f577c6be5..1f11013b0 100644 --- a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdge.java +++ b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdge.java @@ -19,15 +19,15 @@ public final class TryEdge { private final Optional handler; private final TryEdgeType type; - public TryEdge(final BlockNode source, final BlockNode target, final TryEdgeType type) { + public TryEdge(BlockNode source, BlockNode target, TryEdgeType type) { this(source, target, type, Optional.empty()); } - public TryEdge(final BlockNode source, final BlockNode target, final @NotNull ExceptionHandler handler) { + public TryEdge(BlockNode source, BlockNode target, @NotNull ExceptionHandler handler) { this(source, target, TryEdgeType.HANDLER, Optional.of(handler)); } - public TryEdge(final BlockNode source, final BlockNode target, final TryEdgeType type, final Optional handler) { + public TryEdge(BlockNode source, BlockNode target, TryEdgeType type, Optional handler) { this.source = source; this.target = target; this.handler = handler; @@ -41,7 +41,7 @@ public final class TryEdge { } @Override - public final String toString() { + public String toString() { StringBuilder sb = new StringBuilder("TryEdge: ["); sb.append(type); sb.append(' '); @@ -58,12 +58,12 @@ public final class TryEdge { } @Override - public final boolean equals(Object obj) { + public boolean equals(Object obj) { if (!(obj instanceof TryEdge)) { return false; } - final TryEdge other = (TryEdge) obj; + TryEdge other = (TryEdge) obj; return source.equals(other.source) && target.equals(other.target) @@ -72,31 +72,31 @@ public final class TryEdge { } @Override - public final int hashCode() { + public int hashCode() { return Objects.hash(source, target, type, handler); } - public final BlockNode getSource() { + public BlockNode getSource() { return source; } - public final BlockNode getTarget() { + public BlockNode getTarget() { return target; } - public final TryEdgeType getType() { + public TryEdgeType getType() { return type; } - public final boolean isHandlerExit() { + public boolean isHandlerExit() { return type == TryEdgeType.HANDLER; } - public final boolean isNotHandlerExit() { + public boolean isNotHandlerExit() { return !isHandlerExit(); } - public final ExceptionHandler getExceptionHandler() { + public ExceptionHandler getExceptionHandler() { if (!isHandlerExit()) { throw new JadxRuntimeException("Attempted to get the exception handler of a non-handler edge type"); } diff --git a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdgeScopeGroupMap.java b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdgeScopeGroupMap.java index 927cbeb02..ac985b6b0 100644 --- a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdgeScopeGroupMap.java +++ b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryEdgeScopeGroupMap.java @@ -28,7 +28,7 @@ public final class TryEdgeScopeGroupMap implements Map> underlyingMap; - public TryEdgeScopeGroupMap(final MethodNode mth, final TryCatchBlockAttr tryCatch, final int initialCapacity) { + public TryEdgeScopeGroupMap(MethodNode mth, TryCatchBlockAttr tryCatch, int initialCapacity) { this.tryCatch = tryCatch; underlyingMap = new HashMap<>(initialCapacity); } @Override - public final void clear() { + public void clear() { underlyingMap.clear(); } @Override - public final boolean containsKey(Object key) { + public boolean containsKey(Object key) { return underlyingMap.containsKey(key); } @Override - public final boolean containsValue(Object value) { + public boolean containsValue(Object value) { if (!(value instanceof TryEdge)) { return false; } - final TryEdge edge = (TryEdge) value; + TryEdge edge = (TryEdge) value; return underlyingMap.containsKey(edge); } @Override - public final Set>> entrySet() { + public Set>> entrySet() { return underlyingMap.entrySet(); } @Override - public final Map get(Object key) { + public Map get(Object key) { return underlyingMap.get(key); } @Override - public final boolean isEmpty() { + public boolean isEmpty() { return underlyingMap.isEmpty(); } @Override - public final Set keySet() { + public Set keySet() { return underlyingMap.keySet(); } @Override - public final Map put(TryEdge key, Map value) { + public Map put(TryEdge key, Map value) { return underlyingMap.put(key, value); } @Override - public final void putAll(Map> otherMap) { + public void putAll(Map> otherMap) { underlyingMap.putAll(otherMap); } @Override - public final Map remove(Object key) { + public Map remove(Object key) { return underlyingMap.remove(key); } @Override - public final int size() { + public int size() { return underlyingMap.size(); } @Override - public final Collection> values() { + public Collection> values() { return underlyingMap.values(); } - public final boolean hasMergedEdges() { + public boolean hasMergedEdges() { return !mergedEdges.isEmpty(); } - public final List> getMergedScopes() { + public List> getMergedScopes() { return mergedEdges; } - public final void populateFromEdges(final Map edges) { + public void populateFromEdges(Map edges) { mergeSameScopes(edges); - for (final TryEdge edge : edges.keySet()) { - final BlockNode edgeBlock = edges.get(edge); + for (TryEdge edge : edges.keySet()) { + BlockNode edgeBlock = edges.get(edge); - final Map handlerFallthroughMap = createEdgeTerminusMap(edges, edge, edgeBlock); + Map handlerFallthroughMap = createEdgeTerminusMap(edges, edge, edgeBlock); put(edge, handlerFallthroughMap); } } @@ -134,30 +134,30 @@ public final class TryEdgeScopeGroupMap implements Map> getScopeEnds(final MethodNode mth) { - final Map> groups = new HashMap<>(); + public Map> getScopeEnds(MethodNode mth) { + Map> groups = new HashMap<>(); // A list containing pairs of edges where there are no shared common clean successors between the // two handlers. This usually indicates that these edge pairs must be processed differently. - final List isolatedEdgePairs = new LinkedList<>(); + List isolatedEdgePairs = new LinkedList<>(); - for (final TryEdge mergeEdgeA : keySet()) { - final Pair edgeMergedPair = getMergedNodeFromEdge(mergeEdgeA); + for (TryEdge mergeEdgeA : keySet()) { + Pair edgeMergedPair = getMergedNodeFromEdge(mergeEdgeA); if (edgeMergedPair != null) { continue; } - final Map handlerRelations = get(mergeEdgeA); + Map handlerRelations = get(mergeEdgeA); - final List scopeEnds = new ArrayList<>(handlerRelations.size()); - for (final TryEdge mergeEdgeB : handlerRelations.keySet()) { - final Pair mergedPairFromRelation = getMergedNodeFromEdge(mergeEdgeB); + List scopeEnds = new ArrayList<>(handlerRelations.size()); + for (TryEdge mergeEdgeB : handlerRelations.keySet()) { + Pair mergedPairFromRelation = getMergedNodeFromEdge(mergeEdgeB); if (mergedPairFromRelation != null && mergedPairFromRelation.getFirst() == mergeEdgeA) { continue; } - final BlockNode sharedTerminator = handlerRelations.get(mergeEdgeB); + BlockNode sharedTerminator = handlerRelations.get(mergeEdgeB); if (sharedTerminator == null) { // There are no common clean succesors between the two handlers. @@ -172,20 +172,20 @@ public final class TryEdgeScopeGroupMap implements Map groupingHandlers = new LinkedList<>(); + List groupingHandlers = new LinkedList<>(); groupingHandlers.add(mergeEdgeA); groups.put(topGrouping, groupingHandlers); } } - for (final TryEdge isolatedEdge : isolatedEdgePairs) { + for (TryEdge isolatedEdge : isolatedEdgePairs) { boolean isInList = false; - for (final List foundEdges : groups.values()) { + for (List foundEdges : groups.values()) { if (foundEdges.contains(isolatedEdge)) { isInList = true; break; @@ -203,14 +203,14 @@ public final class TryEdgeScopeGroupMap implements Map successorBlocks = BlockUtils.collectAllSuccessors(mth, target, true); - final BlockNode cleanSuccessorEnd = BlockUtils.getBottomBlock(successorBlocks); + BlockNode target = isolatedEdge.getTarget(); + List successorBlocks = BlockUtils.collectAllSuccessors(mth, target, true); + BlockNode cleanSuccessorEnd = BlockUtils.getBottomBlock(successorBlocks); if (cleanSuccessorEnd == null) { throw new JadxRuntimeException("Could not find bottom clean successor for isolated try edge"); } - final List scopeTerminusList; + List scopeTerminusList; if (groups.containsKey(cleanSuccessorEnd)) { scopeTerminusList = groups.get(cleanSuccessorEnd); } else { @@ -221,9 +221,9 @@ public final class TryEdgeScopeGroupMap implements Map pair : mergedEdges) { - final TryEdge keptEdge = pair.getFirst(); - final TryEdge removedEdge = pair.getSecond(); + for (Pair pair : mergedEdges) { + TryEdge keptEdge = pair.getFirst(); + TryEdge removedEdge = pair.getSecond(); if (keptEdge.isHandlerExit() && !tryCatch.getHandlers().contains(keptEdge.getExceptionHandler())) { continue; @@ -238,14 +238,14 @@ public final class TryEdgeScopeGroupMap implements Map edgesWithTerminus : groups.values()) { + for (List edgesWithTerminus : groups.values()) { if (edgesWithTerminus.contains(keptEdge)) { edgesWithTerminus.remove(keptEdge); } } - final BlockNode terminus = get(keptEdge).get(removedEdge); - final List terminusEdges; + BlockNode terminus = get(keptEdge).get(removedEdge); + List terminusEdges; if (!groups.containsKey(terminus)) { terminusEdges = new LinkedList<>(); terminusEdges.add(keptEdge); @@ -261,7 +261,7 @@ public final class TryEdgeScopeGroupMap implements Map getMergedNodeFromEdge(final TryEdge edge) { + private Pair getMergedNodeFromEdge(TryEdge edge) { for (Pair pair : mergedEdges) { if (pair.getSecond() == edge) { return pair; @@ -270,17 +270,17 @@ public final class TryEdgeScopeGroupMap implements Map createEdgeTerminusMap(final Map edgeStartMap, final TryEdge edge, - final BlockNode edgeStart) { - final Map scopeRelations = new HashMap<>(edgeStartMap.size() - 1); - for (final TryEdge otherEdge : edgeStartMap.keySet()) { + private Map createEdgeTerminusMap(Map edgeStartMap, TryEdge edge, + BlockNode edgeStart) { + Map scopeRelations = new HashMap<>(edgeStartMap.size() - 1); + for (TryEdge otherEdge : edgeStartMap.keySet()) { if (edge == otherEdge) { continue; } - final BlockNode otherEdgeStart = edgeStartMap.get(otherEdge); + BlockNode otherEdgeStart = edgeStartMap.get(otherEdge); - final boolean eitherEdgeIsHandler = edge.isHandlerExit() || otherEdge.isHandlerExit(); + boolean eitherEdgeIsHandler = edge.isHandlerExit() || otherEdge.isHandlerExit(); if (otherEdgeStart == edgeStart && eitherEdgeIsHandler) { continue; } @@ -298,14 +298,14 @@ public final class TryEdgeScopeGroupMap implements Map postDomHandler = new LinkedList<>(); + List postDomHandler = new LinkedList<>(); BlockNode currentBlock = edgeStart; while (currentBlock != null) { postDomHandler.add(currentBlock); @@ -322,7 +322,7 @@ public final class TryEdgeScopeGroupMap implements Map mergeSameScopes(final Map handlers) { - final List> exceptionHandlers = new ArrayList<>(handlers.entrySet()); + private Map mergeSameScopes(Map handlers) { + List> exceptionHandlers = new ArrayList<>(handlers.entrySet()); - final List> handlerPairs = new LinkedList<>(); + List> handlerPairs = new LinkedList<>(); for (int i = 0; i < exceptionHandlers.size(); i++) { for (int j = i + 1; j < exceptionHandlers.size(); j++) { TryEdgeScope a = new TryEdgeScope(exceptionHandlers.get(i).getKey(), exceptionHandlers.get(i).getValue()); @@ -347,22 +347,22 @@ public final class TryEdgeScopeGroupMap implements Map simplifiedScopes = new HashMap<>(handlers); + Map simplifiedScopes = new HashMap<>(handlers); int i = 0; while (i < handlerPairs.size()) { - final Pair handlerPair = handlerPairs.get(i); + Pair handlerPair = handlerPairs.get(i); - final TryEdgeScope edgeScopeA = handlerPair.getFirst(); - final TryEdgeScope edgeScopeB = handlerPair.getSecond(); - final BlockNode edgeBlockA = edgeScopeA.block; - final BlockNode edgeBlockB = edgeScopeB.block; - final boolean pathExists = BlockUtils.isPathExists(edgeBlockA, edgeBlockB) || BlockUtils.isPathExists(edgeBlockB, edgeBlockA); + TryEdgeScope edgeScopeA = handlerPair.getFirst(); + TryEdgeScope edgeScopeB = handlerPair.getSecond(); + BlockNode edgeBlockA = edgeScopeA.block; + BlockNode edgeBlockB = edgeScopeB.block; + boolean pathExists = BlockUtils.isPathExists(edgeBlockA, edgeBlockB) || BlockUtils.isPathExists(edgeBlockB, edgeBlockA); if (pathExists) { BlockNode bottomBlock = BlockUtils.getBottomBlock(List.of(edgeBlockA, edgeBlockB)); // The two blocks are within the same scope - remove these from the matrix - final TryEdge removeHandler = edgeBlockA != bottomBlock ? edgeScopeA.edge : edgeScopeB.edge; - final TryEdge keepHandler = edgeBlockA == bottomBlock ? edgeScopeA.edge : edgeScopeB.edge; + TryEdge removeHandler = edgeBlockA != bottomBlock ? edgeScopeA.edge : edgeScopeB.edge; + TryEdge keepHandler = edgeBlockA == bottomBlock ? edgeScopeA.edge : edgeScopeB.edge; simplifiedScopes.remove(removeHandler); handlerPairs.remove(i); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/MethodThrowsVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/MethodThrowsVisitor.java index 342bb8329..ef26472f4 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/MethodThrowsVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/MethodThrowsVisitor.java @@ -114,7 +114,7 @@ public class MethodThrowsVisitor extends AbstractVisitor { return; } try { - blocks: for (final BlockNode block : mth.getBasicBlocks()) { + blocks: for (BlockNode block : mth.getBasicBlocks()) { // Skip e.g. throw instructions of synchronized regions boolean skipExceptions = block.contains(AFlag.REMOVE) || block.contains(AFlag.DONT_GENERATE); Set excludedExceptions = new HashSet<>(); @@ -127,7 +127,7 @@ public class MethodThrowsVisitor extends AbstractVisitor { excludedExceptions.add(handler.getArgType().toString()); } } - for (final InsnNode insn : block.getInstructions()) { + for (InsnNode insn : block.getInstructions()) { checkInsn(mth, insn, excludedExceptions, skipExceptions); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/CentralityState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/CentralityState.java index 363c33e29..9e673c487 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/CentralityState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/CentralityState.java @@ -25,14 +25,14 @@ public final class CentralityState { private boolean allowsCentral = true; private boolean allowsNonStartingNode; - public CentralityState(final SameInstructionsStrategy sameInstructionsStrategy, final boolean allowsNonStartingNode) { + public CentralityState(SameInstructionsStrategy sameInstructionsStrategy, boolean allowsNonStartingNode) { this.sameInstructionsStrategy = sameInstructionsStrategy; this.allowsNonStartingNode = allowsNonStartingNode; } @Override - public final String toString() { - final StringBuilder sb = new StringBuilder("CentralityState - "); + public String toString() { + StringBuilder sb = new StringBuilder("CentralityState - "); if (allowsCentral) { sb.append("allows central"); } else { @@ -46,31 +46,31 @@ public final class CentralityState { return sb.toString(); } - public final SameInstructionsStrategy getSameInstructionsStrategy() { + public SameInstructionsStrategy getSameInstructionsStrategy() { return sameInstructionsStrategy; } - public final boolean getAllowsCentral() { + public boolean getAllowsCentral() { return allowsCentral; } - public final void setAllowsCentral(final boolean allowsCentral) { + public void setAllowsCentral(boolean allowsCentral) { this.allowsCentral = allowsCentral; } - public final boolean getAllowsNonStartingNode() { + public boolean getAllowsNonStartingNode() { return allowsNonStartingNode; } - public final void setAllowsNonStartingNode(final boolean allowsNonStartingNode) { + public void setAllowsNonStartingNode(boolean allowsNonStartingNode) { this.allowsNonStartingNode = allowsNonStartingNode; } - public final void addAllowableOutput(final RegisterArg allowableOutput) { + public void addAllowableOutput(RegisterArg allowableOutput) { allowableOutputArguments.add(allowableOutput); } - public final void addAllowableOutputs(final Collection allowableOutputs) { + public void addAllowableOutputs(Collection allowableOutputs) { allowableOutputArguments.addAll(allowableOutputs); } @@ -79,36 +79,31 @@ public final class CentralityState { * * @param allowableOutputInsn The instruction to retrieve the list of inputs from. */ - public final void addAllowableOutputs(final InsnNode allowableOutputInsn) { - final List registerArgs = new LinkedList<>(); - for (final InsnArg arg : allowableOutputInsn.getArgList()) { + public void addAllowableOutputs(InsnNode allowableOutputInsn) { + List registerArgs = new LinkedList<>(); + for (InsnArg arg : allowableOutputInsn.getArgList()) { if (!(arg instanceof RegisterArg)) { continue; } - registerArgs.add((RegisterArg) arg); } - registerArgs.forEach(this::addAllowableOutput); } - public final boolean hasAllowableOutput(final InsnNode insn) { + public boolean hasAllowableOutput(InsnNode insn) { if (allowableOutputArguments.isEmpty()) { return false; } - - final RegisterArg registerArg; + RegisterArg registerArg; if (insn.getResult() != null) { registerArg = insn.getResult(); } else { registerArg = null; } - if (registerArg == null) { return false; } - - for (final RegisterArg allowableOutput : allowableOutputArguments) { + for (RegisterArg allowableOutput : allowableOutputArguments) { if (allowableOutput.equals(registerArg)) { return true; } @@ -117,26 +112,22 @@ public final class CentralityState { } @SuppressWarnings("unused") - public final boolean hasAllowableInputs(final InsnNode insn) { + public boolean hasAllowableInputs(InsnNode insn) { if (allowableOutputArguments.isEmpty()) { return false; } - - final List registerArgs = new ArrayList<>(); - - for (final InsnArg arg : insn.getArgList()) { + List registerArgs = new ArrayList<>(); + for (InsnArg arg : insn.getArgList()) { if (arg instanceof RegisterArg) { registerArgs.add((RegisterArg) arg); } } - if (registerArgs.isEmpty() || allowableOutputArguments.isEmpty()) { return false; } - - for (final RegisterArg regArg : registerArgs) { + for (RegisterArg regArg : registerArgs) { boolean foundMatch = false; - for (final RegisterArg allowableOutput : allowableOutputArguments) { + for (RegisterArg allowableOutput : allowableOutputArguments) { if (regArg.equals(allowableOutput)) { foundMatch = true; break; @@ -149,14 +140,14 @@ public final class CentralityState { return true; } - public final CentralityState duplicate() { - final CentralityState state = new CentralityState(sameInstructionsStrategy, allowsNonStartingNode); + public CentralityState duplicate() { + CentralityState state = new CentralityState(sameInstructionsStrategy, allowsNonStartingNode); state.allowsCentral = allowsCentral; state.allowableOutputArguments.addAll(allowableOutputArguments); return state; } - public final Set getAllowableOutputArguments() { + public Set getAllowableOutputArguments() { return allowableOutputArguments; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/FinallyExtractInfo.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/FinallyExtractInfo.java deleted file mode 100644 index 7974cbe24..000000000 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/FinallyExtractInfo.java +++ /dev/null @@ -1,90 +0,0 @@ -package jadx.core.dex.visitors.finaly; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import jadx.core.dex.nodes.BlockNode; -import jadx.core.dex.nodes.InsnNode; -import jadx.core.dex.nodes.MethodNode; -import jadx.core.dex.trycatch.ExceptionHandler; -import jadx.core.utils.Utils; - -public class FinallyExtractInfo { - private final MethodNode mth; - private final ExceptionHandler finallyHandler; - private final List allHandlerBlocks; - private final List duplicateSlices = new ArrayList<>(); - private final Set checkedBlocks = new HashSet<>(); - private final InsnsSlice finallyInsnsSlice = new InsnsSlice(); - private final BlockNode startBlock; - - private InsnsSlice curDupSlice; - private List curDupInsns; - private int curDupInsnsOffset; - - public FinallyExtractInfo(MethodNode mth, ExceptionHandler finallyHandler, BlockNode startBlock, List allHandlerBlocks) { - this.mth = mth; - this.finallyHandler = finallyHandler; - this.startBlock = startBlock; - this.allHandlerBlocks = allHandlerBlocks; - } - - public MethodNode getMth() { - return mth; - } - - public ExceptionHandler getFinallyHandler() { - return finallyHandler; - } - - public List getAllHandlerBlocks() { - return allHandlerBlocks; - } - - public InsnsSlice getFinallyInsnsSlice() { - return finallyInsnsSlice; - } - - public List getDuplicateSlices() { - return duplicateSlices; - } - - public Set getCheckedBlocks() { - return checkedBlocks; - } - - public BlockNode getStartBlock() { - return startBlock; - } - - public InsnsSlice getCurDupSlice() { - return curDupSlice; - } - - public void setCurDupSlice(InsnsSlice curDupSlice) { - this.curDupSlice = curDupSlice; - } - - public List getCurDupInsns() { - return curDupInsns; - } - - public int getCurDupInsnsOffset() { - return curDupInsnsOffset; - } - - public void setCurDupInsns(List insns, int offset) { - this.curDupInsns = insns; - this.curDupInsnsOffset = offset; - } - - @Override - public String toString() { - return "FinallyExtractInfo{" - + "\n finally:\n " + finallyInsnsSlice - + "\n dups:\n " + Utils.listToString(duplicateSlices, "\n ") - + "\n}"; - } -} diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/InsnsSlice.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/InsnsSlice.java deleted file mode 100644 index c00320c46..000000000 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/InsnsSlice.java +++ /dev/null @@ -1,79 +0,0 @@ -package jadx.core.dex.visitors.finaly; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.Nullable; - -import jadx.core.dex.nodes.BlockNode; -import jadx.core.dex.nodes.InsnNode; - -public class InsnsSlice { - private final List insnsList = new ArrayList<>(); - private final Map insnMap = new IdentityHashMap<>(); - private boolean complete; - - public void addInsn(InsnNode insn, BlockNode block) { - insnsList.add(insn); - insnMap.put(insn, block); - } - - public void addBlock(BlockNode block) { - for (InsnNode insn : block.getInstructions()) { - addInsn(insn, block); - } - } - - public void addInsns(BlockNode block, int startIndex, int endIndex) { - List insns = block.getInstructions(); - for (int i = startIndex; i < endIndex; i++) { - addInsn(insns.get(i), block); - } - } - - @Nullable - public BlockNode getBlock(InsnNode insn) { - return insnMap.get(insn); - } - - public List getInsnsList() { - return insnsList; - } - - public Set getBlocks() { - Set set = new LinkedHashSet<>(); - for (InsnNode insn : insnsList) { - set.add(insnMap.get(insn)); - } - return set; - } - - public void resetIncomplete() { - if (!complete) { - insnsList.clear(); - insnMap.clear(); - } - } - - public boolean isComplete() { - return complete; - } - - public void setComplete(boolean complete) { - this.complete = complete; - } - - @Override - public String toString() { - return "{[" - + insnsList.stream().map(insn -> insn.getType().toString()).collect(Collectors.joining(", ")) - + ']' - + (complete ? " complete" : "") - + '}'; - } -} diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java index 38b884b7e..24aa5b076 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java @@ -68,59 +68,50 @@ import jadx.core.utils.exceptions.JadxRuntimeException; runBefore = ConstInlineVisitor.class ) public class MarkFinallyVisitor extends AbstractVisitor { - private static final Logger LOG = LoggerFactory.getLogger(MarkFinallyVisitor.class); private static final class TryExtractInfo { - private final TryCatchBlockAttr tryBlock; private final TryEdgeScopeGroupMap scopeGroups; private final ExceptionHandler finallyHandler; private final Map> scopeTerminusGroups; private final TryCatchEdgeBlockMap handlerScopes; - private final Set allHandlerBlocks; private final Set rethrowBlocks; private Set completeFinallyBlocks = null; private Set completeCandidateBlocks = null; - private TryExtractInfo(final TryCatchBlockAttr tryBlock, final TryEdgeScopeGroupMap scopeGroups, - final ExceptionHandler finallyHandler, final Map> fallthroughGroups, - final TryCatchEdgeBlockMap handlerScopes) { + private TryExtractInfo(TryCatchBlockAttr tryBlock, TryEdgeScopeGroupMap scopeGroups, + ExceptionHandler finallyHandler, Map> fallthroughGroups, + TryCatchEdgeBlockMap handlerScopes) { this.tryBlock = tryBlock; this.scopeGroups = scopeGroups; this.finallyHandler = finallyHandler; this.scopeTerminusGroups = fallthroughGroups; this.handlerScopes = handlerScopes; - this.allHandlerBlocks = new HashSet<>(); this.rethrowBlocks = new HashSet<>(); - - for (final List handlerBlocks : handlerScopes.values()) { - allHandlerBlocks.addAll(handlerBlocks); - } } } @Override - public void visit(final MethodNode mth) { + public void visit(MethodNode mth) { if (mth.isNoCode() || mth.isNoExceptionHandlers()) { return; } try { boolean implicitHandlerRemoved = false; - final List tryBlocks = mth.getAll(AType.TRY_BLOCKS_LIST); - - final List processRequiredTryBlocks = new ArrayList<>(); + List tryBlocks = mth.getAll(AType.TRY_BLOCKS_LIST); + List processRequiredTryBlocks = new ArrayList<>(); // Search through all exception handlers and: // - Remove implicit handlers // - Mark non-implicit handlers to be searched for a finally block - for (final TryCatchBlockAttr tryBlock : tryBlocks) { - final TryExtractInfo tryInfo = getTryBlockData(mth, tryBlock); + for (TryCatchBlockAttr tryBlock : tryBlocks) { + TryExtractInfo tryInfo = getTryBlockData(mth, tryBlock); if (tryInfo == null) { continue; } - final List cutHandlerBlocks = cutHandlerBlocks(tryInfo, tryInfo.finallyHandler); + List cutHandlerBlocks = cutHandlerBlocks(mth, tryInfo, tryInfo.finallyHandler); if (cutHandlerBlocks == null) { continue; } @@ -137,33 +128,30 @@ public class MarkFinallyVisitor extends AbstractVisitor { // Search through all non-implicit handlers and search for a finally block. boolean finallyExtracted = false; - for (final TryCatchBlockAttr tryBlock : processRequiredTryBlocks) { + for (TryCatchBlockAttr tryBlock : processRequiredTryBlocks) { // Refresh scope groups now due to implicit handlers - final TryExtractInfo tryInfo = getTryBlockData(mth, tryBlock); - + TryExtractInfo tryInfo = getTryBlockData(mth, tryBlock); if (tryInfo == null) { continue; } - - cutHandlerBlocks(tryInfo, tryInfo.finallyHandler); - + cutHandlerBlocks(mth, tryInfo, tryInfo.finallyHandler); finallyExtracted |= processTryBlock(mth, tryInfo); } // If any handlers have been merged, remove them if (finallyExtracted) { resetTryBlocks(mth, tryBlocks); } - } catch (final Exception e) { - LOG.error(e.getMessage()); + } catch (Exception e) { + LOG.error("MarkFinallyVisitor error", e); undoFinallyVisitor(mth); mth.addWarnComment("Undo finally extract visitor", e); } } - private static void resetTryBlocks(final MethodNode mth, final List tryBlocks) { + private static void resetTryBlocks(MethodNode mth, List tryBlocks) { mth.clearExceptionHandlers(); // remove merged or empty try blocks from list in method attribute - final List clearedTryBlocks = new ArrayList<>(tryBlocks); + List clearedTryBlocks = new ArrayList<>(tryBlocks); if (clearedTryBlocks.removeIf(TryCatchBlockAttr::isImplicitOrMerged)) { mth.remove(AType.TRY_BLOCKS_LIST); mth.addAttr(AType.TRY_BLOCKS_LIST, clearedTryBlocks); @@ -180,28 +168,24 @@ public class MarkFinallyVisitor extends AbstractVisitor { * @param tryBlock The try block to determine the scope information of. * @return The handler identified as the "all" handler. */ - @Nullable - private static TryExtractInfo getTryBlockData(final MethodNode mth, final TryCatchBlockAttr tryBlock) { + private static @Nullable TryExtractInfo getTryBlockData(MethodNode mth, TryCatchBlockAttr tryBlock) { if (tryBlock.isMerged()) { return null; } - // Find the all handler ExceptionHandler allHandler = null; - for (final ExceptionHandler excHandler : tryBlock.getHandlers()) { + for (ExceptionHandler excHandler : tryBlock.getHandlers()) { if (excHandler.isCatchAll()) { allHandler = excHandler; break; } } - if (allHandler == null) { return null; } - - final TryEdgeScopeGroupMap scopeGroups = tryBlock.getExecutionScopeGroups(mth); - final var fallthroughGroups = tryBlock.getHandlerFallthroughGroups(mth, scopeGroups); - final var handlerScopes = TryCatchEdgeBlockMap.getAllInScope(mth, tryBlock, scopeGroups, allHandler, fallthroughGroups); + TryEdgeScopeGroupMap scopeGroups = tryBlock.getExecutionScopeGroups(mth); + var fallthroughGroups = tryBlock.getHandlerFallthroughGroups(mth, scopeGroups); + var handlerScopes = TryCatchEdgeBlockMap.getAllInScope(mth, tryBlock, scopeGroups, allHandler, fallthroughGroups); return new TryExtractInfo(tryBlock, scopeGroups, allHandler, fallthroughGroups, handlerScopes); } @@ -214,14 +198,13 @@ public class MarkFinallyVisitor extends AbstractVisitor { * @param tryInfo The try block information. * @return Whether a finally block has been successfully extracted. */ - private static boolean processTryBlock(final MethodNode mth, final TryExtractInfo tryInfo) { + private static boolean processTryBlock(MethodNode mth, TryExtractInfo tryInfo) { if (tryInfo.rethrowBlocks.isEmpty()) { return false; } - if (extractFinally(mth, tryInfo)) { - for (final BlockNode rethrowBlock : tryInfo.rethrowBlocks) { - final InsnNode lastInsn = BlockUtils.getLastInsn(rethrowBlock); + for (BlockNode rethrowBlock : tryInfo.rethrowBlocks) { + InsnNode lastInsn = BlockUtils.getLastInsn(rethrowBlock); if (lastInsn == null) { continue; } @@ -232,30 +215,33 @@ public class MarkFinallyVisitor extends AbstractVisitor { return false; } - @Nullable - private static List cutHandlerBlocks(final TryExtractInfo tryInfo, final ExceptionHandler handler) { - final BlockNode handlerBlock = handler.getHandlerBlock(); - final List handlerBlocks = tryInfo.handlerScopes.getBlocksForHandler(handler); + private static @Nullable List cutHandlerBlocks(MethodNode mth, TryExtractInfo tryInfo, ExceptionHandler handler) { + BlockNode handlerBlock = handler.getHandlerBlock(); + List handlerBlocks = tryInfo.handlerScopes.getBlocksForHandler(handler); if (handlerBlocks == null) { return null; } - final InsnNode handlerFinalInsn = BlockUtils.getFirstInsn(handlerBlock); + InsnNode handlerFinalInsn = BlockUtils.getFirstInsn(handlerBlock); if (handlerFinalInsn != null && handlerFinalInsn.getType() == InsnType.MOVE_EXCEPTION) { handlerBlocks.remove(handlerBlock); // exclude block with 'move-exception' } - final BlockNode bottomBlock = BlockUtils.getBottomBlock(handlerBlocks); - final List pathExits = BlockUtils.followEmptyUpPathWithinSet(bottomBlock, handlerBlocks); + BlockNode bottomBlock = BlockUtils.getBottomBlock(handlerBlocks); + if (bottomBlock == null) { + mth.addWarn("Bottom block not found for handler: " + handler); + return handlerBlocks; + } + List pathExits = BlockUtils.followEmptyUpPathWithinSet(bottomBlock, handlerBlocks); if (pathExits.isEmpty()) { return handlerBlocks; } - for (final BlockNode pathExit : pathExits) { + for (BlockNode pathExit : pathExits) { // For this to be able to extract a finally, we must ensure that all paths into the handler's logic // end with a THROW equal to the output of the move-exception instruction located at the start of // this handler, if any. - final InsnNode bottomBlockLastInsn = BlockUtils.getLastInsn(pathExit); - final boolean isValidPathExit = bottomBlockLastInsn != null + InsnNode bottomBlockLastInsn = BlockUtils.getLastInsn(pathExit); + boolean isValidPathExit = bottomBlockLastInsn != null && handlerFinalInsn != null && bottomBlockLastInsn.getType() == InsnType.THROW && bottomBlockLastInsn.getArgsCount() > 0 @@ -264,8 +250,8 @@ public class MarkFinallyVisitor extends AbstractVisitor { return handlerBlocks; } } - final List cutHandlerBlocks = new ArrayList<>(handlerBlocks); - for (final BlockNode pathExit : pathExits) { + List cutHandlerBlocks = new ArrayList<>(handlerBlocks); + for (BlockNode pathExit : pathExits) { cutHandlerBlocks.remove(pathExit); removeEmptyUpPath(cutHandlerBlocks, pathExit); tryInfo.rethrowBlocks.add(pathExit); @@ -279,7 +265,7 @@ public class MarkFinallyVisitor extends AbstractVisitor { * @param cutHandlerBlocks The cut handler blocks of the all handler. * @return Whether the try block is implicit and has been removed. */ - private static boolean attemptRemoveImplicitHandlers(final List cutHandlerBlocks, final TryExtractInfo tryInfo) { + private static boolean attemptRemoveImplicitHandlers(List cutHandlerBlocks, TryExtractInfo tryInfo) { if (!(cutHandlerBlocks.isEmpty() || BlockUtils.isAllBlocksEmpty(cutHandlerBlocks))) { return false; } @@ -291,24 +277,22 @@ public class MarkFinallyVisitor extends AbstractVisitor { /** * Search and mark common code from 'try' block and 'handlers'. */ - private static boolean extractFinally(final MethodNode mth, final TryExtractInfo tryInfo) { + private static boolean extractFinally(MethodNode mth, TryExtractInfo tryInfo) { // Get all handlers from this and inner try blocks. - final boolean hasInnerBlocks = !tryInfo.tryBlock.getInnerTryBlocks().isEmpty(); - final List handlers = getHandlersForTryCatch(tryInfo.tryBlock); + boolean hasInnerBlocks = !tryInfo.tryBlock.getInnerTryBlocks().isEmpty(); + List handlers = getHandlersForTryCatch(tryInfo.tryBlock); if (handlers.isEmpty()) { return false; } - - final Map> insns = findCommonInsns(mth, tryInfo); + Map> insns = findCommonInsns(mth, tryInfo); if (insns == null || insns.isEmpty()) { return false; } - - final Set ignoredFinallyInsns = new HashSet<>(); - final Set ignoredCandidateInsns = new HashSet<>(); - final Map> insnMap = new HashMap<>(); - for (final InsnNode finallyInsn : insns.keySet()) { - final List candidateInsns = insns.get(finallyInsn); + Set ignoredFinallyInsns = new HashSet<>(); + Set ignoredCandidateInsns = new HashSet<>(); + Map> insnMap = new HashMap<>(); + for (InsnNode finallyInsn : insns.keySet()) { + List candidateInsns = insns.get(finallyInsn); // For an instruction to have matched, the number of times it has been found must be // equal to the number of edges that the exception handler has which aren't the @@ -323,17 +307,15 @@ public class MarkFinallyVisitor extends AbstractVisitor { insnMap.put(finallyInsn, candidateInsns); } - - for (final InsnNode finallyInsn : insnMap.keySet()) { + for (InsnNode finallyInsn : insnMap.keySet()) { finallyInsn.add(AFlag.FINALLY_INSNS); - final List candidateInsns = insnMap.get(finallyInsn); - for (final InsnNode candidateInsn : candidateInsns) { + List candidateInsns = insnMap.get(finallyInsn); + for (InsnNode candidateInsn : candidateInsns) { copyCodeVars(finallyInsn, candidateInsn); candidateInsn.add(AFlag.DONT_GENERATE); } } - - for (final BlockNode finallyBlock : tryInfo.completeFinallyBlocks) { + for (BlockNode finallyBlock : tryInfo.completeFinallyBlocks) { if (ListUtils.anyMatch(finallyBlock.getInstructions(), ignoredFinallyInsns::contains)) { // If this block contains an instruction which was not found in all try edges, // don't mark it as a finally block. @@ -341,7 +323,7 @@ public class MarkFinallyVisitor extends AbstractVisitor { } finallyBlock.add(AFlag.FINALLY_INSNS); } - for (final BlockNode candidateBlock : tryInfo.completeCandidateBlocks) { + for (BlockNode candidateBlock : tryInfo.completeCandidateBlocks) { if (ListUtils.anyMatch(candidateBlock.getInstructions(), ignoredCandidateInsns::contains)) { // If this block contains an instruction which was found to "duplicate" a finally // instruction which was not found in all try edges, don't mark it as a duplicated @@ -353,15 +335,14 @@ public class MarkFinallyVisitor extends AbstractVisitor { // If any scope has been merged with the fallthrough case of the try catch, don't merge inner trys. // Otherwise, merge inner trys. - final boolean mergedFallthroughScope = + boolean mergedFallthroughScope = ListUtils.anyMatch(tryInfo.scopeGroups.getMergedScopes(), scopePair -> scopePair.getFirst().isNotHandlerExit()); - final boolean mergeInnerTryBlocks = hasInnerBlocks && !mergedFallthroughScope; + boolean mergeInnerTryBlocks = hasInnerBlocks && !mergedFallthroughScope; tryInfo.finallyHandler.setFinally(true); - if (mergeInnerTryBlocks) { - final List innerTryBlocks = tryInfo.tryBlock.getInnerTryBlocks(); - for (final TryCatchBlockAttr innerTryBlock : innerTryBlocks) { + List innerTryBlocks = tryInfo.tryBlock.getInnerTryBlocks(); + for (TryCatchBlockAttr innerTryBlock : innerTryBlocks) { tryInfo.tryBlock.getHandlers().addAll(innerTryBlock.getHandlers()); tryInfo.tryBlock.getBlocks().addAll(innerTryBlock.getBlocks()); innerTryBlock.setMerged(true); @@ -369,7 +350,6 @@ public class MarkFinallyVisitor extends AbstractVisitor { tryInfo.tryBlock.setBlocks(ListUtils.distinctList(tryInfo.tryBlock.getBlocks())); innerTryBlocks.clear(); } - return true; } @@ -380,13 +360,13 @@ public class MarkFinallyVisitor extends AbstractVisitor { * @param tryBlock The source try block to get the list of exception handlers for * @return The list of exception handlers. */ - private static List getHandlersForTryCatch(final TryCatchBlockAttr tryBlock) { - final boolean hasInnerBlocks = !tryBlock.getInnerTryBlocks().isEmpty(); - final List handlers; + private static List getHandlersForTryCatch(TryCatchBlockAttr tryBlock) { + boolean hasInnerBlocks = !tryBlock.getInnerTryBlocks().isEmpty(); + List handlers; if (hasInnerBlocks) { // collect handlers from this and all inner blocks handlers = new ArrayList<>(tryBlock.getHandlers()); - for (final TryCatchBlockAttr innerTryBlock : tryBlock.getInnerTryBlocks()) { + for (TryCatchBlockAttr innerTryBlock : tryBlock.getInnerTryBlocks()) { handlers.addAll(getHandlersForTryCatch(innerTryBlock)); } } else { @@ -395,21 +375,21 @@ public class MarkFinallyVisitor extends AbstractVisitor { return handlers; } - @Nullable - private static Map> findCommonInsns(final MethodNode mth, final TryExtractInfo tryInfo) { - final List allHandlerBlocks = tryInfo.handlerScopes.getBlocksForHandler(tryInfo.finallyHandler); - final BlockNode finallyScopeTerminus = getTerminusForHandler(tryInfo.finallyHandler, tryInfo); - - final Map> matchingInsns = new HashMap<>(); - for (final TryEdge edge : tryInfo.handlerScopes.keySet()) { + private static @Nullable Map> findCommonInsns(MethodNode mth, TryExtractInfo tryInfo) { + List allHandlerBlocks = tryInfo.handlerScopes.getBlocksForHandler(tryInfo.finallyHandler); + BlockNode finallyScopeTerminus = getTerminusForHandler(tryInfo.finallyHandler, tryInfo); + if (finallyScopeTerminus == null) { + return null; + } + Map> matchingInsns = new HashMap<>(); + for (TryEdge edge : tryInfo.handlerScopes.keySet()) { if (edge.isHandlerExit() && edge.getExceptionHandler() == tryInfo.finallyHandler) { continue; } - - final List handlerBlocks = tryInfo.handlerScopes.get(edge); + List handlerBlocks = tryInfo.handlerScopes.get(edge); BlockNode scopeTerminus = null; - for (final BlockNode edgeTerminusBlock : tryInfo.scopeTerminusGroups.keySet()) { - final List edgesWithTerminus = tryInfo.scopeTerminusGroups.get(edgeTerminusBlock); + for (BlockNode edgeTerminusBlock : tryInfo.scopeTerminusGroups.keySet()) { + List edgesWithTerminus = tryInfo.scopeTerminusGroups.get(edgeTerminusBlock); if (edgesWithTerminus.contains(edge)) { scopeTerminus = edgeTerminusBlock; break; @@ -418,26 +398,24 @@ public class MarkFinallyVisitor extends AbstractVisitor { if (scopeTerminus == null) { throw new JadxRuntimeException("Expected to find fallthrough terminus for handler " + edge); } - - final TraverserActivePathState comparatorState = + TraverserActivePathState comparatorState = new TraverserActivePathState(mth, new SameInstructionsStrategyImpl(), finallyScopeTerminus, scopeTerminus, allHandlerBlocks, handlerBlocks); - final TraverserController controller = new TraverserController(); - final List pathResults; + TraverserController controller = new TraverserController(); + List pathResults; try { pathResults = controller.process(comparatorState); - } catch (final TraverserException e) { + } catch (TraverserException e) { LOG.error("Could not search for finally duplicate instructions in path", e); return null; } - - final Set completeFinally = new HashSet<>(); - final Set completeCandidate = new HashSet<>(); - for (final TraverserActivePathState pathResult : pathResults) { - for (final Pair matchingInsnPair : pathResult.getMatchedInsns()) { - final InsnNode finallyInsn = matchingInsnPair.getFirst(); - final InsnNode candidateInsn = matchingInsnPair.getSecond(); - final List candidateInsnsList; + Set completeFinally = new HashSet<>(); + Set completeCandidate = new HashSet<>(); + for (TraverserActivePathState pathResult : pathResults) { + for (Pair matchingInsnPair : pathResult.getMatchedInsns()) { + InsnNode finallyInsn = matchingInsnPair.getFirst(); + InsnNode candidateInsn = matchingInsnPair.getSecond(); + List candidateInsnsList; if (!matchingInsns.containsKey(finallyInsn)) { candidateInsnsList = new LinkedList<>(); matchingInsns.put(finallyInsn, candidateInsnsList); @@ -446,29 +424,25 @@ public class MarkFinallyVisitor extends AbstractVisitor { } candidateInsnsList.add(candidateInsn); } - completeFinally.addAll(pathResult.getAllFullyMatchedFinallyBlocks()); completeCandidate.addAll(pathResult.getAllFullyMatchedCandidateBlocks()); } - if (tryInfo.completeFinallyBlocks == null) { tryInfo.completeFinallyBlocks = completeFinally; } else { tryInfo.completeFinallyBlocks.retainAll(completeFinally); } - if (tryInfo.completeCandidateBlocks == null) { tryInfo.completeCandidateBlocks = completeCandidate; } else { tryInfo.completeCandidateBlocks.addAll(completeCandidate); } } - return matchingInsns; } - private static void removeEmptyUpPath(final List handlerBlocks, final BlockNode startBlock) { - for (final BlockNode pred : startBlock.getPredecessors()) { + private static void removeEmptyUpPath(List handlerBlocks, BlockNode startBlock) { + for (BlockNode pred : startBlock.getPredecessors()) { if (pred.isEmpty()) { if (handlerBlocks.remove(pred) && !BlockUtils.isBackEdge(pred, startBlock)) { removeEmptyUpPath(handlerBlocks, pred); @@ -477,28 +451,28 @@ public class MarkFinallyVisitor extends AbstractVisitor { } } - private static void copyCodeVars(final InsnNode fromInsn, final InsnNode toInsn) { + private static void copyCodeVars(InsnNode fromInsn, InsnNode toInsn) { copyCodeVars(fromInsn.getResult(), toInsn.getResult()); - final int argsCount = fromInsn.getArgsCount(); + int argsCount = fromInsn.getArgsCount(); for (int i = 0; i < argsCount; i++) { copyCodeVars(fromInsn.getArg(i), toInsn.getArg(i)); } } - private static void copyCodeVars(final InsnArg fromArg, final InsnArg toArg) { + private static void copyCodeVars(InsnArg fromArg, InsnArg toArg) { if (fromArg == null || toArg == null || !fromArg.isRegister() || !toArg.isRegister()) { return; } - final SSAVar fromSsaVar = ((RegisterArg) fromArg).getSVar(); - final SSAVar toSsaVar = ((RegisterArg) toArg).getSVar(); + SSAVar fromSsaVar = ((RegisterArg) fromArg).getSVar(); + SSAVar toSsaVar = ((RegisterArg) toArg).getSVar(); toSsaVar.setCodeVar(fromSsaVar.getCodeVar()); } /** * Reload method without applying this visitor */ - private static void undoFinallyVisitor(final MethodNode mth) { + private static void undoFinallyVisitor(MethodNode mth) { try { // TODO: make more common and less hacky mth.unload(); @@ -511,16 +485,15 @@ public class MarkFinallyVisitor extends AbstractVisitor { } DepthTraversal.visit(visitor, mth); } - } catch (final DecodeException e) { + } catch (DecodeException e) { mth.addError("Undo finally extract failed", e); } } - @Nullable - private static BlockNode getTerminusForHandler(final ExceptionHandler handler, final TryExtractInfo tryInfo) { - for (final BlockNode terminus : tryInfo.scopeTerminusGroups.keySet()) { - final List edgesWithTerminus = tryInfo.scopeTerminusGroups.get(terminus); - for (final TryEdge edge : edgesWithTerminus) { + private static @Nullable BlockNode getTerminusForHandler(ExceptionHandler handler, TryExtractInfo tryInfo) { + for (BlockNode terminus : tryInfo.scopeTerminusGroups.keySet()) { + List edgesWithTerminus = tryInfo.scopeTerminusGroups.get(terminus); + for (TryEdge edge : edgesWithTerminus) { if (edge.isNotHandlerExit()) { continue; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/SameInstructionsStrategyImpl.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/SameInstructionsStrategyImpl.java index dcd5e895c..9c03c3844 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/SameInstructionsStrategyImpl.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/SameInstructionsStrategyImpl.java @@ -10,18 +10,18 @@ import jadx.core.dex.nodes.InsnNode; public final class SameInstructionsStrategyImpl extends SameInstructionsStrategy { - private static boolean sameDebugInfo(final RegisterArg dupReg, final RegisterArg fReg) { - final RegDebugInfoAttr fDbgInfo = fReg.get(AType.REG_DEBUG_INFO); - final RegDebugInfoAttr dupDbgInfo = dupReg.get(AType.REG_DEBUG_INFO); + private static boolean sameDebugInfo(RegisterArg dupReg, RegisterArg fReg) { + RegDebugInfoAttr fDbgInfo = fReg.get(AType.REG_DEBUG_INFO); + RegDebugInfoAttr dupDbgInfo = dupReg.get(AType.REG_DEBUG_INFO); if (fDbgInfo == null || dupDbgInfo == null) { return false; } return dupDbgInfo.equals(fDbgInfo); } - private static boolean assignInsnDifferent(final RegisterArg dupReg, final RegisterArg fReg) { - final InsnNode assignInsn = fReg.getAssignInsn(); - final InsnNode dupAssign = dupReg.getAssignInsn(); + private static boolean assignInsnDifferent(RegisterArg dupReg, RegisterArg fReg) { + InsnNode assignInsn = fReg.getAssignInsn(); + InsnNode dupAssign = dupReg.getAssignInsn(); if (assignInsn == null || dupAssign == null) { return true; } @@ -31,48 +31,45 @@ public final class SameInstructionsStrategyImpl extends SameInstructionsStrategy if (assignInsn.isConstInsn() && dupAssign.isConstInsn()) { // Do this and not deep equals since we already know that the result is the same and that the insn // type is the same - return !(Objects.equals(assignInsn.getArguments(), assignInsn.getArguments())); + return !Objects.equals(assignInsn.getArguments(), assignInsn.getArguments()); } return false; } @Override - public final boolean sameInsns(final InsnNode dupInsn, final InsnNode fInsn) { + public boolean sameInsns(InsnNode dupInsn, InsnNode fInsn) { if (!dupInsn.isSame(fInsn)) { return false; } - for (int i = 0; i < dupInsn.getArgsCount(); i++) { - final InsnArg dupArg = dupInsn.getArg(i); - final InsnArg fArg = fInsn.getArg(i); + InsnArg dupArg = dupInsn.getArg(i); + InsnArg fArg = fInsn.getArg(i); if (!isSameArgs(dupArg, fArg)) { return false; } } - return true; } @Override - public final boolean isSameArgs(final InsnArg dupArg, final InsnArg fArg) { + public boolean isSameArgs(InsnArg dupArg, InsnArg fArg) { if (dupArg == null) { return false; } - final boolean isReg = dupArg.isRegister(); + boolean isReg = dupArg.isRegister(); if (isReg != fArg.isRegister()) { return false; } if (isReg) { - final RegisterArg dupReg = (RegisterArg) dupArg; - final RegisterArg fReg = (RegisterArg) fArg; - + RegisterArg dupReg = (RegisterArg) dupArg; + RegisterArg fReg = (RegisterArg) fArg; if (!dupReg.sameCodeVar(fReg) && !sameDebugInfo(dupReg, fReg) && assignInsnDifferent(dupReg, fReg)) { return false; } } - final boolean remConst = dupArg.isConst(); + boolean remConst = dupArg.isConst(); if (remConst != fArg.isConst()) { return false; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/TryCatchEdgeBlockMap.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/TryCatchEdgeBlockMap.java index 7728f64b6..310e7e284 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/TryCatchEdgeBlockMap.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/TryCatchEdgeBlockMap.java @@ -27,15 +27,14 @@ import jadx.core.utils.ListUtils; */ public final class TryCatchEdgeBlockMap implements Map> { - public static boolean anyBlockHasNonImplicitTry(final List blocks) { - final List blocksWithTries = ListUtils.filter(blocks, blk -> blk.contains(AFlag.EXC_TOP_SPLITTER)); + public static boolean anyBlockHasNonImplicitTry(List blocks) { + List blocksWithTries = ListUtils.filter(blocks, blk -> blk.contains(AFlag.EXC_TOP_SPLITTER)); if (blocksWithTries.isEmpty()) { return false; } - - for (final BlockNode topSplitter : blocksWithTries) { + for (BlockNode topSplitter : blocksWithTries) { TryCatchBlockAttr block = null; - for (final BlockNode topSplitterSuccessor : topSplitter.getCleanSuccessors()) { + for (BlockNode topSplitterSuccessor : topSplitter.getCleanSuccessors()) { if (topSplitterSuccessor.contains(AType.TRY_BLOCK)) { block = topSplitterSuccessor.get(AType.TRY_BLOCK); } @@ -50,47 +49,42 @@ public final class TryCatchEdgeBlockMap implements Map> return false; } - public static TryCatchEdgeBlockMap getAllInScope(final MethodNode mth, final TryCatchBlockAttr tryCatch, - final TryEdgeScopeGroupMap scopeGroups, final ExceptionHandler finallyHandler, - final Map> scopeTerminusGroups) { - final Map edgeBlocks = tryCatch.getEdgeBlockMap(mth); - - final TryCatchEdgeBlockMap result = new TryCatchEdgeBlockMap(); - for (final BlockNode scopeTerminus : scopeTerminusGroups.keySet()) { - final List sourceEdges = scopeTerminusGroups.get(scopeTerminus); - for (final TryEdge sourceEdge : sourceEdges) { - final BlockNode edgeBlock = edgeBlocks.get(sourceEdge); - - final boolean useClean = !(sourceEdge.isNotHandlerExit() + public static TryCatchEdgeBlockMap getAllInScope(MethodNode mth, TryCatchBlockAttr tryCatch, + TryEdgeScopeGroupMap scopeGroups, ExceptionHandler finallyHandler, + Map> scopeTerminusGroups) { + Map edgeBlocks = tryCatch.getEdgeBlockMap(); + TryCatchEdgeBlockMap result = new TryCatchEdgeBlockMap(); + for (BlockNode scopeTerminus : scopeTerminusGroups.keySet()) { + List sourceEdges = scopeTerminusGroups.get(scopeTerminus); + for (TryEdge sourceEdge : sourceEdges) { + BlockNode edgeBlock = edgeBlocks.get(sourceEdge); + boolean useClean = !(sourceEdge.isNotHandlerExit() && ListUtils.anyMatch(scopeGroups.getMergedScopes(), pair -> pair.getSecond().isNotHandlerExit())); - List allBlocks = - BlockUtils.collectAllSuccessorsUntil(mth, edgeBlock, useClean, (block) -> block == scopeTerminus); - final boolean anyBlockHasTry = anyBlockHasNonImplicitTry(allBlocks); - + List allBlocks = BlockUtils.collectAllSuccessorsUntil(mth, edgeBlock, useClean, block -> block == scopeTerminus); + boolean anyBlockHasTry = anyBlockHasNonImplicitTry(allBlocks); if (anyBlockHasTry && useClean) { // If there's a try edge in the found blocks, collect all successors, not just clean successors. - allBlocks = BlockUtils.collectAllSuccessorsUntil(mth, edgeBlock, false, (block) -> block == scopeTerminus); + allBlocks = BlockUtils.collectAllSuccessorsUntil(mth, edgeBlock, false, block -> block == scopeTerminus); } if (sourceEdge.isNotHandlerExit()) { // If source edge is a fallthrough case, add the try body. allBlocks = new ArrayList<>(allBlocks); allBlocks.addAll(tryCatch.getBlocks()); } - result.put(sourceEdge, allBlocks); } } - final List finallyBlocks = result.getBlocksForHandler(finallyHandler); - for (final TryEdge edge : result.keySet()) { - if (edge.isHandlerExit() && edge.getExceptionHandler() == finallyHandler) { - continue; + List finallyBlocks = result.getBlocksForHandler(finallyHandler); + if (finallyBlocks != null) { + for (TryEdge edge : result.keySet()) { + if (edge.isHandlerExit() && edge.getExceptionHandler() == finallyHandler) { + continue; + } + List blocks = result.get(edge); + blocks.removeAll(finallyBlocks); } - - final List blocks = result.get(edge); - blocks.removeAll(finallyBlocks); } - return result; } @@ -101,82 +95,79 @@ public final class TryCatchEdgeBlockMap implements Map> } @Override - public final void clear() { + public void clear() { underlying.clear(); } @Override - public final boolean containsKey(Object key) { + public boolean containsKey(Object key) { return underlying.containsKey(key); } @Override - public final boolean containsValue(Object value) { + public boolean containsValue(Object value) { if (!(value instanceof TryEdge)) { return false; } - - final TryEdge edge = (TryEdge) value; + TryEdge edge = (TryEdge) value; return underlying.containsKey(edge); } @Override - public final Set>> entrySet() { + public Set>> entrySet() { return underlying.entrySet(); } @Override - public final List get(Object key) { + public List get(Object key) { return underlying.get(key); } @Override - public final boolean isEmpty() { + public boolean isEmpty() { return underlying.isEmpty(); } @Override - public final Set keySet() { + public Set keySet() { return underlying.keySet(); } @Override - public final List put(TryEdge key, List value) { + public List put(TryEdge key, List value) { return underlying.put(key, value); } @Override - public final void putAll(Map> otherMap) { + public void putAll(Map> otherMap) { underlying.putAll(otherMap); } @Override - public final List remove(Object key) { + public List remove(Object key) { return underlying.remove(key); } @Override - public final int size() { + public int size() { return underlying.size(); } @Override - public final Collection> values() { + public Collection> values() { return underlying.values(); } @Nullable - public final List getBlocksForHandler(final ExceptionHandler handler) { + public List getBlocksForHandler(ExceptionHandler handler) { TryEdge edgeWithHandler = null; - for (final TryEdge edge : keySet()) { + for (TryEdge edge : keySet()) { if (edge.isNotHandlerExit()) { continue; } - if (!edge.getExceptionHandler().equals(handler)) { continue; } - edgeWithHandler = edge; break; } @@ -186,9 +177,9 @@ public final class TryCatchEdgeBlockMap implements Map> return get(edgeWithHandler); } - public final List getBlocksForAllFallthroughs() { - final List blks = new ArrayList<>(); - for (final TryEdge edge : keySet()) { + public List getBlocksForAllFallthroughs() { + List blks = new ArrayList<>(); + for (TryEdge edge : keySet()) { if (edge.isHandlerExit()) { continue; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/GlobalTraverserSourceState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/GlobalTraverserSourceState.java index 179c76e9d..8fa718351 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/GlobalTraverserSourceState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/GlobalTraverserSourceState.java @@ -12,15 +12,15 @@ public final class GlobalTraverserSourceState { private final Set containedBlocks; - public GlobalTraverserSourceState(final Set containedBlocks) { + public GlobalTraverserSourceState(Set containedBlocks) { this.containedBlocks = containedBlocks; } - public final boolean isBlockContained(final BlockNode block) { + public boolean isBlockContained(BlockNode block) { return containedBlocks.contains(block); } - public final Set getContainedBlocks() { + public Set getContainedBlocks() { return containedBlocks; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java index ca3f88ed0..6e0097722 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java @@ -34,8 +34,8 @@ import jadx.core.utils.exceptions.JadxRuntimeException; */ public final class TraverserController { - private static List processHandlerImplementations(final TraverserActivePathState state, - final AbstractBlockTraverserHandler handler) throws TraverserException { + private static List processHandlerImplementations(TraverserActivePathState state, + AbstractBlockTraverserHandler handler) throws TraverserException { if (handler instanceof AbstractBlockPathTraverserHandler) { ((AbstractBlockPathTraverserHandler) handler).process(); return List.of(state); @@ -53,7 +53,7 @@ public final class TraverserController { this(null); } - public TraverserController(final @Nullable Function stateAbortCondition) { + public TraverserController(@Nullable Function stateAbortCondition) { this.stateAbortCondition = stateAbortCondition; } @@ -70,30 +70,25 @@ public final class TraverserController { * * This function will return a list of all of the different paths taken at the point of * termination of each individual branch. - * - * @param state - * @return */ - public final List process(final TraverserActivePathState state) throws TraverserException { + public List process(TraverserActivePathState state) throws TraverserException { TraverserActivePathState nextState = state; - final AtomicReference previousFinallyState = new AtomicReference<>(null); - final AtomicReference previousCandidateState = new AtomicReference<>(null); + AtomicReference previousFinallyState = new AtomicReference<>(null); + AtomicReference previousCandidateState = new AtomicReference<>(null); while (true) { - final List advancedStates = advance(nextState, previousFinallyState, previousCandidateState); + List advancedStates = advance(nextState, previousFinallyState, previousCandidateState); if (advancedStates == null || advancedStates.isEmpty()) { break; } - if (advancedStates.size() != 1) { - final TraverserController nextController = new TraverserController(stateAbortCondition); - final List returnStates = new ArrayList<>(); - for (final TraverserActivePathState advancedState : advancedStates) { - final List childStates = nextController.process(advancedState); + TraverserController nextController = new TraverserController(stateAbortCondition); + List returnStates = new ArrayList<>(); + for (TraverserActivePathState advancedState : advancedStates) { + List childStates = nextController.process(advancedState); returnStates.addAll(childStates); } return returnStates; } - nextState = advancedStates.get(0); } return List.of(nextState); @@ -101,42 +96,33 @@ public final class TraverserController { /** * Processes a singular traverser state once. - * - * @param state - * @param previousFinallyState - * @param previousCandidateState - * @return */ - public final List advance(final TraverserActivePathState state, - final AtomicReference previousFinallyState, - final AtomicReference previousCandidateState) throws TraverserException { - final TraverserGlobalCommonState commonState = state.getGlobalCommonState(); - final TraverserState finallyState = state.getFinallyState(); - final TraverserState candidateState = state.getCandidateState(); + public List advance(TraverserActivePathState state, + AtomicReference previousFinallyState, + AtomicReference previousCandidateState) throws TraverserException { + TraverserGlobalCommonState commonState = state.getGlobalCommonState(); + TraverserState finallyState = state.getFinallyState(); + TraverserState candidateState = state.getCandidateState(); if (previousFinallyState.get() == finallyState && previousCandidateState.get() == candidateState) { - final TraverserStateFactory finallyStateProducer = + TraverserStateFactory finallyStateProducer = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.UNRESOLVABLE_STATES); - final TraverserStateFactory candidateStateProducer = + TraverserStateFactory candidateStateProducer = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.UNRESOLVABLE_STATES); return List.of(TraverserActivePathState.produceFromFactories(state, finallyStateProducer, candidateStateProducer)); } - previousFinallyState.set(finallyState); previousCandidateState.set(candidateState); - if (finallyState.isTerminal() || candidateState.isTerminal()) { return null; } - if (finallyState.getClass().equals(candidateState.getClass()) && finallyState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE && candidateState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE) { - - final BlockNode finallyBlock; - final BlockNode candidateBlock; - final TraverserBlockInfo finallyBlockInfo = finallyState.getBlockInsnInfo(); - final TraverserBlockInfo candidateBlockInfo = candidateState.getBlockInsnInfo(); + BlockNode finallyBlock; + BlockNode candidateBlock; + TraverserBlockInfo finallyBlockInfo = finallyState.getBlockInsnInfo(); + TraverserBlockInfo candidateBlockInfo = candidateState.getBlockInsnInfo(); if (finallyBlockInfo != null && candidateBlockInfo != null) { finallyBlock = finallyBlockInfo.getBlock(); candidateBlock = candidateBlockInfo.getBlock(); @@ -144,46 +130,38 @@ public final class TraverserController { finallyBlock = null; candidateBlock = null; } - - final boolean isCached; + boolean isCached; if (finallyBlock != null && candidateBlock != null) { isCached = commonState.hasBlocksBeenCached(finallyBlock, candidateBlock); } else { isCached = false; } - if (isCached) { - final List dupStates = commonState.getCachedStateFor(finallyBlock, candidateBlock); - final List recoveredFromCacheStates = new ArrayList<>(dupStates.size()); - for (final TraverserActivePathState dupState : dupStates) { - final TraverserState reusedFinallyState = dupState.getFinallyState(); - final TraverserState reusedCandidateState = dupState.getCandidateState(); - final TraverserStateFactory finallyStateProducer = RecoveredFromCacheTraverserState.getFactory(reusedFinallyState); - final TraverserStateFactory candidateStateProducer = + List dupStates = commonState.getCachedStateFor(finallyBlock, candidateBlock); + List recoveredFromCacheStates = new ArrayList<>(dupStates.size()); + for (TraverserActivePathState dupState : dupStates) { + TraverserState reusedFinallyState = dupState.getFinallyState(); + TraverserState reusedCandidateState = dupState.getCandidateState(); + TraverserStateFactory finallyStateProducer = RecoveredFromCacheTraverserState.getFactory(reusedFinallyState); + TraverserStateFactory candidateStateProducer = RecoveredFromCacheTraverserState.getFactory(reusedCandidateState); - final TraverserActivePathState recoveredFromCacheState = + TraverserActivePathState recoveredFromCacheState = TraverserActivePathState.produceFromFactories(state, finallyStateProducer, candidateStateProducer); recoveredFromCacheState.mergeWith(dupStates); recoveredFromCacheStates.add(recoveredFromCacheState); } return recoveredFromCacheStates; } - - final AbstractBlockTraverserHandler handler = candidateState.getNextHandler(); - final List resultingStates = processHandlerImplementations(state, handler); - return resultingStates; + AbstractBlockTraverserHandler handler = candidateState.getNextHandler(); + return processHandlerImplementations(state, handler); } - - final boolean hasReadyToCompare = finallyState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE + boolean hasReadyToCompare = finallyState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE || candidateState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE; - - final boolean finallyStateAborted = advanceSingleState(state, finallyState, hasReadyToCompare); - final boolean candidateStateAborted = advanceSingleState(state, candidateState, hasReadyToCompare); - + boolean finallyStateAborted = advanceSingleState(state, finallyState, hasReadyToCompare); + boolean candidateStateAborted = advanceSingleState(state, candidateState, hasReadyToCompare); if (finallyStateAborted && candidateStateAborted) { return null; } - return List.of(state); } @@ -192,15 +170,15 @@ public final class TraverserController { * * @return Whether this state has been aborted by the state abort function. */ - private boolean advanceSingleState(final TraverserActivePathState activePathState, final TraverserState singleState, - final boolean hasReadyToCompare) throws TraverserException { - final boolean stateAborted = stateAbortCondition != null && stateAbortCondition.apply(singleState); + private boolean advanceSingleState(TraverserActivePathState activePathState, TraverserState singleState, + boolean hasReadyToCompare) throws TraverserException { + boolean stateAborted = stateAbortCondition != null && stateAbortCondition.apply(singleState); if (stateAbortCondition == null || !stateAborted) { if (singleState.getCompareState() == TraverserState.ComparisonState.NOT_READY - || (singleState.getCompareState() == TraverserState.ComparisonState.AWAITING_OPTIONAL_PREDECESSOR_MERGE - && hasReadyToCompare)) { - final AbstractBlockTraverserHandler handler = singleState.getNextHandler(); - final List results = processHandlerImplementations(activePathState, handler); + || singleState.getCompareState() == TraverserState.ComparisonState.AWAITING_OPTIONAL_PREDECESSOR_MERGE + && hasReadyToCompare) { + AbstractBlockTraverserHandler handler = singleState.getNextHandler(); + List results = processHandlerImplementations(activePathState, handler); if (results.size() != 1 || results.get(0) != activePathState) { throw new JadxRuntimeException("A traverser handler which was not expected to change path states actually did"); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserException.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserException.java index 3c097a8aa..679439ebf 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserException.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserException.java @@ -2,7 +2,7 @@ package jadx.core.dex.visitors.finaly.traverser; public class TraverserException extends Exception { - public TraverserException(final String msg) { + public TraverserException(String msg) { super(msg); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/DuplicatedTraverserStateFactory.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/DuplicatedTraverserStateFactory.java index fcad4a41b..0dd755c70 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/DuplicatedTraverserStateFactory.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/DuplicatedTraverserStateFactory.java @@ -5,17 +5,17 @@ import jadx.core.dex.visitors.finaly.traverser.state.TraverserState; import jadx.core.utils.exceptions.JadxRuntimeException; public final class DuplicatedTraverserStateFactory extends TraverserStateFactory { - private final T baseState; - public DuplicatedTraverserStateFactory(final T baseState) { + public DuplicatedTraverserStateFactory(T baseState) { this.baseState = baseState; } + @SuppressWarnings("unchecked") @Override - public final T generateInternalState(final TraverserActivePathState state) { - final Class baseStateClass = (Class) baseState.getClass(); - final TraverserState duplicated = baseState.duplicate(state); + public T generateInternalState(TraverserActivePathState state) { + Class baseStateClass = (Class) baseState.getClass(); + TraverserState duplicated = baseState.duplicate(state); if (!baseStateClass.isInstance(duplicated)) { throw new JadxRuntimeException( "A state of class " + baseState.getClass() + " has duplicated to produce a class of " + duplicated.getClass()); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/TraverserStateFactory.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/TraverserStateFactory.java index 72a4e4608..1a04991f7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/TraverserStateFactory.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/TraverserStateFactory.java @@ -5,10 +5,9 @@ import jadx.core.dex.visitors.finaly.traverser.state.TraverserState; public abstract class TraverserStateFactory { - protected abstract T generateInternalState(final TraverserActivePathState state); + protected abstract T generateInternalState(TraverserActivePathState state); - public final T generateState(final TraverserActivePathState state) { - final T generatedState = generateInternalState(state); - return generatedState; + public final T generateState(TraverserActivePathState state) { + return generateInternalState(state); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractActivePathTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractActivePathTraverserHandler.java index dae9ce6a3..87c443d28 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractActivePathTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractActivePathTraverserHandler.java @@ -9,7 +9,7 @@ public abstract class AbstractActivePathTraverserHandler extends AbstractBlockTr private final TraverserActivePathState comparatorState; - public AbstractActivePathTraverserHandler(final TraverserActivePathState comparatorState) { + public AbstractActivePathTraverserHandler(TraverserActivePathState comparatorState) { this.comparatorState = comparatorState; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractBlockPathTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractBlockPathTraverserHandler.java index bbce55d65..404e2f734 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractBlockPathTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/AbstractBlockPathTraverserHandler.java @@ -14,11 +14,11 @@ public abstract class AbstractBlockPathTraverserHandler extends AbstractBlockTra private final AtomicReference stateRef; - public AbstractBlockPathTraverserHandler(final TraverserState initialState) { + public AbstractBlockPathTraverserHandler(TraverserState initialState) { this.stateRef = new AtomicReference<>(initialState); } - public AbstractBlockPathTraverserHandler(final AtomicReference initialStateRef) { + public AbstractBlockPathTraverserHandler(AtomicReference initialStateRef) { this.stateRef = initialStateRef; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java index e0b05baae..aed78e87f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java @@ -12,34 +12,30 @@ import jadx.core.utils.exceptions.JadxRuntimeException; public class BaseBlockTraverserHandler extends AbstractBlockPathTraverserHandler { - public BaseBlockTraverserHandler(final TraverserState initialState) { + public BaseBlockTraverserHandler(TraverserState initialState) { super(initialState); } - public BaseBlockTraverserHandler(final AtomicReference initialStateRef) { + public BaseBlockTraverserHandler(AtomicReference initialStateRef) { super(initialStateRef); } @Override protected void handle() { - final TraverserBlockInfo blockInsnInfo = getState().getBlockInsnInfo(); + TraverserBlockInfo blockInsnInfo = getState().getBlockInsnInfo(); if (blockInsnInfo == null) { throw new JadxRuntimeException("Expected to find block info within " + getClass().getSimpleName()); } - - final TraverserActivePathState comparator = getState().getComparatorState(); - final AtomicReference stateRef = comparator.getReferenceForState(getState()); - + TraverserActivePathState comparator = getState().getComparatorState(); + AtomicReference stateRef = comparator.getReferenceForState(getState()); if (stateRef == null) { throw new JadxRuntimeException("Orphaned traverser state"); } - - final BlockNode block = blockInsnInfo.getBlock(); - - final ImplicitInsnBlockTraverserVisitor implicitVisitor = new ImplicitInsnBlockTraverserVisitor(getState()); - final TraverserState stateAfterImplicit = implicitVisitor.visit(block); - final PathEndBlockTraverserVisitor pathEndVisitor = new PathEndBlockTraverserVisitor(stateAfterImplicit); - final TraverserState nextState = pathEndVisitor.visit(block); + BlockNode block = blockInsnInfo.getBlock(); + ImplicitInsnBlockTraverserVisitor implicitVisitor = new ImplicitInsnBlockTraverserVisitor(getState()); + TraverserState stateAfterImplicit = implicitVisitor.visit(block); + PathEndBlockTraverserVisitor pathEndVisitor = new PathEndBlockTraverserVisitor(stateAfterImplicit); + TraverserState nextState = pathEndVisitor.visit(block); stateRef.set(nextState); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/InstructionActivePathTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/InstructionActivePathTraverserHandler.java index f1f72768f..c432052ec 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/InstructionActivePathTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/InstructionActivePathTraverserHandler.java @@ -13,36 +13,34 @@ import jadx.core.dex.visitors.finaly.traverser.visitors.comparator.InstructionBl public final class InstructionActivePathTraverserHandler extends AbstractActivePathTraverserHandler { public static final class UnresolvableBlockException extends TraverserException { - public UnresolvableBlockException(final BlockNode block, final String reason) { + public UnresolvableBlockException(BlockNode block, String reason) { super("A block, " + block.toString() + ", could not have instructions compared.\n\t" + reason); } } - public InstructionActivePathTraverserHandler(final TraverserActivePathState state) { + public InstructionActivePathTraverserHandler(TraverserActivePathState state) { super(state); } @Override protected List handle() throws TraverserException { - final TraverserActivePathState comparator = getComparator(); - final TraverserGlobalCommonState commonState = comparator.getGlobalCommonState(); + TraverserActivePathState comparator = getComparator(); + TraverserGlobalCommonState commonState = comparator.getGlobalCommonState(); - final TraverserState finallyState = comparator.getFinallyState(); - final TraverserState candidateState = comparator.getCandidateState(); + TraverserState finallyState = comparator.getFinallyState(); + TraverserState candidateState = comparator.getCandidateState(); - final TraverserBlockInfo finallyBlockInfo = finallyState.getBlockInsnInfo(); - final TraverserBlockInfo candidateBlockInfo = candidateState.getBlockInsnInfo(); - final BlockNode finallyBlock = finallyBlockInfo.getBlock(); - final BlockNode candidateBlock = candidateBlockInfo.getBlock(); + TraverserBlockInfo finallyBlockInfo = finallyState.getBlockInsnInfo(); + TraverserBlockInfo candidateBlockInfo = candidateState.getBlockInsnInfo(); + BlockNode finallyBlock = finallyBlockInfo.getBlock(); + BlockNode candidateBlock = candidateBlockInfo.getBlock(); - final InstructionBlockComparatorTraverserVisitor visitor = new InstructionBlockComparatorTraverserVisitor(); - final TraverserActivePathState newState = visitor.visit(comparator); + InstructionBlockComparatorTraverserVisitor visitor = new InstructionBlockComparatorTraverserVisitor(); + TraverserActivePathState newState = visitor.visit(comparator); if (finallyBlock != null && candidateBlock != null) { commonState.addCachedStateFor(finallyBlock, candidateBlock, List.of(newState)); } - return List.of(newState); } - } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/MergePathActivePathTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/MergePathActivePathTraverserHandler.java index b1cc8ab07..71e5e6c92 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/MergePathActivePathTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/MergePathActivePathTraverserHandler.java @@ -27,17 +27,17 @@ import jadx.core.utils.exceptions.JadxRuntimeException; public final class MergePathActivePathTraverserHandler extends AbstractActivePathTraverserHandler { - private static TraverserActivePathState createNonMatchingTerminator(final TraverserActivePathState state) { - final TraverserStateFactory finallyStateFactory = + private static TraverserActivePathState createNonMatchingTerminator(TraverserActivePathState state) { + TraverserStateFactory finallyStateFactory = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.NON_MATCHING_PATHS); - final TraverserStateFactory candidateStateFactory = + TraverserStateFactory candidateStateFactory = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.NON_MATCHING_PATHS); return TraverserActivePathState.produceFromFactories(state, finallyStateFactory, candidateStateFactory); } - private static boolean isStateOnTerminus(final TraverserState state, final BlockNode terminus) { - final TraverserBlockInfo blockInfo = state.getBlockInsnInfo(); + private static boolean isStateOnTerminus(TraverserState state, BlockNode terminus) { + TraverserBlockInfo blockInfo = state.getBlockInsnInfo(); if (blockInfo == null) { return false; } @@ -45,12 +45,12 @@ public final class MergePathActivePathTraverserHandler extends AbstractActivePat } private static Function getStateAbortOnTerminusFunction( - final IdentifiedScopeWithTerminatorTraverserState finallyState, - final IdentifiedScopeWithTerminatorTraverserState candidateState) { - final BlockNode finallyTerminus = finallyState.getTerminus(); - final BlockNode candidateTerminus = candidateState.getTerminus(); - final GlobalTraverserSourceState finallyGlobalState = finallyState.getGlobalState(); - final GlobalTraverserSourceState candidateGlobalState = candidateState.getGlobalState(); + IdentifiedScopeWithTerminatorTraverserState finallyState, + IdentifiedScopeWithTerminatorTraverserState candidateState) { + BlockNode finallyTerminus = finallyState.getTerminus(); + BlockNode candidateTerminus = candidateState.getTerminus(); + GlobalTraverserSourceState finallyGlobalState = finallyState.getGlobalState(); + GlobalTraverserSourceState candidateGlobalState = candidateState.getGlobalState(); return (final TraverserState state) -> { if (state.getGlobalState() == finallyGlobalState) { @@ -63,25 +63,24 @@ public final class MergePathActivePathTraverserHandler extends AbstractActivePat }; } - private static PostMergeStatus getScopeSplitPostMergeStatus(final List pathsTaken) { + private static PostMergeStatus getScopeSplitPostMergeStatus(List pathsTaken) { // If the scope split is the same, all branches must not end in a terminator. - - final PostMergeStatus status = new PostMergeStatus(); - for (final TraverserActivePathState path : pathsTaken) { - final TraverserState finallyState; - final TraverserState candidateState; + PostMergeStatus status = new PostMergeStatus(); + for (TraverserActivePathState path : pathsTaken) { + TraverserState finallyState; + TraverserState candidateState; if (path.getFinallyState().isTerminal() || path.getCandidateState().isTerminal()) { - final TraverserState rawFinallyState = path.getFinallyState(); - final TraverserState rawCandidateState = path.getCandidateState(); - final boolean finallyIsCached = rawFinallyState instanceof RecoveredFromCacheTraverserState; - final boolean candidateIsCached = rawCandidateState instanceof RecoveredFromCacheTraverserState; + TraverserState rawFinallyState = path.getFinallyState(); + TraverserState rawCandidateState = path.getCandidateState(); + boolean finallyIsCached = rawFinallyState instanceof RecoveredFromCacheTraverserState; + boolean candidateIsCached = rawCandidateState instanceof RecoveredFromCacheTraverserState; if (!(finallyIsCached && candidateIsCached)) { status.perfectMatch = false; continue; } - final RecoveredFromCacheTraverserState finallyCachedState = (RecoveredFromCacheTraverserState) rawFinallyState; - final RecoveredFromCacheTraverserState candidateCachedState = (RecoveredFromCacheTraverserState) rawCandidateState; + RecoveredFromCacheTraverserState finallyCachedState = (RecoveredFromCacheTraverserState) rawFinallyState; + RecoveredFromCacheTraverserState candidateCachedState = (RecoveredFromCacheTraverserState) rawCandidateState; if (finallyCachedState.canContinue() || candidateCachedState.canContinue()) { status.perfectMatch = false; continue; @@ -92,20 +91,17 @@ public final class MergePathActivePathTraverserHandler extends AbstractActivePat finallyState = path.getFinallyState(); candidateState = path.getCandidateState(); } - - final CentralityState finallyCentralityState = finallyState.getCentralityState(); - final CentralityState candidateCentralityState = candidateState.getCentralityState(); + CentralityState finallyCentralityState = finallyState.getCentralityState(); + CentralityState candidateCentralityState = candidateState.getCentralityState(); status.finallyAllowsCentral &= finallyCentralityState.getAllowsCentral(); status.candidateAllowsCentral &= candidateCentralityState.getAllowsCentral(); status.finallyAllowableOutputs.addAll(finallyCentralityState.getAllowableOutputArguments()); status.candidateAllowableOutputs.addAll(candidateCentralityState.getAllowableOutputArguments()); } - return status; } private static final class PostMergeStatus { - public final Set finallyAllowableOutputs = new HashSet<>(); public final Set candidateAllowableOutputs = new HashSet<>(); public boolean finallyAllowsCentral; @@ -113,54 +109,54 @@ public final class MergePathActivePathTraverserHandler extends AbstractActivePat public boolean perfectMatch = true; } - public MergePathActivePathTraverserHandler(final TraverserActivePathState comparatorState) { + public MergePathActivePathTraverserHandler(TraverserActivePathState comparatorState) { super(comparatorState); } @Override - protected final List handle() { - final TraverserActivePathState comparator = getComparator().duplicate(); - final TraverserGlobalCommonState commonState = comparator.getGlobalCommonState(); - final IdentifiedScopeWithTerminatorTraverserState finallyState = + protected List handle() { + TraverserActivePathState comparator = getComparator().duplicate(); + TraverserGlobalCommonState commonState = comparator.getGlobalCommonState(); + IdentifiedScopeWithTerminatorTraverserState finallyState = (IdentifiedScopeWithTerminatorTraverserState) comparator.getFinallyState(); - final IdentifiedScopeWithTerminatorTraverserState candidateState = + IdentifiedScopeWithTerminatorTraverserState candidateState = (IdentifiedScopeWithTerminatorTraverserState) comparator.getCandidateState(); - final BlockNode finallyTerminus = finallyState.getTerminus(); - final BlockNode candidateTerminus = candidateState.getTerminus(); + BlockNode finallyTerminus = finallyState.getTerminus(); + BlockNode candidateTerminus = candidateState.getTerminus(); - final Function abortFunction = getStateAbortOnTerminusFunction(finallyState, candidateState); + Function abortFunction = getStateAbortOnTerminusFunction(finallyState, candidateState); - final List allPermutationsPaths = getAllPermutationsOfCollection(candidateState.getRoots()); + List allPermutationsPaths = getAllPermutationsOfCollection(candidateState.getRoots()); List paths = null; PostMergeStatus postMerge = null; - for (final BlockNode[] candidateRootsPermutation : allPermutationsPaths) { - final List traversalPaths = new ArrayList<>(); + for (BlockNode[] candidateRootsPermutation : allPermutationsPaths) { + List traversalPaths = new ArrayList<>(); for (int i = 0; i < finallyState.getRoots().size(); i++) { - final var finallyRoot = finallyState.getRoots().get(i); - final var candidateRoot = candidateRootsPermutation[i]; + var finallyRoot = finallyState.getRoots().get(i); + var candidateRoot = candidateRootsPermutation[i]; - final var finallyCentrality = finallyState.getCentralityState().duplicate(); - final var candidateCentrality = candidateState.getCentralityState().duplicate(); + var finallyCentrality = finallyState.getCentralityState().duplicate(); + var candidateCentrality = candidateState.getCentralityState().duplicate(); - final var finallyBlockInfo = new TraverserBlockInfo(finallyRoot); - final var candidateBlockInfo = new TraverserBlockInfo(candidateRoot); + var finallyBlockInfo = new TraverserBlockInfo(finallyRoot); + var candidateBlockInfo = new TraverserBlockInfo(candidateRoot); - final var finallyStateFactory = NewBlockTraverserState.getFactory(finallyCentrality, finallyBlockInfo); - final var candidateStateFactory = NewBlockTraverserState.getFactory(candidateCentrality, candidateBlockInfo); + var finallyStateFactory = NewBlockTraverserState.getFactory(finallyCentrality, finallyBlockInfo); + var candidateStateFactory = NewBlockTraverserState.getFactory(candidateCentrality, candidateBlockInfo); - final var newState = TraverserActivePathState.produceFromFactories(comparator, finallyStateFactory, candidateStateFactory); + var newState = TraverserActivePathState.produceFromFactories(comparator, finallyStateFactory, candidateStateFactory); traversalPaths.add(newState); } - final List currentPaths = new ArrayList<>(); + List currentPaths = new ArrayList<>(); boolean errorOccurred = false; - for (final TraverserActivePathState pathState : traversalPaths) { - final TraverserController branchController = new TraverserController(abortFunction); - final List out; + for (TraverserActivePathState pathState : traversalPaths) { + TraverserController branchController = new TraverserController(abortFunction); + List out; try { out = branchController.process(pathState); - } catch (final TraverserException e) { + } catch (TraverserException e) { errorOccurred = true; break; } @@ -175,57 +171,53 @@ public final class MergePathActivePathTraverserHandler extends AbstractActivePat // If the finally terminus and candidate terminus have been cached at this stage, it means that a // path that we searched evaluated the two termini. At this point, we can ignore a non-perfect // match if the path could continue from the point of the termini. - final boolean hasTerminusBeenEvaluatedInPaths = commonState.hasBlocksBeenCached(finallyTerminus, candidateTerminus); - final PostMergeStatus currentPostMerge = getScopeSplitPostMergeStatus(currentPaths); + boolean hasTerminusBeenEvaluatedInPaths = commonState.hasBlocksBeenCached(finallyTerminus, candidateTerminus); + PostMergeStatus currentPostMerge = getScopeSplitPostMergeStatus(currentPaths); if (!currentPostMerge.perfectMatch && !hasTerminusBeenEvaluatedInPaths) { // No match continue; } - paths = currentPaths; postMerge = currentPostMerge; break; } - if (paths == null || postMerge == null) { - final TraverserActivePathState nonMatchingState = createNonMatchingTerminator(comparator); + TraverserActivePathState nonMatchingState = createNonMatchingTerminator(comparator); return List.of(nonMatchingState); } - - final CentralityState newFinallyCentralityState = finallyState.getCentralityState().duplicate(); + CentralityState newFinallyCentralityState = finallyState.getCentralityState().duplicate(); newFinallyCentralityState.setAllowsCentral(postMerge.finallyAllowsCentral); newFinallyCentralityState.addAllowableOutputs(postMerge.finallyAllowableOutputs); - final CentralityState newCandidateCentralityState = candidateState.getCentralityState().duplicate(); + CentralityState newCandidateCentralityState = candidateState.getCentralityState().duplicate(); newCandidateCentralityState.setAllowsCentral(postMerge.candidateAllowsCentral); newCandidateCentralityState.addAllowableOutputs(postMerge.candidateAllowableOutputs); - final TraverserBlockInfo finallyTerminusBlockInfo = new TraverserBlockInfo(finallyState.getTerminus()); - final TraverserBlockInfo candidateTerminusBlockInfo = new TraverserBlockInfo(candidateState.getTerminus()); + TraverserBlockInfo finallyTerminusBlockInfo = new TraverserBlockInfo(finallyState.getTerminus()); + TraverserBlockInfo candidateTerminusBlockInfo = new TraverserBlockInfo(candidateState.getTerminus()); - final TraverserStateFactory finallyStateFactory = + TraverserStateFactory finallyStateFactory = NewBlockTraverserState.getFactory(newFinallyCentralityState, finallyTerminusBlockInfo); - final TraverserStateFactory candidateStateFactory = + TraverserStateFactory candidateStateFactory = NewBlockTraverserState.getFactory(newCandidateCentralityState, candidateTerminusBlockInfo); - final TraverserActivePathState nextState = + TraverserActivePathState nextState = TraverserActivePathState.produceFromFactories(comparator, finallyStateFactory, candidateStateFactory); nextState.mergeWith(paths); return List.of(nextState); } - public static List getAllPermutationsOfCollection(final Collection elements) { - final Stack permutationStack = new Stack<>(); - final List permutations = new ArrayList<>(); + public static List getAllPermutationsOfCollection(Collection elements) { + Stack permutationStack = new Stack<>(); + List permutations = new ArrayList<>(); permutations(permutations, elements, permutationStack, elements.size()); return permutations; } - public static void permutations(final List permutations, final Collection elements, - final Stack permutationStack, final int size) { + public static void permutations(List permutations, Collection elements, + Stack permutationStack, int size) { if (permutationStack.size() == size) { permutations.add(permutationStack.toArray(BlockNode[]::new)); } - BlockNode[] availableItems = elements.toArray(BlockNode[]::new); for (BlockNode i : availableItems) { permutationStack.push(i); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorBlockPathTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorBlockPathTraverserHandler.java index 77e65896e..e89b62557 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorBlockPathTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorBlockPathTraverserHandler.java @@ -12,36 +12,30 @@ import jadx.core.utils.exceptions.JadxRuntimeException; public final class PredecessorBlockPathTraverserHandler extends AbstractBlockPathTraverserHandler { - private final ISourceBlockState sourceBlockState; - public PredecessorBlockPathTraverserHandler(final T initialState) { + public PredecessorBlockPathTraverserHandler(T initialState) { super(initialState); - this.sourceBlockState = initialState; } - public PredecessorBlockPathTraverserHandler(final AtomicReference initialStateRef) { + public PredecessorBlockPathTraverserHandler(AtomicReference initialStateRef) { super(initialStateRef); - this.sourceBlockState = initialStateRef.get(); } @Override - protected final void handle() { - final TraverserState baseState = getState(); - final TraverserActivePathState comparator = baseState.getComparatorState(); - final AtomicReference stateRef = comparator.getReferenceForState(baseState); - + protected void handle() { + TraverserState baseState = getState(); + TraverserActivePathState comparator = baseState.getComparatorState(); + AtomicReference stateRef = comparator.getReferenceForState(baseState); if (stateRef == null) { throw new JadxRuntimeException("Orphaned traverser state"); } - - final BlockNode sourceBlock = sourceBlockState.getSourceBlock(); - final AbstractBlockTraverserVisitor visitor = new PredecessorBlockTraverserVisitor(baseState); - final TraverserState nextState = visitor.visit(sourceBlock); + BlockNode sourceBlock = sourceBlockState.getSourceBlock(); + AbstractBlockTraverserVisitor visitor = new PredecessorBlockTraverserVisitor(baseState); + TraverserState nextState = visitor.visit(sourceBlock); stateRef.set(nextState); } - } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorMergeActivePathTraverserHandler.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorMergeActivePathTraverserHandler.java index b1fd22d53..ea66b0035 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorMergeActivePathTraverserHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/PredecessorMergeActivePathTraverserHandler.java @@ -21,11 +21,9 @@ import jadx.core.utils.BlockUtils; public final class PredecessorMergeActivePathTraverserHandler extends AbstractActivePathTraverserHandler { - private static List orderBlocks(final List blocks) { - final List dup = new ArrayList<>(blocks); - + private static List orderBlocks(List blocks) { + List dup = new ArrayList<>(blocks); // Collections.sort(dup, (blk1, blk2) -> Integer.compare(blk1.getCId(), blk2.getCId())); - return dup; } @@ -34,25 +32,24 @@ public final class PredecessorMergeActivePathTraverserHandler extends AbstractAc } @Override - protected final List handle() throws TraverserException { + protected List handle() throws TraverserException { // At this point, we expect the handler to contain the block state of the path which is // requesting a predecessor merge. If the other handler also requests a predecessor merge, // we can merge the two. If not, we'll split the active handler to support the multiple // paths. + TraverserActivePathState comparator = getComparator(); + TraverserState finallyState = comparator.getFinallyState(); + TraverserState candidateState = comparator.getCandidateState(); - final TraverserActivePathState comparator = getComparator(); - final TraverserState finallyState = comparator.getFinallyState(); - final TraverserState candidateState = comparator.getCandidateState(); - - final boolean finallyNeedsDuplicate = finallyState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE; - final boolean candidateNeedsDuplicate = candidateState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE; - final boolean shouldMerge = finallyNeedsDuplicate && candidateNeedsDuplicate; + boolean finallyNeedsDuplicate = finallyState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE; + boolean candidateNeedsDuplicate = candidateState.getCompareState() == TraverserState.ComparisonState.READY_TO_COMPARE; + boolean shouldMerge = finallyNeedsDuplicate && candidateNeedsDuplicate; if (shouldMerge) { return mergeScopes((UnknownAdvanceStrategyTraverserState) finallyState, (UnknownAdvanceStrategyTraverserState) candidateState); } else { - final UnknownAdvanceStrategyTraverserState advancingState; - final TraverserState otherState; + UnknownAdvanceStrategyTraverserState advancingState; + TraverserState otherState; if (finallyNeedsDuplicate) { advancingState = (UnknownAdvanceStrategyTraverserState) finallyState; otherState = candidateState; @@ -64,57 +61,57 @@ public final class PredecessorMergeActivePathTraverserHandler extends AbstractAc } } - private List mergeScopes(final UnknownAdvanceStrategyTraverserState finallyState, - final UnknownAdvanceStrategyTraverserState candidateState) throws TraverserException { - final List finallyBlocks = finallyState.getNextBlocks(); - final List candidateBlocks = candidateState.getNextBlocks(); + private List mergeScopes(UnknownAdvanceStrategyTraverserState finallyState, + UnknownAdvanceStrategyTraverserState candidateState) throws TraverserException { + List finallyBlocks = finallyState.getNextBlocks(); + List candidateBlocks = candidateState.getNextBlocks(); - final int finallyBlocksSize = finallyBlocks.size(); - final int candidateBlocksSize = candidateBlocks.size(); + int finallyBlocksSize = finallyBlocks.size(); + int candidateBlocksSize = candidateBlocks.size(); - final List states; + List states; if (candidateBlocksSize % finallyBlocksSize == 0 && candidateBlocksSize == finallyBlocksSize) { - final List finallyBlocksOrdered = orderBlocks(finallyBlocks); - final List candidateBlocksOrdered = orderBlocks(candidateBlocks); + List finallyBlocksOrdered = orderBlocks(finallyBlocks); + List candidateBlocksOrdered = orderBlocks(candidateBlocks); - final int duplicationCount = candidateBlocksSize / finallyBlocksSize; + int duplicationCount = candidateBlocksSize / finallyBlocksSize; states = new ArrayList<>(duplicationCount); for (int i = 0; i < duplicationCount; i++) { - final List candidateBlocksSubset = new ArrayList<>(finallyBlocksSize); + List candidateBlocksSubset = new ArrayList<>(finallyBlocksSize); for (int j = 0; j < finallyBlocksSize; j++) { candidateBlocksSubset.add(candidateBlocksOrdered.get(i * finallyBlocksSize + j)); } - final TraverserActivePathState comparatorState = getScopeForBlocks(finallyBlocksOrdered, candidateBlocksSubset); + TraverserActivePathState comparatorState = getScopeForBlocks(finallyBlocksOrdered, candidateBlocksSubset); states.add(comparatorState); } } else { - final TraverserStateFactory finallyStateFactory = + TraverserStateFactory finallyStateFactory = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.UNMERGEABLE_STATE); - final TraverserStateFactory candidateStateFactory = + TraverserStateFactory candidateStateFactory = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.UNMERGEABLE_STATE); - final TraverserActivePathState newState = + TraverserActivePathState newState = TraverserActivePathState.produceFromFactories(getComparator(), finallyStateFactory, candidateStateFactory); states = List.of(newState); } return states; } - private List duplicateForPaths(final TraverserActivePathState comparator, - final UnknownAdvanceStrategyTraverserState advancingState, final TraverserState otherState, - final boolean duplicateIsFromFinally) { - final List nextPredecessors = advancingState.getNextBlocks(); - final List newPaths = new ArrayList<>(nextPredecessors.size()); - for (final BlockNode predecessor : nextPredecessors) { - final CentralityState centralityState = advancingState.getCentralityState(); - final TraverserBlockInfo duplicatePathBlockInfo = new TraverserBlockInfo(predecessor); - final TraverserStateFactory duplicatePathStateFactory = + private List duplicateForPaths(TraverserActivePathState comparator, + UnknownAdvanceStrategyTraverserState advancingState, TraverserState otherState, + boolean duplicateIsFromFinally) { + List nextPredecessors = advancingState.getNextBlocks(); + List newPaths = new ArrayList<>(nextPredecessors.size()); + for (BlockNode predecessor : nextPredecessors) { + CentralityState centralityState = advancingState.getCentralityState(); + TraverserBlockInfo duplicatePathBlockInfo = new TraverserBlockInfo(predecessor); + TraverserStateFactory duplicatePathStateFactory = NewBlockTraverserState.getFactory(centralityState, duplicatePathBlockInfo); - final TraverserStateFactory otherStateFactory = new DuplicatedTraverserStateFactory<>(otherState); + TraverserStateFactory otherStateFactory = new DuplicatedTraverserStateFactory<>(otherState); - final TraverserActivePathState comparatorDuplicated = comparator.duplicate(); - final TraverserActivePathState newPathState; + TraverserActivePathState comparatorDuplicated = comparator.duplicate(); + TraverserActivePathState newPathState; if (duplicateIsFromFinally) { newPathState = TraverserActivePathState.produceFromFactories(comparatorDuplicated, duplicatePathStateFactory, otherStateFactory); @@ -124,29 +121,28 @@ public final class PredecessorMergeActivePathTraverserHandler extends AbstractAc } newPaths.add(newPathState); } - return newPaths; } - private TraverserActivePathState getScopeForBlocks(final List finallyBlocks, final List candidateBlocks) { - final TraverserActivePathState comparator = getComparator(); - final MethodNode mth = getComparator().getGlobalCommonState().getMethodNode(); + private TraverserActivePathState getScopeForBlocks(List finallyBlocks, List candidateBlocks) { + TraverserActivePathState comparator = getComparator(); + MethodNode mth = getComparator().getGlobalCommonState().getMethodNode(); - final TraverserState finallyState = comparator.getFinallyState(); - final TraverserState candidateState = comparator.getCandidateState(); + TraverserState finallyState = comparator.getFinallyState(); + TraverserState candidateState = comparator.getCandidateState(); - final GlobalTraverserSourceState finallyGlobalState = comparator.getGlobalStateFor(finallyState); - final CentralityState finallyCentralityState = finallyState.getCentralityState(); - final BlockNode finallyTerminator = + GlobalTraverserSourceState finallyGlobalState = comparator.getGlobalStateFor(finallyState); + CentralityState finallyCentralityState = finallyState.getCentralityState(); + BlockNode finallyTerminator = BlockUtils.getBottomCommonPredecessor(mth, finallyBlocks, finallyGlobalState.getContainedBlocks()); - final TraverserStateFactory finallyStateFactory = + TraverserStateFactory finallyStateFactory = IdentifiedScopeWithTerminatorTraverserState.getFactory(finallyCentralityState, finallyBlocks, finallyTerminator); - final GlobalTraverserSourceState candidateGlobalState = comparator.getGlobalStateFor(candidateState); - final CentralityState candidateCentralityState = candidateState.getCentralityState(); - final BlockNode candidateTerminator = + GlobalTraverserSourceState candidateGlobalState = comparator.getGlobalStateFor(candidateState); + CentralityState candidateCentralityState = candidateState.getCentralityState(); + BlockNode candidateTerminator = BlockUtils.getBottomCommonPredecessor(mth, candidateBlocks, candidateGlobalState.getContainedBlocks()); - final TraverserStateFactory candidateStateFactory = + TraverserStateFactory candidateStateFactory = IdentifiedScopeWithTerminatorTraverserState.getFactory(candidateCentralityState, candidateBlocks, candidateTerminator); return TraverserActivePathState.produceFromFactories(comparator, finallyStateFactory, candidateStateFactory); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/AwaitingInsnCompareTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/AwaitingInsnCompareTraverserState.java index c5a6385e7..0cdb423cd 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/AwaitingInsnCompareTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/AwaitingInsnCompareTraverserState.java @@ -7,50 +7,45 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.AbstractBlockTraverserHa import jadx.core.dex.visitors.finaly.traverser.handlers.InstructionActivePathTraverserHandler; public final class AwaitingInsnCompareTraverserState extends TraverserState { - private final CentralityState centralityState; private final @Nullable TraverserBlockInfo blockInsnInfo; - public AwaitingInsnCompareTraverserState(final TraverserActivePathState state, final CentralityState centralityState, - final TraverserBlockInfo blockInsnInfo) { + public AwaitingInsnCompareTraverserState(TraverserActivePathState state, CentralityState centralityState, + TraverserBlockInfo blockInsnInfo) { super(state); - this.centralityState = centralityState; this.blockInsnInfo = blockInsnInfo; } @Override - public final @Nullable AbstractBlockTraverserHandler getNextHandler() { + public @Nullable AbstractBlockTraverserHandler getNextHandler() { return new InstructionActivePathTraverserHandler(getComparatorState()); } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.READY_TO_COMPARE; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return false; } @Override - protected final @Nullable CentralityState getUnderlyingCentralityState() { + protected @Nullable CentralityState getUnderlyingCentralityState() { return centralityState; } @Override - protected final @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { + protected @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { return blockInsnInfo; } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { - final CentralityState dCentralityState = centralityState.duplicate(); - final TraverserBlockInfo dBlockInsnInfo = blockInsnInfo.duplicate(); - - final TraverserState duplicated = new AwaitingInsnCompareTraverserState(comparatorState, dCentralityState, dBlockInsnInfo); - - return duplicated; + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { + CentralityState dCentralityState = centralityState.duplicate(); + TraverserBlockInfo dBlockInsnInfo = blockInsnInfo.duplicate(); + return new AwaitingInsnCompareTraverserState(comparatorState, dCentralityState, dBlockInsnInfo); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/ISourceBlockState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/ISourceBlockState.java index 4f119baf5..a827893ca 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/ISourceBlockState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/ISourceBlockState.java @@ -4,5 +4,5 @@ import jadx.core.dex.nodes.BlockNode; public interface ISourceBlockState { - public abstract BlockNode getSourceBlock(); + BlockNode getSourceBlock(); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/IdentifiedScopeWithTerminatorTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/IdentifiedScopeWithTerminatorTraverserState.java index 79b893414..ce8496c82 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/IdentifiedScopeWithTerminatorTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/IdentifiedScopeWithTerminatorTraverserState.java @@ -12,8 +12,8 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.MergePathActivePathTrave public final class IdentifiedScopeWithTerminatorTraverserState extends TraverserState { - public static TraverserStateFactory getFactory(final CentralityState centralityState, - final List roots, final BlockNode scopeTerminator) { + public static TraverserStateFactory getFactory(CentralityState centralityState, + List roots, BlockNode scopeTerminator) { return new IdentifiedScopeWithTerminatorStateFactory(centralityState, roots, scopeTerminator); } @@ -24,15 +24,15 @@ public final class IdentifiedScopeWithTerminatorTraverserState extends Traverser private final List roots; private final BlockNode scopeTerminator; - public IdentifiedScopeWithTerminatorStateFactory(final CentralityState centralityState, final List roots, - final BlockNode scopeTerminator) { + public IdentifiedScopeWithTerminatorStateFactory(CentralityState centralityState, List roots, + BlockNode scopeTerminator) { this.centralityState = centralityState; this.roots = roots; this.scopeTerminator = scopeTerminator; } @Override - public final IdentifiedScopeWithTerminatorTraverserState generateInternalState(final TraverserActivePathState state) { + public IdentifiedScopeWithTerminatorTraverserState generateInternalState(TraverserActivePathState state) { return new IdentifiedScopeWithTerminatorTraverserState(state, centralityState, roots, scopeTerminator); } } @@ -41,8 +41,8 @@ public final class IdentifiedScopeWithTerminatorTraverserState extends Traverser private final List roots; private final BlockNode scopeTerminator; - public IdentifiedScopeWithTerminatorTraverserState(final TraverserActivePathState state, final CentralityState centralityState, - final List roots, final BlockNode scopeTerminator) { + public IdentifiedScopeWithTerminatorTraverserState(TraverserActivePathState state, CentralityState centralityState, + List roots, BlockNode scopeTerminator) { super(state); this.roots = roots; this.scopeTerminator = scopeTerminator; @@ -50,40 +50,40 @@ public final class IdentifiedScopeWithTerminatorTraverserState extends Traverser } @Override - public final @Nullable AbstractBlockTraverserHandler getNextHandler() { + public @Nullable AbstractBlockTraverserHandler getNextHandler() { return new MergePathActivePathTraverserHandler(getComparatorState()); } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.READY_TO_COMPARE; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return false; } @Override - protected final @Nullable CentralityState getUnderlyingCentralityState() { + protected @Nullable CentralityState getUnderlyingCentralityState() { return centralityState; } @Override - protected final @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { + protected @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { return null; } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { return new IdentifiedScopeWithTerminatorTraverserState(comparatorState, centralityState, roots, scopeTerminator); } - public final BlockNode getTerminus() { + public BlockNode getTerminus() { return scopeTerminator; } - public final List getRoots() { + public List getRoots() { return roots; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NewBlockTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NewBlockTraverserState.java index 43b0c03d2..eba9edea7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NewBlockTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NewBlockTraverserState.java @@ -9,23 +9,22 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.BaseBlockTraverserHandle public final class NewBlockTraverserState extends TraverserState { - public static final TraverserStateFactory getFactory(final CentralityState centralityState, - final TraverserBlockInfo blockInsnInfo) { + public static TraverserStateFactory getFactory(CentralityState centralityState, + TraverserBlockInfo blockInsnInfo) { return new NewBlockStateFactory(centralityState, blockInsnInfo); } private static class NewBlockStateFactory extends TraverserStateFactory { - private final CentralityState centralityState; private final TraverserBlockInfo blockInsnInfo; - public NewBlockStateFactory(final CentralityState centralityState, final TraverserBlockInfo blockInsnInfo) { + public NewBlockStateFactory(CentralityState centralityState, TraverserBlockInfo blockInsnInfo) { this.centralityState = centralityState; this.blockInsnInfo = blockInsnInfo; } @Override - public NewBlockTraverserState generateInternalState(final TraverserActivePathState state) { + public NewBlockTraverserState generateInternalState(TraverserActivePathState state) { return new NewBlockTraverserState(state, centralityState, blockInsnInfo); } } @@ -33,20 +32,19 @@ public final class NewBlockTraverserState extends TraverserState { private final CentralityState centralityState; private final @Nullable TraverserBlockInfo blockInsnInfo; - public NewBlockTraverserState(final TraverserActivePathState state, final CentralityState centralityState, - final TraverserBlockInfo blockInsnInfo) { + public NewBlockTraverserState(TraverserActivePathState state, CentralityState centralityState, TraverserBlockInfo blockInsnInfo) { super(state); this.centralityState = centralityState; this.blockInsnInfo = blockInsnInfo; } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.NOT_READY; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return false; } @@ -68,12 +66,9 @@ public final class NewBlockTraverserState extends TraverserState { } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { - final CentralityState dCentralityState = centralityState.duplicate(); - final TraverserBlockInfo dBlockInsnInfo = blockInsnInfo.duplicate(); - - final TraverserState duplicated = new NewBlockTraverserState(comparatorState, dCentralityState, dBlockInsnInfo); - - return duplicated; + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { + CentralityState dCentralityState = centralityState.duplicate(); + TraverserBlockInfo dBlockInsnInfo = blockInsnInfo.duplicate(); + return new NewBlockTraverserState(comparatorState, dCentralityState, dBlockInsnInfo); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NoBlockTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NoBlockTraverserState.java index 43dc11bec..5471a6c86 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NoBlockTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/NoBlockTraverserState.java @@ -10,23 +10,21 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.PredecessorBlockPathTrav public final class NoBlockTraverserState extends TraverserState implements ISourceBlockState { - public static TraverserStateFactory getFactory(final CentralityState centralityState, - final BlockNode sourceBlock) { + public static TraverserStateFactory getFactory(CentralityState centralityState, BlockNode sourceBlock) { return new NoBlockStateFactory(centralityState, sourceBlock); } private static class NoBlockStateFactory extends TraverserStateFactory { - private final CentralityState centralityState; private final BlockNode sourceBlock; - public NoBlockStateFactory(final CentralityState centralityState, final BlockNode sourceBlock) { + public NoBlockStateFactory(CentralityState centralityState, BlockNode sourceBlock) { this.centralityState = centralityState; this.sourceBlock = sourceBlock; } @Override - public NoBlockTraverserState generateInternalState(final TraverserActivePathState state) { + public NoBlockTraverserState generateInternalState(TraverserActivePathState state) { return new NoBlockTraverserState(state, centralityState, sourceBlock); } } @@ -34,45 +32,45 @@ public final class NoBlockTraverserState extends TraverserState implements ISour private final BlockNode sourceBlock; private final CentralityState centralityState; - public NoBlockTraverserState(final TraverserActivePathState state, final CentralityState centralityState, final BlockNode sourceBlock) { + public NoBlockTraverserState(TraverserActivePathState state, CentralityState centralityState, BlockNode sourceBlock) { super(state); this.sourceBlock = sourceBlock; this.centralityState = centralityState; } @Override - public final @Nullable AbstractBlockPathTraverserHandler getNextHandler() { + public @Nullable AbstractBlockPathTraverserHandler getNextHandler() { return new PredecessorBlockPathTraverserHandler<>(this); } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.NOT_READY; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return false; } @Override - protected final @Nullable CentralityState getUnderlyingCentralityState() { + protected @Nullable CentralityState getUnderlyingCentralityState() { return centralityState; } @Override - protected final @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { + protected @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { return null; } @Override - public final BlockNode getSourceBlock() { + public BlockNode getSourceBlock() { return sourceBlock; } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { - final CentralityState dCentralityState = centralityState.duplicate(); + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { + CentralityState dCentralityState = centralityState.duplicate(); return new NoBlockTraverserState(comparatorState, dCentralityState, sourceBlock); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/RecoveredFromCacheTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/RecoveredFromCacheTraverserState.java index 76baffba3..7e6f3a7ae 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/RecoveredFromCacheTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/RecoveredFromCacheTraverserState.java @@ -8,20 +8,19 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.AbstractBlockTraverserHa public final class RecoveredFromCacheTraverserState extends TraverserState { - public static TraverserStateFactory getFactory(final TraverserState underlying) { + public static TraverserStateFactory getFactory(TraverserState underlying) { return new RecoveredFromCacheStateFactory(underlying); } private static final class RecoveredFromCacheStateFactory extends TraverserStateFactory { - private final TraverserState underlying; - private RecoveredFromCacheStateFactory(final TraverserState underlying) { + private RecoveredFromCacheStateFactory(TraverserState underlying) { this.underlying = underlying; } @Override - protected final RecoveredFromCacheTraverserState generateInternalState(final TraverserActivePathState state) { + protected RecoveredFromCacheTraverserState generateInternalState(TraverserActivePathState state) { return new RecoveredFromCacheTraverserState(underlying); } @@ -29,47 +28,46 @@ public final class RecoveredFromCacheTraverserState extends TraverserState { private final TraverserState underlying; - public RecoveredFromCacheTraverserState(final TraverserState underlying) { + public RecoveredFromCacheTraverserState(TraverserState underlying) { super(underlying.getComparatorState()); - this.underlying = underlying; } @Override - public final @Nullable AbstractBlockTraverserHandler getNextHandler() { + public @Nullable AbstractBlockTraverserHandler getNextHandler() { return null; } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.NOT_READY; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return true; } @Override - protected final @Nullable CentralityState getUnderlyingCentralityState() { + protected @Nullable CentralityState getUnderlyingCentralityState() { return null; } @Override - protected final @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { + protected @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { return null; } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { return new RecoveredFromCacheTraverserState(underlying); } - public final TraverserState getUnderlying() { + public TraverserState getUnderlying() { return underlying; } - public final boolean canContinue() { + public boolean canContinue() { return underlying.isTerminal(); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TerminalTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TerminalTraverserState.java index 879ba40a9..674770c00 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TerminalTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TerminalTraverserState.java @@ -8,11 +8,11 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.AbstractBlockPathTravers public final class TerminalTraverserState extends TraverserState { - public static TraverserStateFactory getFactory(final TerminationReason terminationReason) { + public static TraverserStateFactory getFactory(TerminationReason terminationReason) { return new TerminalStateFactory(terminationReason); } - public static enum TerminationReason { + public enum TerminationReason { /** * When comparing instructions within a finally and candidate block, non-matching * instructions were found calling for the termination of the Traverser. @@ -38,10 +38,9 @@ public final class TerminalTraverserState extends TraverserState { } private static class TerminalStateFactory extends TraverserStateFactory { - private final TerminationReason terminationReason; - public TerminalStateFactory(final TerminationReason terminationReason) { + public TerminalStateFactory(TerminationReason terminationReason) { this.terminationReason = terminationReason; } @@ -53,45 +52,42 @@ public final class TerminalTraverserState extends TraverserState { private final TerminationReason terminationReason; - public TerminalTraverserState(final TraverserActivePathState state, final TerminationReason terminationReason) { + public TerminalTraverserState(TraverserActivePathState state, TerminationReason terminationReason) { super(state); this.terminationReason = terminationReason; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return true; } @Override - @Nullable - public final AbstractBlockPathTraverserHandler getNextHandler() { + public @Nullable AbstractBlockPathTraverserHandler getNextHandler() { return null; } - public final TerminationReason getTerminationReason() { + public TerminationReason getTerminationReason() { return terminationReason; } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.NOT_READY; } @Override - protected final @Nullable CentralityState getUnderlyingCentralityState() { + protected @Nullable CentralityState getUnderlyingCentralityState() { return null; } @Override - protected final @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { + protected @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { return null; } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { - final TraverserState duplicated = new TerminalTraverserState(comparatorState, terminationReason); - - return duplicated; + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { + return new TerminalTraverserState(comparatorState, terminationReason); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java index 730f3659d..657b85340 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java @@ -41,20 +41,18 @@ public class TraverserActivePathState { * be held by the resulting active path state. * @return The cloned active path state. */ - public static TraverserActivePathState produceFromFactories(final TraverserActivePathState previousTraverserState, - final TraverserStateFactory finallyStateProducer, final TraverserStateFactory candidateStateProducer) { - final TraverserActivePathState dState = + public static TraverserActivePathState produceFromFactories(TraverserActivePathState previousTraverserState, + TraverserStateFactory finallyStateProducer, TraverserStateFactory candidateStateProducer) { + TraverserActivePathState dState = new TraverserActivePathState(previousTraverserState.matchedInsns, previousTraverserState.finallyCompletionMonitor, previousTraverserState.candidateCompletionMonitor, previousTraverserState.commonGlobalState, previousTraverserState.finallyGlobalState, previousTraverserState.candidateGlobalState); - final TraverserState dFinallyState = finallyStateProducer.generateState(dState); - final TraverserState dCandidateState = candidateStateProducer.generateState(dState); - + TraverserState dFinallyState = finallyStateProducer.generateState(dState); + TraverserState dCandidateState = candidateStateProducer.generateState(dState); dState.candidateStateRef.set(dCandidateState); dState.finallyStateRef.set(dFinallyState); - return dState; } @@ -63,33 +61,29 @@ public class TraverserActivePathState { * i.e. how many of the instructions have been compared in the Traversal. */ private static final class BlockCompletionMonitor { - private final BlockNode block; private final Set matchedIndices; - private final int insnCount; - private BlockCompletionMonitor(final BlockNode block) { + private BlockCompletionMonitor(BlockNode block) { this.block = block; - this.insnCount = block.getInstructions().size(); + int insnCount = block.getInstructions().size(); this.matchedIndices = new HashSet<>(insnCount); for (int i = 0; i < insnCount; i++) { matchedIndices.add(i); } } - private void registerWithBlockInfo(final TraverserBlockInfo info, final int numberMatched) { + private void registerWithBlockInfo(TraverserBlockInfo info, int numberMatched) { if (info.getBlock() != block) { return; } - - final int botPointer = info.getBottomOffset(); + int botPointer = info.getBottomOffset(); for (int i = 0; i < numberMatched; i++) { - final int indexMatched = botPointer + i; + int indexMatched = botPointer + i; matchedIndices.remove(indexMatched); } - - final int bottomImplicitCount = info.getBottomImplicitCount(); - final boolean noPathEndInsns = botPointer - bottomImplicitCount == 0; + int bottomImplicitCount = info.getBottomImplicitCount(); + boolean noPathEndInsns = botPointer - bottomImplicitCount == 0; if (noPathEndInsns) { for (int i = 0; i < bottomImplicitCount; i++) { matchedIndices.remove(i); @@ -98,16 +92,15 @@ public class TraverserActivePathState { } private BlockCompletionMonitor duplicate() { - final BlockCompletionMonitor dup = new BlockCompletionMonitor(block); + BlockCompletionMonitor dup = new BlockCompletionMonitor(block); dup.matchedIndices.retainAll(matchedIndices); return dup; } - private void mergeWith(final BlockCompletionMonitor other) { + private void mergeWith(BlockCompletionMonitor other) { if (other.block != block) { return; } - matchedIndices.retainAll(other.matchedIndices); } @@ -125,101 +118,100 @@ public class TraverserActivePathState { } @Override - public final void clear() { + public void clear() { underlying.clear(); } @Override - public final boolean containsKey(Object key) { + public boolean containsKey(Object key) { return underlying.containsKey(key); } @Override - public final boolean containsValue(Object value) { + public boolean containsValue(Object value) { if (!(value instanceof BlockNode)) { return false; } - - final BlockNode edge = (BlockNode) value; + BlockNode edge = (BlockNode) value; return underlying.containsKey(edge); } @Override - public final Set> entrySet() { + public Set> entrySet() { return underlying.entrySet(); } @Override - public final BlockCompletionMonitor get(Object key) { + public BlockCompletionMonitor get(Object key) { return underlying.get(key); } @Override - public final boolean isEmpty() { + public boolean isEmpty() { return underlying.isEmpty(); } @Override - public final Set keySet() { + public Set keySet() { return underlying.keySet(); } @Override - public final BlockCompletionMonitor put(BlockNode key, BlockCompletionMonitor value) { + public BlockCompletionMonitor put(BlockNode key, BlockCompletionMonitor value) { return underlying.put(key, value); } @Override - public final void putAll(Map otherMap) { + public void putAll(Map otherMap) { underlying.putAll(otherMap); } @Override - public final BlockCompletionMonitor remove(Object key) { + public BlockCompletionMonitor remove(Object key) { return underlying.remove(key); } @Override - public final int size() { + public int size() { return underlying.size(); } @Override - public final Collection values() { + public Collection values() { return underlying.values(); } - private void registerWithBlockInfo(final TraverserBlockInfo info, final int numberMatched) { - final BlockNode block = info.getBlock(); + private void registerWithBlockInfo(TraverserBlockInfo info, int numberMatched) { + BlockNode block = info.getBlock(); if (containsKey(block)) { get(block).registerWithBlockInfo(info, numberMatched); } else { - final BlockCompletionMonitor monitor = new BlockCompletionMonitor(block); + BlockCompletionMonitor monitor = new BlockCompletionMonitor(block); monitor.registerWithBlockInfo(info, numberMatched); put(block, monitor); } } - private void mergeEntry(final BlockCompletionMonitor other) { - final BlockNode block = other.block; + private void mergeEntry(BlockCompletionMonitor other) { + BlockNode block = other.block; if (containsKey(block)) { get(block).mergeWith(other); } else { - final BlockCompletionMonitor monitor = other.duplicate(); + BlockCompletionMonitor monitor = other.duplicate(); put(block, monitor); } } - private void mergeMap(final BlockCompletionMonitorMap other) { - for (final BlockCompletionMonitor monitor : other.values()) { + private void mergeMap(BlockCompletionMonitorMap other) { + for (BlockCompletionMonitor monitor : other.values()) { mergeEntry(monitor); } } private BlockCompletionMonitorMap duplicate() { - final BlockCompletionMonitorMap dup = new BlockCompletionMonitorMap(); - for (final BlockNode sourceBlock : keySet()) { - final BlockCompletionMonitor monitor = get(sourceBlock); + BlockCompletionMonitorMap dup = new BlockCompletionMonitorMap(); + for (BlockNode sourceBlock : keySet()) { + BlockCompletionMonitor monitor = get(sourceBlock); dup.put(sourceBlock, monitor.duplicate()); } return dup; @@ -239,27 +231,20 @@ public class TraverserActivePathState { /** * Creates a new instance of a traversal active path. This constructor is used to create a new * path to be used by the traverser controller to begin a new traversal. - * - * @param mth - * @param sameInstructionsStrategy - * @param finallyBlockTerminus - * @param candidateBlockTerminus - * @param finallyBlocks - * @param candidateBlocks */ - public TraverserActivePathState(final MethodNode mth, final SameInstructionsStrategy sameInstructionsStrategy, - final BlockNode finallyBlockTerminus, final BlockNode candidateBlockTerminus, final List finallyBlocks, - final List candidateBlocks) { - final boolean shouldFinallyAllowFirstBlockSkip = !finallyBlockTerminus.getInstructions().isEmpty(); - final boolean shouldCandidateAllowFirstBlockSkip = !candidateBlockTerminus.getInstructions().isEmpty(); - final CentralityState finallyCentralityState = new CentralityState(sameInstructionsStrategy, shouldFinallyAllowFirstBlockSkip); - final CentralityState candidateCentralityState = new CentralityState(sameInstructionsStrategy, shouldCandidateAllowFirstBlockSkip); + public TraverserActivePathState(MethodNode mth, SameInstructionsStrategy sameInstructionsStrategy, + BlockNode finallyBlockTerminus, BlockNode candidateBlockTerminus, List finallyBlocks, + List candidateBlocks) { + boolean shouldFinallyAllowFirstBlockSkip = !finallyBlockTerminus.getInstructions().isEmpty(); + boolean shouldCandidateAllowFirstBlockSkip = !candidateBlockTerminus.getInstructions().isEmpty(); + CentralityState finallyCentralityState = new CentralityState(sameInstructionsStrategy, shouldFinallyAllowFirstBlockSkip); + CentralityState candidateCentralityState = new CentralityState(sameInstructionsStrategy, shouldCandidateAllowFirstBlockSkip); - final TraverserBlockInfo finallyBlockInfo = new TraverserBlockInfo(finallyBlockTerminus); - final TraverserBlockInfo candidateBlockInfo = new TraverserBlockInfo(candidateBlockTerminus); + TraverserBlockInfo finallyBlockInfo = new TraverserBlockInfo(finallyBlockTerminus); + TraverserBlockInfo candidateBlockInfo = new TraverserBlockInfo(candidateBlockTerminus); - final TraverserState finallyState = new NewBlockTraverserState(this, finallyCentralityState, finallyBlockInfo); - final TraverserState candidateState = new NewBlockTraverserState(this, candidateCentralityState, candidateBlockInfo); + TraverserState finallyState = new NewBlockTraverserState(this, finallyCentralityState, finallyBlockInfo); + TraverserState candidateState = new NewBlockTraverserState(this, candidateCentralityState, candidateBlockInfo); this.finallyGlobalState = new GlobalTraverserSourceState(new HashSet<>(finallyBlocks)); this.candidateGlobalState = new GlobalTraverserSourceState(new HashSet<>(candidateBlocks)); @@ -276,17 +261,10 @@ public class TraverserActivePathState { * Creates a new instance of a traversal active path. This constructor is used to duplicate a * state between a previous traverser controller and is a liaison for initialising non-null * final fields for the {@link TraverserActivePathState#produceFromFactories} function. - * - * @param matchedInsns - * @param finallyCompletionMonitor - * @param candidateCompletionMonitor - * @param commonGlobalState - * @param finallyGlobalState - * @param candidateGlobalState */ - private TraverserActivePathState(final Set> matchedInsns, final BlockCompletionMonitorMap finallyCompletionMonitor, - final BlockCompletionMonitorMap candidateCompletionMonitor, final TraverserGlobalCommonState commonGlobalState, - final GlobalTraverserSourceState finallyGlobalState, final GlobalTraverserSourceState candidateGlobalState) { + private TraverserActivePathState(Set> matchedInsns, BlockCompletionMonitorMap finallyCompletionMonitor, + BlockCompletionMonitorMap candidateCompletionMonitor, TraverserGlobalCommonState commonGlobalState, + GlobalTraverserSourceState finallyGlobalState, GlobalTraverserSourceState candidateGlobalState) { this.finallyStateRef = new AtomicReference<>(); this.candidateStateRef = new AtomicReference<>(); this.matchedInsns = matchedInsns; @@ -298,19 +276,17 @@ public class TraverserActivePathState { } public final TraverserActivePathState duplicate() { - final Set> dMatchedInsns = new HashSet<>(matchedInsns); - final BlockCompletionMonitorMap dFinallyCompletionMonitor = finallyCompletionMonitor.duplicate(); - final BlockCompletionMonitorMap dCandidateCompletionMonitor = candidateCompletionMonitor.duplicate(); - final TraverserActivePathState dState = + Set> dMatchedInsns = new HashSet<>(matchedInsns); + BlockCompletionMonitorMap dFinallyCompletionMonitor = finallyCompletionMonitor.duplicate(); + BlockCompletionMonitorMap dCandidateCompletionMonitor = candidateCompletionMonitor.duplicate(); + TraverserActivePathState dState = new TraverserActivePathState(dMatchedInsns, dFinallyCompletionMonitor, dCandidateCompletionMonitor, commonGlobalState, finallyGlobalState, candidateGlobalState); - final TraverserState dFinallyState = getFinallyState().duplicate(dState); - final TraverserState dCandidateState = getCandidateState().duplicate(dState); - + TraverserState dFinallyState = getFinallyState().duplicate(dState); + TraverserState dCandidateState = getCandidateState().duplicate(dState); dState.candidateStateRef.set(dCandidateState); dState.finallyStateRef.set(dFinallyState); - return dState; } @@ -335,24 +311,24 @@ public class TraverserActivePathState { } @Nullable - public final AtomicReference getReferenceForState(final TraverserState state) { + public final AtomicReference getReferenceForState(TraverserState state) { if (finallyStateRef.get() == state) { return finallyStateRef; - } else if (candidateStateRef.get() == state) { - return candidateStateRef; - } else { - return null; } + if (candidateStateRef.get() == state) { + return candidateStateRef; + } + return null; } - public final GlobalTraverserSourceState getGlobalStateFor(final TraverserState state) { + public final GlobalTraverserSourceState getGlobalStateFor(TraverserState state) { if (finallyStateRef.get() == state) { return finallyGlobalState; - } else if (candidateStateRef.get() == state) { - return candidateGlobalState; - } else { - throw new JadxRuntimeException("Orphaned TraverserState node"); } + if (candidateStateRef.get() == state) { + return candidateGlobalState; + } + throw new JadxRuntimeException("Orphaned TraverserState node"); } public final GlobalTraverserSourceState getFinallyGlobalState() { @@ -367,8 +343,8 @@ public class TraverserActivePathState { return commonGlobalState; } - public final void mergeWith(final List otherStates) { - for (final TraverserActivePathState otherState : otherStates) { + public final void mergeWith(List otherStates) { + for (TraverserActivePathState otherState : otherStates) { matchedInsns.addAll(otherState.getMatchedInsns()); finallyCompletionMonitor.mergeMap(otherState.finallyCompletionMonitor); @@ -376,10 +352,10 @@ public class TraverserActivePathState { } } - public final void registerWithBlockInfo(final TraverserBlockInfo info, final int numberMatched) { - final BlockNode block = info.getBlock(); - final boolean isFinallyBlock = finallyGlobalState.isBlockContained(block); - final BlockCompletionMonitorMap monitorMap; + public final void registerWithBlockInfo(TraverserBlockInfo info, int numberMatched) { + BlockNode block = info.getBlock(); + boolean isFinallyBlock = finallyGlobalState.isBlockContained(block); + BlockCompletionMonitorMap monitorMap; if (isFinallyBlock) { monitorMap = finallyCompletionMonitor; } else { @@ -396,17 +372,14 @@ public class TraverserActivePathState { return getAllFullyMatchedBlocks(candidateCompletionMonitor); } - private Set getAllFullyMatchedBlocks(final BlockCompletionMonitorMap monitorMap) { - final Set matches = new HashSet<>(); - - for (final BlockCompletionMonitor monitor : monitorMap.values()) { + private Set getAllFullyMatchedBlocks(BlockCompletionMonitorMap monitorMap) { + Set matches = new HashSet<>(); + for (BlockCompletionMonitor monitor : monitorMap.values()) { if (!monitor.isEntireBlock()) { continue; } - matches.add(monitor.block); } - return matches; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserBlockInfo.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserBlockInfo.java index db0fd75d2..2877154b0 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserBlockInfo.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserBlockInfo.java @@ -6,7 +6,6 @@ import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.InsnNode; public final class TraverserBlockInfo { - private final BlockNode block; // These offsets are the instruction indices NOT an instruction size. @@ -14,11 +13,11 @@ public final class TraverserBlockInfo { private int topOffset; private int bottomImplicitCount; - public TraverserBlockInfo(final BlockNode block) { + public TraverserBlockInfo(BlockNode block) { this(block, 0, 0, 0); } - public TraverserBlockInfo(final BlockNode block, final int bottomOffset, final int topOffset, final int bottomImplicitCount) { + public TraverserBlockInfo(BlockNode block, int bottomOffset, int topOffset, int bottomImplicitCount) { this.bottomOffset = bottomOffset; this.topOffset = topOffset; this.block = block; @@ -26,67 +25,62 @@ public final class TraverserBlockInfo { } @Override - public final String toString() { + public String toString() { return toString(""); } - public final String toString(final String indent) { - final StringBuilder sb = new StringBuilder("BlockInsnInfo - "); - + public String toString(String indent) { + StringBuilder sb = new StringBuilder("BlockInsnInfo - "); sb.append(block.toString()); sb.append(" [↑ "); sb.append(bottomOffset); sb.append("] [↓ "); sb.append(topOffset); sb.append("] "); - return sb.toString(); } - public final TraverserBlockInfo duplicate() { + public TraverserBlockInfo duplicate() { return new TraverserBlockInfo(block, bottomOffset, topOffset, bottomImplicitCount); } - public final BlockNode getBlock() { + public BlockNode getBlock() { return block; } - public final int getTopOffset() { + public int getTopOffset() { return topOffset; } - public final void setTopOffset(final int topOffset) { + public void setTopOffset(int topOffset) { this.topOffset = topOffset; } - public final int getBottomOffset() { + public int getBottomOffset() { return bottomOffset; } - public final void setBottomOffset(final int bottomOffset) { + public void setBottomOffset(int bottomOffset) { this.bottomOffset = bottomOffset; } - public final int getBottomImplicitCount() { + public int getBottomImplicitCount() { return bottomImplicitCount; } - public final void setBottomImplicitOffset(final int bottomImplicitCount) { + public void setBottomImplicitOffset(int bottomImplicitCount) { this.bottomImplicitCount = bottomImplicitCount; } - public final List getInsnsSlice() { - final List insns = block.getInstructions(); - - final int totalSkippedCount = bottomOffset + topOffset; + public List getInsnsSlice() { + List insns = block.getInstructions(); + int totalSkippedCount = bottomOffset + topOffset; if (totalSkippedCount > insns.size()) { throw new IndexOutOfBoundsException("Attempted to get instructions slice of block " + block.toString() + " with " + totalSkippedCount + " skipped instructions whilst only having " + insns.size() + " instructions in block."); } - - final int startIndex = topOffset; - final int endIndex = insns.size() - bottomOffset; - + int startIndex = topOffset; + int endIndex = insns.size() - bottomOffset; return insns.subList(startIndex, endIndex); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserGlobalCommonState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserGlobalCommonState.java index 803ea4c86..981e92f9c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserGlobalCommonState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserGlobalCommonState.java @@ -11,33 +11,31 @@ import jadx.core.dex.nodes.MethodNode; import jadx.core.utils.Pair; public final class TraverserGlobalCommonState { - private final MethodNode mth; private final Map, List> searchedStates; - public TraverserGlobalCommonState(final MethodNode mth) { + public TraverserGlobalCommonState(MethodNode mth) { this.mth = mth; this.searchedStates = new HashMap<>(); } - public final void addCachedStateFor(final BlockNode finallyBlock, final BlockNode candidateBlock, - final List state) { - final Pair blocks = new Pair<>(finallyBlock, candidateBlock); + public void addCachedStateFor(BlockNode finallyBlock, BlockNode candidateBlock, List state) { + Pair blocks = new Pair<>(finallyBlock, candidateBlock); searchedStates.put(blocks, state); } @Nullable - public final List getCachedStateFor(final BlockNode finallyBlock, final BlockNode candidateBlock) { - final Pair blocks = new Pair<>(finallyBlock, candidateBlock); + public List getCachedStateFor(BlockNode finallyBlock, BlockNode candidateBlock) { + Pair blocks = new Pair<>(finallyBlock, candidateBlock); return searchedStates.get(blocks); } - public final boolean hasBlocksBeenCached(final BlockNode finallyBlock, final BlockNode candidateBlock) { - final Pair blocks = new Pair<>(finallyBlock, candidateBlock); + public boolean hasBlocksBeenCached(BlockNode finallyBlock, BlockNode candidateBlock) { + Pair blocks = new Pair<>(finallyBlock, candidateBlock); return searchedStates.containsKey(blocks); } - public final MethodNode getMethodNode() { + public MethodNode getMethodNode() { return mth; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserState.java index d8c3cc380..d4df30d73 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserState.java @@ -8,7 +8,7 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.AbstractBlockTraverserHa public abstract class TraverserState { - public static enum ComparisonState { + public enum ComparisonState { NOT_READY, AWAITING_OPTIONAL_PREDECESSOR_MERGE, READY_TO_COMPARE @@ -16,12 +16,11 @@ public abstract class TraverserState { private final TraverserActivePathState comparatorState; - public TraverserState(final TraverserActivePathState comparatorState) { + public TraverserState(TraverserActivePathState comparatorState) { this.comparatorState = comparatorState; } - @Nullable - public abstract AbstractBlockTraverserHandler getNextHandler(); + public abstract @Nullable AbstractBlockTraverserHandler getNextHandler(); public abstract ComparisonState getCompareState(); @@ -36,40 +35,37 @@ public abstract class TraverserState { * * @return The deep cloned duplication of this Traverser state. */ - protected abstract TraverserState duplicateInternalState(final TraverserActivePathState comparatorState); + protected abstract TraverserState duplicateInternalState(TraverserActivePathState comparatorState); @Override public final String toString() { return toString(0); } - public final TraverserState duplicate(final TraverserActivePathState comparatorState) { - final TraverserState duplicatedState = duplicateInternalState(comparatorState); - return duplicatedState; + public final TraverserState duplicate(TraverserActivePathState comparatorState) { + return duplicateInternalState(comparatorState); } public final TraverserActivePathState getComparatorState() { return comparatorState; } - public final String toString(final int indentAmount) { - final String baseIndent = " ".repeat(indentAmount); - final String secondIndent = " ".repeat(indentAmount + 2); + public final String toString(int indentAmount) { + String baseIndent = " ".repeat(indentAmount); + String secondIndent = " ".repeat(indentAmount + 2); - final StringBuilder sb = new StringBuilder(baseIndent); + StringBuilder sb = new StringBuilder(baseIndent); sb.append(getClass().getSimpleName()); sb.append(' '); - if (isTerminal()) { sb.append("TERMINAL "); } - sb.append(" {"); sb.append(System.lineSeparator()); sb.append(secondIndent); sb.append("centrality: "); - final CentralityState centralityState = getUnderlyingCentralityState(); + CentralityState centralityState = getUnderlyingCentralityState(); if (centralityState == null) { sb.append("none"); } else { @@ -82,7 +78,7 @@ public abstract class TraverserState { sb.append(System.lineSeparator()); sb.append(secondIndent); - final TraverserBlockInfo blockInsnInfo = getBlockInsnInfo(); + TraverserBlockInfo blockInsnInfo = getBlockInsnInfo(); if (blockInsnInfo != null) { sb.append(blockInsnInfo.toString(secondIndent)); } else { @@ -92,12 +88,11 @@ public abstract class TraverserState { sb.append(baseIndent); sb.append("}"); - return sb.toString(); } public final CentralityState getCentralityState() { - final CentralityState underlying = getUnderlyingCentralityState(); + CentralityState underlying = getUnderlyingCentralityState(); if (underlying == null) { throw new UnsupportedOperationException("Centrality state is not supported for " + getClass().getName()); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/UnknownAdvanceStrategyTraverserState.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/UnknownAdvanceStrategyTraverserState.java index 0f091ffdb..0babaff7a 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/UnknownAdvanceStrategyTraverserState.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/UnknownAdvanceStrategyTraverserState.java @@ -11,54 +11,49 @@ import jadx.core.dex.visitors.finaly.traverser.handlers.AbstractActivePathTraver import jadx.core.dex.visitors.finaly.traverser.handlers.PredecessorMergeActivePathTraverserHandler; public final class UnknownAdvanceStrategyTraverserState extends TraverserState { - private final CentralityState centralityState; private final List nextBlocks; - public UnknownAdvanceStrategyTraverserState(final TraverserActivePathState state, final CentralityState centralityState, - final List nextBlocks) { + public UnknownAdvanceStrategyTraverserState(TraverserActivePathState state, CentralityState centralityState, + List nextBlocks) { super(state); - this.centralityState = centralityState; this.nextBlocks = nextBlocks; } @Override - public final @Nullable AbstractActivePathTraverserHandler getNextHandler() { + public @Nullable AbstractActivePathTraverserHandler getNextHandler() { return new PredecessorMergeActivePathTraverserHandler(getComparatorState()); } @Override - public final ComparisonState getCompareState() { + public ComparisonState getCompareState() { return ComparisonState.READY_TO_COMPARE; } @Override - public final boolean isTerminal() { + public boolean isTerminal() { return false; } @Override - protected final @Nullable CentralityState getUnderlyingCentralityState() { + protected @Nullable CentralityState getUnderlyingCentralityState() { return centralityState; } @Override - protected final @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { + protected @Nullable TraverserBlockInfo getUnderlyingBlockInsnInfo() { return null; } @Override - protected final TraverserState duplicateInternalState(final TraverserActivePathState comparatorState) { - final CentralityState dCentralityState = centralityState.duplicate(); - final List dNextBlocks = new ArrayList<>(nextBlocks); - - final TraverserState duplicated = new UnknownAdvanceStrategyTraverserState(comparatorState, dCentralityState, dNextBlocks); - - return duplicated; + protected TraverserState duplicateInternalState(TraverserActivePathState comparatorState) { + CentralityState dCentralityState = centralityState.duplicate(); + List dNextBlocks = new ArrayList<>(nextBlocks); + return new UnknownAdvanceStrategyTraverserState(comparatorState, dCentralityState, dNextBlocks); } - public final List getNextBlocks() { + public List getNextBlocks() { return nextBlocks; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/ImplicitInsnBlockTraverserVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/ImplicitInsnBlockTraverserVisitor.java index f2c0ce1da..ae574c600 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/ImplicitInsnBlockTraverserVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/ImplicitInsnBlockTraverserVisitor.java @@ -11,44 +11,34 @@ import jadx.core.dex.visitors.finaly.traverser.state.TraverserState; public final class ImplicitInsnBlockTraverserVisitor extends AbstractBlockTraverserVisitor { - public static boolean isInstructionImplicit(final InsnNode node) { + public static boolean isInstructionImplicit(InsnNode node) { // An instruction is implicit if it can be safely skipped for comparison when traversing in reverse // order. // The presence of a GOTO should be reflected in the structure of a block graph. // i.e. a GOTO should be the last instruction of a block with a single successor. // Another example might be NOP. - final InsnType type = node.getType(); - switch (type) { - case GOTO: - return true; - default: - return false; - } + return node.getType() == InsnType.GOTO; } - public ImplicitInsnBlockTraverserVisitor(final TraverserState state) { + public ImplicitInsnBlockTraverserVisitor(TraverserState state) { super(state); } @Override - public final TraverserState visit(final BlockNode block) { - final TraverserBlockInfo insnInfo = getState().getBlockInsnInfo(); + public TraverserState visit(BlockNode block) { + TraverserBlockInfo insnInfo = getState().getBlockInsnInfo(); + List insns = insnInfo.getInsnsSlice(); + ListIterator insnsIterator = insns.listIterator(insns.size()); - final List insns = insnInfo.getInsnsSlice(); - final ListIterator insnsIterator = insns.listIterator(insns.size()); - - /** - * The number of instructions that have been identified as "implicit" instructions. - */ + // The number of instructions that have been identified as "implicit" instructions. int bottomDelta = 0; while (insnsIterator.hasPrevious()) { - final InsnNode insn = insnsIterator.previous(); + InsnNode insn = insnsIterator.previous(); if (!isInstructionImplicit(insn)) { break; } bottomDelta++; } - insnInfo.setBottomOffset(insnInfo.getBottomOffset() + bottomDelta); insnInfo.setBottomImplicitOffset(insnInfo.getBottomImplicitCount() + bottomDelta); return getState(); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PathEndBlockTraverserVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PathEndBlockTraverserVisitor.java index 0ce67ac97..8784f2420 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PathEndBlockTraverserVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PathEndBlockTraverserVisitor.java @@ -16,8 +16,8 @@ import jadx.core.dex.visitors.finaly.traverser.state.TraverserState; public final class PathEndBlockTraverserVisitor extends AbstractBlockTraverserVisitor { - public static boolean isInstructionPathEnd(final InsnNode insn) { - final InsnType type = insn.getType(); + public static boolean isInstructionPathEnd(InsnNode insn) { + InsnType type = insn.getType(); switch (type) { case RETURN: @@ -28,29 +28,24 @@ public final class PathEndBlockTraverserVisitor extends AbstractBlockTraverserVi } } - public PathEndBlockTraverserVisitor(final TraverserState state) { + public PathEndBlockTraverserVisitor(TraverserState state) { super(state); } @Override - public final TraverserState visit(final BlockNode block) { - final CentralityState centralityState = getState().getCentralityState(); - - final TraverserBlockInfo insnInfo = getState().getBlockInsnInfo(); - + public TraverserState visit(BlockNode block) { + CentralityState centralityState = getState().getCentralityState(); + TraverserBlockInfo insnInfo = getState().getBlockInsnInfo(); if (!centralityState.getAllowsCentral()) { return new AwaitingInsnCompareTraverserState(getComparator(), centralityState, insnInfo); } + List insns = insnInfo.getInsnsSlice(); + ListIterator insnsIterator = insns.listIterator(insns.size()); - final List insns = insnInfo.getInsnsSlice(); - final ListIterator insnsIterator = insns.listIterator(insns.size()); - - /** - * The number of instructions that have been identified as "path end" instructions. - */ + // The number of instructions that have been identified as "path end" instructions. int bottomDelta = 0; while (insnsIterator.hasPrevious()) { - final InsnNode insn = insnsIterator.previous(); + InsnNode insn = insnsIterator.previous(); // Check if we should ignore the instruction due to it being a "path end" instruction. if (isInstructionPathEnd(insn)) { @@ -68,7 +63,7 @@ public final class PathEndBlockTraverserVisitor extends AbstractBlockTraverserVi // RETURN r2 <-- A path end instruction if (insn.getArgsCount() != 0) { - final InsnArg handlerExitArg = insn.getArg(0); + InsnArg handlerExitArg = insn.getArg(0); // Returned values from instructions can only be register args so we check that the input to the // path end insn is a register arg if (handlerExitArg instanceof RegisterArg) { @@ -89,8 +84,8 @@ public final class PathEndBlockTraverserVisitor extends AbstractBlockTraverserVi insnInfo.setBottomOffset(insnInfo.getBottomOffset() + bottomDelta); - final BlockNode sourceBlock = insnInfo.getBlock(); - final boolean noInstructionsLeft = insnInfo.getBottomOffset() >= sourceBlock.getInstructions().size(); + BlockNode sourceBlock = insnInfo.getBlock(); + boolean noInstructionsLeft = insnInfo.getBottomOffset() >= sourceBlock.getInstructions().size(); if (noInstructionsLeft) { // Mark the state to request finding predecessors to search for duplicate instructions for return new NoBlockTraverserState(getComparator(), centralityState, sourceBlock); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PredecessorBlockTraverserVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PredecessorBlockTraverserVisitor.java index 7a6161bd5..f7580d4f5 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PredecessorBlockTraverserVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/PredecessorBlockTraverserVisitor.java @@ -14,31 +14,28 @@ import jadx.core.utils.ListUtils; public final class PredecessorBlockTraverserVisitor extends AbstractBlockTraverserVisitor { - public PredecessorBlockTraverserVisitor(final TraverserState state) { + public PredecessorBlockTraverserVisitor(TraverserState state) { super(state); } @Override - public final TraverserState visit(final BlockNode block) { - - final TraverserState currentState = getState(); - final CentralityState centralityState = currentState.getCentralityState(); - final GlobalTraverserSourceState globalState = currentState.getGlobalState(); - - final List predecessors = block.getPredecessors(); - final List containedPredecessors = ListUtils.filter(predecessors, globalState::isBlockContained); - final int predecessorsCount = containedPredecessors.size(); + public TraverserState visit(BlockNode block) { + TraverserState currentState = getState(); + CentralityState centralityState = currentState.getCentralityState(); + GlobalTraverserSourceState globalState = currentState.getGlobalState(); + List predecessors = block.getPredecessors(); + List containedPredecessors = ListUtils.filter(predecessors, globalState::isBlockContained); + int predecessorsCount = containedPredecessors.size(); switch (predecessorsCount) { case 0: return new TerminalTraverserState(getComparator(), TerminalTraverserState.TerminationReason.END_OF_PATH); case 1: - final BlockNode nextBlock = containedPredecessors.get(0); - final TraverserBlockInfo blockInfo = new TraverserBlockInfo(nextBlock); + BlockNode nextBlock = containedPredecessors.get(0); + TraverserBlockInfo blockInfo = new TraverserBlockInfo(nextBlock); return new NewBlockTraverserState(getComparator(), centralityState, blockInfo); default: return new UnknownAdvanceStrategyTraverserState(getComparator(), centralityState, containedPredecessors); } } - } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/AbstractTraverserComparatorVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/AbstractTraverserComparatorVisitor.java index b3b08293d..24056ff8d 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/AbstractTraverserComparatorVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/AbstractTraverserComparatorVisitor.java @@ -4,5 +4,5 @@ import jadx.core.dex.visitors.finaly.traverser.state.TraverserActivePathState; public abstract class AbstractTraverserComparatorVisitor { - public abstract TraverserActivePathState visit(final TraverserActivePathState state); + public abstract TraverserActivePathState visit(TraverserActivePathState state); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/InstructionBlockComparatorTraverserVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/InstructionBlockComparatorTraverserVisitor.java index 1c4feaa53..2015e12ee 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/InstructionBlockComparatorTraverserVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/visitors/comparator/InstructionBlockComparatorTraverserVisitor.java @@ -19,42 +19,42 @@ import jadx.core.utils.Pair; public final class InstructionBlockComparatorTraverserVisitor extends AbstractTraverserComparatorVisitor { - private static TraverserActivePathState createStateForPerfectMatch(final TraverserActivePathState previousState, - final BlockNode finallyBlock, - final BlockNode candidateBlock) { - final CentralityState finallyCentralityState = previousState.getFinallyState().getCentralityState().duplicate(); - final CentralityState candidateCentralityState = previousState.getCandidateState().getCentralityState().duplicate(); + private static TraverserActivePathState createStateForPerfectMatch(TraverserActivePathState previousState, + BlockNode finallyBlock, + BlockNode candidateBlock) { + CentralityState finallyCentralityState = previousState.getFinallyState().getCentralityState().duplicate(); + CentralityState candidateCentralityState = previousState.getCandidateState().getCentralityState().duplicate(); finallyCentralityState.setAllowsCentral(false); candidateCentralityState.setAllowsCentral(false); finallyCentralityState.setAllowsNonStartingNode(false); candidateCentralityState.setAllowsNonStartingNode(false); - final TraverserStateFactory finallyStateProducer = + TraverserStateFactory finallyStateProducer = NoBlockTraverserState.getFactory(finallyCentralityState, finallyBlock); - final TraverserStateFactory candidateStateProducer = + TraverserStateFactory candidateStateProducer = NoBlockTraverserState.getFactory(candidateCentralityState, candidateBlock); return TraverserActivePathState.produceFromFactories(previousState, finallyStateProducer, candidateStateProducer); } - private static TraverserActivePathState createStateForUnevenMatch(final TraverserActivePathState previousState, - final TraverserState finallyState, - final TraverserState candidateState, final BlockNode finallyBlock, final BlockNode candidateBlock, final int finallyInsnsSize, - final int candidateInsnsSize) { - final int maxIterateCount = Math.max(finallyInsnsSize, candidateInsnsSize); - final boolean finallyOverruns = finallyInsnsSize > candidateInsnsSize; + private static TraverserActivePathState createStateForUnevenMatch(TraverserActivePathState previousState, + TraverserState finallyState, + TraverserState candidateState, BlockNode finallyBlock, BlockNode candidateBlock, int finallyInsnsSize, + int candidateInsnsSize) { + int maxIterateCount = Math.max(finallyInsnsSize, candidateInsnsSize); + boolean finallyOverruns = finallyInsnsSize > candidateInsnsSize; - final int insnsDelta; - final TraverserStateFactory newFinallyStateProducer; - final TraverserStateFactory newCandidateStateProducer; - final TraverserBlockInfo adjustedBlockInfo; + int insnsDelta; + TraverserStateFactory newFinallyStateProducer; + TraverserStateFactory newCandidateStateProducer; + TraverserBlockInfo adjustedBlockInfo; if (finallyOverruns) { // More finally instructions than candidate instructions - final CentralityState candidateCentralityState = candidateState.getCentralityState().duplicate(); + CentralityState candidateCentralityState = candidateState.getCentralityState().duplicate(); candidateCentralityState.setAllowsCentral(false); candidateCentralityState.setAllowsNonStartingNode(false); - final CentralityState finallyCentralityState = finallyState.getCentralityState(); + CentralityState finallyCentralityState = finallyState.getCentralityState(); finallyCentralityState.setAllowsCentral(false); finallyCentralityState.setAllowsNonStartingNode(false); @@ -64,10 +64,10 @@ public final class InstructionBlockComparatorTraverserVisitor extends AbstractTr newCandidateStateProducer = NoBlockTraverserState.getFactory(candidateCentralityState, candidateBlock); } else { // More candidate instructions than finally instructions - final CentralityState finallyCentralityState = finallyState.getCentralityState().duplicate(); + CentralityState finallyCentralityState = finallyState.getCentralityState().duplicate(); finallyCentralityState.setAllowsCentral(false); finallyCentralityState.setAllowsNonStartingNode(false); - final CentralityState candidateCentralityState = candidateState.getCentralityState(); + CentralityState candidateCentralityState = candidateState.getCentralityState(); candidateCentralityState.setAllowsCentral(false); candidateCentralityState.setAllowsNonStartingNode(false); @@ -82,11 +82,11 @@ public final class InstructionBlockComparatorTraverserVisitor extends AbstractTr return TraverserActivePathState.produceFromFactories(previousState, newFinallyStateProducer, newCandidateStateProducer); } - private static TraverserActivePathState createStateForBlockSkip(final TraverserActivePathState previousState, - final TraverserState finallyState, - final TraverserState candidateState, final BlockNode finallyBlock, final BlockNode candidateBlock) { - final CentralityState finallyCentralityState = finallyState.getCentralityState(); - final CentralityState candidateCentralityState = candidateState.getCentralityState(); + private static TraverserActivePathState createStateForBlockSkip(TraverserActivePathState previousState, + TraverserState finallyState, + TraverserState candidateState, BlockNode finallyBlock, BlockNode candidateBlock) { + CentralityState finallyCentralityState = finallyState.getCentralityState(); + CentralityState candidateCentralityState = candidateState.getCentralityState(); // TODO: Maybe replace this with controller logic so that we can determine if we need to use these // as path ends and then merge above path? @@ -95,23 +95,23 @@ public final class InstructionBlockComparatorTraverserVisitor extends AbstractTr // later iteration. if (finallyCentralityState.getAllowsNonStartingNode()) { finallyCentralityState.setAllowsNonStartingNode(false); - final TraverserStateFactory newFinallyStateProducer = + TraverserStateFactory newFinallyStateProducer = NoBlockTraverserState.getFactory(finallyCentralityState, finallyBlock); - final TraverserStateFactory newCandidateStateProducer = new DuplicatedTraverserStateFactory<>(candidateState); + TraverserStateFactory newCandidateStateProducer = new DuplicatedTraverserStateFactory<>(candidateState); return TraverserActivePathState.produceFromFactories(previousState, newFinallyStateProducer, newCandidateStateProducer); } else { candidateCentralityState.setAllowsNonStartingNode(false); - final TraverserStateFactory newCandidateStateProducer = + TraverserStateFactory newCandidateStateProducer = NoBlockTraverserState.getFactory(candidateCentralityState, candidateBlock); - final TraverserStateFactory newFinallyStateProducer = new DuplicatedTraverserStateFactory<>(finallyState); + TraverserStateFactory newFinallyStateProducer = new DuplicatedTraverserStateFactory<>(finallyState); return TraverserActivePathState.produceFromFactories(previousState, newFinallyStateProducer, newCandidateStateProducer); } } - private static TraverserActivePathState createStateForTerminatorState(final TraverserActivePathState previousState) { - final TraverserStateFactory finallyStateProducer = + private static TraverserActivePathState createStateForTerminatorState(TraverserActivePathState previousState) { + TraverserStateFactory finallyStateProducer = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.NON_MATCHING_INSTRUCTIONS); - final TraverserStateFactory candidateStateProducer = + TraverserStateFactory candidateStateProducer = TerminalTraverserState.getFactory(TerminalTraverserState.TerminationReason.NON_MATCHING_INSTRUCTIONS); return TraverserActivePathState.produceFromFactories(previousState, finallyStateProducer, candidateStateProducer); @@ -120,57 +120,57 @@ public final class InstructionBlockComparatorTraverserVisitor extends AbstractTr private final SameInstructionsStrategy sameInstructionsStrategy = new SameInstructionsStrategyImpl(); @Override - public final TraverserActivePathState visit(final TraverserActivePathState state) { - final TraverserState finallyState = state.getFinallyState(); - final TraverserState candidateState = state.getCandidateState(); + public TraverserActivePathState visit(TraverserActivePathState state) { + TraverserState finallyState = state.getFinallyState(); + TraverserState candidateState = state.getCandidateState(); - final TraverserBlockInfo finallyBlockInfo = finallyState.getBlockInsnInfo(); - final TraverserBlockInfo candidateBlockInfo = candidateState.getBlockInsnInfo(); + TraverserBlockInfo finallyBlockInfo = finallyState.getBlockInsnInfo(); + TraverserBlockInfo candidateBlockInfo = candidateState.getBlockInsnInfo(); if (finallyBlockInfo == null || candidateBlockInfo == null) { throw new UnsupportedOperationException( "The instruction comparator handler has received a state which does not support block insn info"); } - final BlockNode finallyBlock = finallyBlockInfo.getBlock(); - final BlockNode candidateBlock = candidateBlockInfo.getBlock(); + BlockNode finallyBlock = finallyBlockInfo.getBlock(); + BlockNode candidateBlock = candidateBlockInfo.getBlock(); - final List finallyInsns = finallyBlockInfo.getInsnsSlice(); - final List candidateInsns = candidateBlockInfo.getInsnsSlice(); - final int finallyInsnsSize = finallyInsns.size(); - final int candidateInsnsSize = candidateInsns.size(); + List finallyInsns = finallyBlockInfo.getInsnsSlice(); + List candidateInsns = candidateBlockInfo.getInsnsSlice(); + int finallyInsnsSize = finallyInsns.size(); + int candidateInsnsSize = candidateInsns.size(); - final int maxIterateCount = Math.min(finallyInsnsSize, candidateInsnsSize); + int maxIterateCount = Math.min(finallyInsnsSize, candidateInsnsSize); - final List> matchingInsns = new ArrayList<>(maxIterateCount); + List> matchingInsns = new ArrayList<>(maxIterateCount); // Search through each instruction in reverse and see how many match for (int i = 0; i < maxIterateCount; i++) { - final InsnNode candidateInsn = candidateInsns.get(candidateInsnsSize - i - 1); - final InsnNode finallyInsn = finallyInsns.get(finallyInsnsSize - i - 1); + InsnNode candidateInsn = candidateInsns.get(candidateInsnsSize - i - 1); + InsnNode finallyInsn = finallyInsns.get(finallyInsnsSize - i - 1); if (!sameInstructionsStrategy.sameInsns(candidateInsn, finallyInsn)) { break; } - final Pair match = new Pair<>(finallyInsn, candidateInsn); + Pair match = new Pair<>(finallyInsn, candidateInsn); matchingInsns.add(match); } - final int matchedInsnsCount = matchingInsns.size(); + int matchedInsnsCount = matchingInsns.size(); state.registerWithBlockInfo(finallyBlockInfo, matchedInsnsCount); state.registerWithBlockInfo(candidateBlockInfo, matchedInsnsCount); - final boolean finallyOverruns = finallyInsnsSize > candidateInsnsSize; - final boolean candidateOverruns = finallyInsnsSize < candidateInsnsSize; - final boolean sameSizedSlices = !finallyOverruns && !candidateOverruns; - final boolean allMatched = matchedInsnsCount == maxIterateCount; - final boolean noneMatched = matchedInsnsCount == 0; + boolean finallyOverruns = finallyInsnsSize > candidateInsnsSize; + boolean candidateOverruns = finallyInsnsSize < candidateInsnsSize; + boolean sameSizedSlices = !finallyOverruns && !candidateOverruns; + boolean allMatched = matchedInsnsCount == maxIterateCount; + boolean noneMatched = matchedInsnsCount == 0; state.getMatchedInsns().addAll(matchingInsns); - final TraverserActivePathState newState; + TraverserActivePathState newState; if (allMatched) { if (sameSizedSlices) { // All instructions matched and there are no more instructions to match in either @@ -195,9 +195,9 @@ public final class InstructionBlockComparatorTraverserVisitor extends AbstractTr return newState; } - private boolean eitherStateAllowsBlockSkip(final TraverserState finallyState, final TraverserState candidateState) { - final CentralityState finallyCentralityState = finallyState.getCentralityState(); - final CentralityState candidateCentralityState = candidateState.getCentralityState(); + private boolean eitherStateAllowsBlockSkip(TraverserState finallyState, TraverserState candidateState) { + CentralityState finallyCentralityState = finallyState.getCentralityState(); + CentralityState candidateCentralityState = candidateState.getCentralityState(); return finallyCentralityState.getAllowsNonStartingNode() || candidateCentralityState.getAllowsNonStartingNode(); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/rename/SourceFileRename.java b/jadx-core/src/main/java/jadx/core/dex/visitors/rename/SourceFileRename.java index eaff971e8..0f2dbb2f9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/rename/SourceFileRename.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/rename/SourceFileRename.java @@ -30,7 +30,7 @@ public class SourceFileRename extends AbstractVisitor { @Override public void init(RootNode root) throws JadxException { - final var useSourceName = root.getArgs().getUseSourceNameAsClassNameAlias(); + var useSourceName = root.getArgs().getUseSourceNameAsClassNameAlias(); if (useSourceName == UseSourceNameAsClassNameAlias.NEVER) { return; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java index d5be14c5c..9b7376b2d 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeCompare.java @@ -323,8 +323,8 @@ public class TypeCompare { return WIDER; } - final int type1Width = getTypeWidth(type1); - final int type2Width = getTypeWidth(type2); + int type1Width = getTypeWidth(type1); + int type2Width = getTypeWidth(type2); if (type1Width > type2Width) { return WIDER; } else if (type1Width < type2Width) { diff --git a/jadx-core/src/main/java/jadx/core/utils/BetterName.java b/jadx-core/src/main/java/jadx/core/utils/BetterName.java index fd0531b21..212330bdc 100644 --- a/jadx-core/src/main/java/jadx/core/utils/BetterName.java +++ b/jadx-core/src/main/java/jadx/core/utils/BetterName.java @@ -44,12 +44,12 @@ public class BetterName { : secondName; } - final var firstResult = analyze(firstName); - final var secondResult = analyze(secondName); + var firstResult = analyze(firstName); + var secondResult = analyze(secondName); if (firstResult.digitCount != 0 || secondResult.digitCount != 0) { - final var firstRatio = (float) firstResult.digitCount / firstResult.length; - final var secondRatio = (float) secondResult.digitCount / secondResult.length; + var firstRatio = (float) firstResult.digitCount / firstResult.length; + var secondRatio = (float) secondResult.digitCount / secondResult.length; if (Math.abs(secondRatio - firstRatio) >= TOLERANCE) { return firstRatio <= secondRatio @@ -64,7 +64,7 @@ public class BetterName { } private static AnalyzeResult analyze(String name) { - final var result = new AnalyzeResult(); + var result = new AnalyzeResult(); StringUtils.visitCodePoints(name, cp -> { if (Character.isDigit(cp)) { diff --git a/jadx-core/src/main/java/jadx/core/utils/ListUtils.java b/jadx-core/src/main/java/jadx/core/utils/ListUtils.java index 2fbcf7e73..5d94ce94c 100644 --- a/jadx-core/src/main/java/jadx/core/utils/ListUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/ListUtils.java @@ -40,11 +40,11 @@ public class ListUtils { if (list1.size() != list2.size()) { return false; } - final Iterator iter1 = list1.iterator(); - final Iterator iter2 = list2.iterator(); + Iterator iter1 = list1.iterator(); + Iterator iter2 = list2.iterator(); while (iter1.hasNext() && iter2.hasNext()) { - final T item1 = iter1.next(); - final U item2 = iter2.next(); + T item1 = iter1.next(); + U item2 = iter2.next(); if (!comparer.test(item1, item2)) { return false; } diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ResNameUtils.java b/jadx-core/src/main/java/jadx/core/xmlgen/ResNameUtils.java index e0f4f7646..1570e1450 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ResNameUtils.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ResNameUtils.java @@ -26,7 +26,7 @@ class ResNameUtils { return postfix; } - final StringBuilder sb = new StringBuilder(name.length() + 1); + StringBuilder sb = new StringBuilder(name.length() + 1); boolean nameChanged = false; int cp = name.codePointAt(0); @@ -51,7 +51,7 @@ class ResNameUtils { } } - final String sanitizedName = sb.toString(); + String sanitizedName = sb.toString(); if (NameMapper.isReserved(sanitizedName)) { nameChanged = true; } diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java index e54e9cda3..2e0217b7a 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java @@ -483,7 +483,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl } if (constField != null) { - final String newFieldName = ResNameUtils.convertToRFieldName(newResName); + String newFieldName = ResNameUtils.convertToRFieldName(newResName); constField.rename(newFieldName); constField.add(AFlag.DONT_RENAME); } @@ -500,7 +500,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl } if (root.getArgs().isRenameValid()) { - final boolean allowNonPrintable = !root.getArgs().isRenamePrintable(); + boolean allowNonPrintable = !root.getArgs().isRenamePrintable(); newResName = ResNameUtils.sanitizeAsResourceName(newResName, String.format("_res_0x%08x", resRef), allowNonPrintable); } diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java b/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java index 6f770d319..38860ecff 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java @@ -225,7 +225,7 @@ public class ResXmlGen { } break; case "plurals": - final String quantity = PLURALS_MAP.get(value.getNameRef()); + String quantity = PLURALS_MAP.get(value.getNameRef()); addSimpleValue(cw, typeName, itemTag, "quantity", quantity, valueStr); break; default: diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/StringFormattedCheck.java b/jadx-core/src/main/java/jadx/core/xmlgen/StringFormattedCheck.java index dd317fad3..657a525fa 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/StringFormattedCheck.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/StringFormattedCheck.java @@ -36,7 +36,7 @@ public class StringFormattedCheck { return false; } @SuppressWarnings("unchecked") - final Duo other = (Duo) obj; + Duo other = (Duo) obj; if (!Objects.equals(this.m1, other.m1)) { return false; } diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/XMLChar.java b/jadx-core/src/main/java/jadx/core/xmlgen/XMLChar.java index 730e63f56..3d66820d7 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/XMLChar.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/XMLChar.java @@ -907,7 +907,7 @@ public class XMLChar { * @return true if name is a valid Name */ public static boolean isValidName(String name) { - final int length = name.length(); + int length = name.length(); if (length == 0) { return false; } @@ -937,7 +937,7 @@ public class XMLChar { * @return true if name is a valid NCName */ public static boolean isValidNCName(String ncName) { - final int length = ncName.length(); + int length = ncName.length(); if (length == 0) { return false; } @@ -966,7 +966,7 @@ public class XMLChar { * @return true if nmtoken is a valid Nmtoken */ public static boolean isValidNmtoken(String nmtoken) { - final int length = nmtoken.length(); + int length = nmtoken.length(); if (length == 0) { return false; } @@ -1049,7 +1049,7 @@ public class XMLChar { public static String trim(String value) { int start; int end; - final int lengthMinusOne = value.length() - 1; + int lengthMinusOne = value.length() - 1; for (start = 0; start <= lengthMinusOne; ++start) { if (!isSpace(value.charAt(start))) { break; diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/entry/EntryConfig.java b/jadx-core/src/main/java/jadx/core/xmlgen/entry/EntryConfig.java index 2911f8498..7c991f8e6 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/entry/EntryConfig.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/entry/EntryConfig.java @@ -488,7 +488,7 @@ public class EntryConfig { if (getClass() != obj.getClass()) { return false; } - final EntryConfig other = (EntryConfig) obj; + EntryConfig other = (EntryConfig) obj; return this.mQualifiers.equals(other.mQualifiers); }