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 fa2175449..b86d7067e 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java @@ -237,7 +237,7 @@ public class ClassGen { if (badCode) { code.startLine("/* JADX WARNING: inconsistent code. */"); code.startLine("/* Code decompiled incorrectly, please refer to instructions dump. */"); - LOG.error(ErrorsCounter.formatErrorMsg(mth, " Inconsistent code")); + ErrorsCounter.methodError(mth, "Inconsistent code"); } if (mthGen.addDefinition(code)) { code.add(' '); diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java index 8ea513a85..81d059588 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java @@ -12,29 +12,46 @@ import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.utils.exceptions.DecodeException; +import java.io.EOFException; + import com.android.dx.io.Code; import com.android.dx.io.OpcodeInfo; import com.android.dx.io.Opcodes; import com.android.dx.io.instructions.DecodedInstruction; import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction; import com.android.dx.io.instructions.PackedSwitchPayloadDecodedInstruction; +import com.android.dx.io.instructions.ShortArrayCodeInput; import com.android.dx.io.instructions.SparseSwitchPayloadDecodedInstruction; public class InsnDecoder { private final MethodNode method; - private final DecodedInstruction[] insnArr; private final DexNode dex; + private DecodedInstruction[] insnArr; - public InsnDecoder(MethodNode mthNode, Code mthCode) { + public InsnDecoder(MethodNode mthNode) throws DecodeException { this.method = mthNode; this.dex = method.dex(); - this.insnArr = DecodedInstruction.decodeAll(mthCode.getInstructions()); } - public InsnNode[] run() throws DecodeException { - InsnNode[] instructions = new InsnNode[insnArr.length]; + public void decodeInsns(Code mthCode) throws DecodeException { + short[] encodedInstructions = mthCode.getInstructions(); + int size = encodedInstructions.length; + DecodedInstruction[] decoded = new DecodedInstruction[size]; + ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions); + try { + while (in.hasMore()) { + decoded[in.cursor()] = DecodedInstruction.decode(in); + } + } catch (EOFException e) { + throw new DecodeException(method, "", e); + } + insnArr = decoded; + } + + public InsnNode[] process() throws DecodeException { + InsnNode[] instructions = new InsnNode[insnArr.length]; for (int i = 0; i < insnArr.length; i++) { DecodedInstruction rawInsn = insnArr[i]; if (rawInsn != null) { @@ -48,6 +65,7 @@ public class InsnDecoder { instructions[i] = null; } } + insnArr = null; return instructions; } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java index 0a0f55103..0dda73859 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java @@ -95,7 +95,7 @@ public class RegisterArg extends InsnArg { InsnNode ai = getAssignInsn(); if (ai != null && ai.getType() == InsnType.MOVE) { InsnArg arg = ai.getArg(0); - if (arg != this && arg.isThis()) { + if (arg != this && "this".equals(arg.getTypedVar().getName())) { return true; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index ff154635f..28c49bace 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -3,6 +3,7 @@ package jadx.core.dex.nodes; import jadx.core.Consts; import jadx.core.codegen.CodeWriter; import jadx.core.dex.attributes.AttributeType; +import jadx.core.dex.attributes.JadxErrorAttr; import jadx.core.dex.attributes.LineAttrNode; import jadx.core.dex.attributes.SourceFileAttr; import jadx.core.dex.attributes.annotations.Annotation; @@ -206,7 +207,12 @@ public class ClassNode extends LineAttrNode implements ILoadable { @Override public void load() throws DecodeException { for (MethodNode mth : getMethods()) { - mth.load(); + try { + mth.load(); + } catch (DecodeException e) { + LOG.error("Method load error", e); + mth.getAttributes().add(new JadxErrorAttr(e)); + } } for (ClassNode innerCls : getInnerClasses()) { innerCls.load(); diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index c3daf3567..cc8bbd73e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -87,8 +87,9 @@ public class MethodNode extends LineAttrNode implements ILoadable { regsCount = mthCode.getRegistersSize(); initMethodTypes(); - InsnDecoder decoder = new InsnDecoder(this, mthCode); - InsnNode[] insnByOffset = decoder.run(); + InsnDecoder decoder = new InsnDecoder(this); + decoder.decodeInsns(mthCode); + InsnNode[] insnByOffset = decoder.process(); instructions = new ArrayList(); for (InsnNode insn : insnByOffset) { if (insn != null) { @@ -113,6 +114,11 @@ public class MethodNode extends LineAttrNode implements ILoadable { } } } catch (Exception e) { + if (!noCode) { + noCode = true; + // load without code + load(); + } throw new DecodeException(this, "Load method exception", e); } } 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 ded1a1bd6..6bbce0d4c 100644 --- a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java @@ -34,7 +34,9 @@ public class BlockUtils { if (list.size() > 2) { list = cleanBlockList(list); } - assert list.size() == 2 : "too many nodes for selectOther: " + node + " in " + list; + if (list.size() != 2) { + throw new JadxRuntimeException("Incorrect nodes count for selectOther: " + node + " in " + list); + } BlockNode first = list.get(0); if (first != node) { return first; diff --git a/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java b/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java index 4b15bbeaa..671bb4d97 100644 --- a/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java +++ b/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java @@ -66,9 +66,9 @@ public class ErrorsCounter { if (getErrorCount() > 0) { LOG.error(getErrorCount() + " errors occured in following nodes:"); for (Object node : ERROR_NODES) { - LOG.error(" " + node.getClass().getSimpleName() + ": " + node); + String nodeName = node.getClass().getSimpleName().replace("Node", ""); + LOG.error(" " + nodeName + ": " + node); } - // LOG.error("You can run jadx with '-f' option to view low level instructions"); } }