diff --git a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java index e10974220..9e5e28cf4 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java @@ -50,21 +50,24 @@ public class ClassGen { private final ClassGen parentGen; private final AnnotationGen annotationGen; private final boolean fallback; - - private boolean showInconsistentCode = false; + private final boolean showInconsistentCode; private final Set imports = new HashSet(); private int clsDeclLine; - public ClassGen(ClassNode cls, ClassGen parentClsGen, IJadxArgs jadxArgs) { - this(cls, parentClsGen, jadxArgs.isFallbackMode()); - this.showInconsistentCode = jadxArgs.isShowInconsistentCode(); + public ClassGen(ClassNode cls, IJadxArgs jadxArgs) { + this(cls, null, jadxArgs.isFallbackMode(), jadxArgs.isShowInconsistentCode()); } - public ClassGen(ClassNode cls, ClassGen parentClsGen, boolean fallback) { + public ClassGen(ClassNode cls, ClassGen parentClsGen) { + this(cls, parentClsGen, parentClsGen.fallback, parentClsGen.showInconsistentCode); + } + + public ClassGen(ClassNode cls, ClassGen parentClsGen, boolean fallback, boolean showBadCode) { this.cls = cls; this.parentGen = parentClsGen; this.fallback = fallback; + this.showInconsistentCode = showBadCode; this.annotationGen = new AnnotationGen(cls, this); } @@ -230,7 +233,7 @@ public class ClassGen { || innerCls.isAnonymous()) { continue; } - ClassGen inClGen = new ClassGen(innerCls, getParentGen(), fallback); + ClassGen inClGen = new ClassGen(innerCls, getParentGen()); code.newLine(); inClGen.addClassCode(code); imports.addAll(inClGen.getImports()); @@ -299,6 +302,7 @@ public class ClassGen { ErrorsCounter.methodError(mth, "Inconsistent code"); if (showInconsistentCode) { mth.remove(AFlag.INCONSISTENT_CODE); + badCode = false; } } MethodGen mthGen; @@ -384,7 +388,7 @@ public class ClassGen { } if (f.getCls() != null) { code.add(' '); - new ClassGen(f.getCls(), this, fallback).addClassBody(code); + new ClassGen(f.getCls(), this).addClassBody(code); } if (it.hasNext()) { code.add(','); diff --git a/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java b/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java index c635508a9..90c89e1cd 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java @@ -15,7 +15,7 @@ public class CodeGen extends AbstractVisitor { @Override public boolean visit(ClassNode cls) throws CodegenException { - ClassGen clsGen = new ClassGen(cls, null, args); + ClassGen clsGen = new ClassGen(cls, args); CodeWriter clsCode = clsGen.makeClass(); clsCode.finish(); cls.setCode(clsCode); diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 9aa6ea261..f8458258c 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -554,7 +554,7 @@ public class InsnGen { useClass(code, parent); } code.add("() "); - new ClassGen(cls, mgen.getClassGen().getParentGen(), fallback).addClassBody(code); + new ClassGen(cls, mgen.getClassGen().getParentGen()).addClassBody(code); return; } if (insn.isSelf()) { 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 5b8b003a0..55ffc4bef 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java @@ -235,7 +235,7 @@ public class MethodGen { * Return fallback variant of method codegen */ public static MethodGen getFallbackMethodGen(MethodNode mth) { - ClassGen clsGen = new ClassGen(mth.getParentClass(), null, true); + ClassGen clsGen = new ClassGen(mth.getParentClass(), null, true, true); return new MethodGen(clsGen, mth); } diff --git a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlock.java b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlock.java index 12cd9250c..8532db5a6 100644 --- a/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlock.java +++ b/jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlock.java @@ -88,8 +88,10 @@ public class TryCatchBlock { insn.removeAttr(attr); } insns.clear(); - for (BlockNode block : mth.getBasicBlocks()) { - block.removeAttr(attr); + if (mth.getBasicBlocks() != null) { + for (BlockNode block : mth.getBasicBlocks()) { + block.removeAttr(attr); + } } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java b/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java index 4b6ee94d7..96a9f79a2 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java @@ -1,5 +1,6 @@ package jadx.core.dex.visitors; +import jadx.core.dex.attributes.AType; import jadx.core.dex.info.ClassInfo; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; @@ -39,7 +40,7 @@ public class DependencyCollector extends AbstractVisitor { } // TODO: process annotations and generics for (MethodNode methodNode : cls.getMethods()) { - if (methodNode.isNoCode()) { + if (methodNode.isNoCode() || methodNode.contains(AType.JADX_ERROR)) { continue; } processMethod(dex, depList, methodNode); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessTryCatchRegions.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessTryCatchRegions.java index da018c3e6..e7609380c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessTryCatchRegions.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessTryCatchRegions.java @@ -66,6 +66,10 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor { // for each try block search nearest dominator block for (TryCatchBlock tb : tryBlocks) { + if (tb.getHandlersCount() == 0) { + LOG.warn("No exception handlers in catch block, method: {}", mth); + continue; + } BitSet bs = new BitSet(mth.getBasicBlocks().size()); for (ExceptionHandler excHandler : tb.getHandlers()) { SplitterBlockAttr splitter = excHandler.getHandlerBlock().get(AType.SPLITTER_BLOCK); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java index ca2627190..fc487a0f2 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java @@ -202,14 +202,19 @@ public class SSATransform extends AbstractVisitor { private static void fixPhiInTryCatch(PhiInsn phi) { int argsCount = phi.getArgsCount(); - for (int i = 0; i < argsCount; i++) { - RegisterArg arg = phi.getArg(i); + int k = 0; + while (k < argsCount) { + RegisterArg arg = phi.getArg(k); InsnNode parentInsn = arg.getAssignInsn(); if (parentInsn != null && parentInsn.getResult() != null && parentInsn.contains(AFlag.TRY_LEAVE)) { - phi.removeArg(arg); + if (phi.removeArg(arg)) { + argsCount--; + continue; + } } + k++; } } diff --git a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java index 062d5ad83..c31809c2e 100644 --- a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java @@ -312,8 +312,9 @@ public class BlockUtils { } } - private static boolean traverseSuccessorsUntil(BlockNode from, BlockNode until, BitSet visited) { - for (BlockNode s : from.getCleanSuccessors()) { + private static boolean traverseSuccessorsUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean) { + List nodes = clean ? from.getCleanSuccessors() : from.getSuccessors(); + for (BlockNode s : nodes) { if (s == until) { return true; } @@ -323,7 +324,7 @@ public class BlockUtils { if (until.isDominator(s)) { return true; } - if (traverseSuccessorsUntil(s, until, visited)) { + if (traverseSuccessorsUntil(s, until, visited, clean)) { return true; } } @@ -340,7 +341,19 @@ public class BlockUtils { if (start.getPredecessors().contains(end)) { return false; } - return traverseSuccessorsUntil(start, end, new BitSet()); + return traverseSuccessorsUntil(start, end, new BitSet(), true); + } + + public static boolean isAnyPathExists(BlockNode start, BlockNode end) { + if (start == end + || end.isDominator(start) + || start.getSuccessors().contains(end)) { + return true; + } + if (start.getPredecessors().contains(end)) { + return false; + } + return traverseSuccessorsUntil(start, end, new BitSet(), false); } public static BlockNode getTopBlock(Collection blocks) { @@ -350,7 +363,7 @@ public class BlockUtils { for (BlockNode from : blocks) { boolean top = true; for (BlockNode to : blocks) { - if (from != to && !isPathExists(from, to)) { + if (from != to && !isAnyPathExists(from, to)) { top = false; break; }