From e054ea6683fd047d81803bf45be5cf8ff49d9cad Mon Sep 17 00:00:00 2001 From: Skylot Date: Tue, 10 Nov 2020 13:19:20 +0000 Subject: [PATCH] fix: adjust limits to skip processing of large methods (#1012) --- jadx-core/src/main/java/jadx/core/codegen/MethodGen.java | 8 +++++++- .../main/java/jadx/core/dex/visitors/DepthTraversal.java | 4 ++++ .../core/dex/visitors/blocksmaker/BlockProcessor.java | 3 +-- .../jadx/core/dex/visitors/typeinference/TypeSearch.java | 6 ++++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java index 4c5c9b4d9..8aed8616a 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java @@ -290,6 +290,10 @@ public class MethodGen { code.startLine("// Can't load method instructions."); return; } + if (insnArr.length > 100) { + code.startLine("// Method dump skipped, instructions count: " + insnArr.length); + return; + } code.incIndent(); if (mth.getThisArg() != null) { code.startLine(nameGen.useArg(mth.getThisArg())).add(" = this;"); @@ -305,6 +309,7 @@ public class MethodGen { } public static void addFallbackInsns(CodeWriter code, MethodNode mth, InsnNode[] insnArr, FallbackOption option) { + int startIndent = code.getIndent(); InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), true); boolean attachInsns = mth.root().getArgs().isJsonOutput(); InsnNode prevInsn = null; @@ -349,8 +354,9 @@ public class MethodGen { if (catchAttr != null) { code.add(" // " + catchAttr); } - } catch (CodegenException e) { + } catch (Exception e) { LOG.debug("Error generate fallback instruction: ", e.getCause()); + code.setIndent(startIndent); code.startLine("// error: " + insn); } prevInsn = insn; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraversal.java b/jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraversal.java index 76235c25f..6f9fe85ea 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraversal.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraversal.java @@ -1,5 +1,6 @@ package jadx.core.dex.visitors; +import jadx.core.dex.attributes.AType; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.utils.DebugChecks; @@ -19,6 +20,9 @@ public class DepthTraversal { public static void visit(IDexTreeVisitor visitor, MethodNode mth) { try { + if (mth.contains(AType.JADX_ERROR)) { + return; + } visitor.visit(mth); if (DebugChecks.checksEnabled) { DebugChecks.runChecksAfterVisitor(mth, visitor); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java index 0f9c929ed..1c7d697e6 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java @@ -69,8 +69,7 @@ public class BlockProcessor extends AbstractVisitor { updateExitBlocks(mth); if (i++ > 100) { - mth.addWarn("CFG modification limit reached, blocks count: " + mth.getBasicBlocks().size()); - break; + throw new JadxRuntimeException("CFG modification limit reached, blocks count: " + mth.getBasicBlocks().size()); } } checkForUnreachableBlocks(mth); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeSearch.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeSearch.java index c54db5d23..b2c587d9a 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeSearch.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeSearch.java @@ -34,6 +34,7 @@ import jadx.core.dex.nodes.MethodNode; public class TypeSearch { private static final Logger LOG = LoggerFactory.getLogger(TypeSearch.class); + private static final int VARS_PROCESS_LIMIT = 5_000; private static final int CANDIDATES_COUNT_LIMIT = 10; private static final int SEARCH_ITERATION_LIMIT = 1_000_000; @@ -50,6 +51,11 @@ public class TypeSearch { } public boolean run() { + if (mth.getSVars().size() > VARS_PROCESS_LIMIT) { + mth.addWarnComment("Multi-variable search skipped. Vars limit reached: " + mth.getSVars().size() + + " (expected less than " + VARS_PROCESS_LIMIT + ")"); + return false; + } mth.getSVars().forEach(this::fillTypeCandidates); mth.getSVars().forEach(this::collectConstraints);