Commit 5c94e0bc authored by Skylot's avatar Skylot

core: improve exceptions handling

parent 18a1788d
...@@ -237,7 +237,7 @@ public class ClassGen { ...@@ -237,7 +237,7 @@ public class ClassGen {
if (badCode) { if (badCode) {
code.startLine("/* JADX WARNING: inconsistent code. */"); code.startLine("/* JADX WARNING: inconsistent code. */");
code.startLine("/* Code decompiled incorrectly, please refer to instructions dump. */"); 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)) { if (mthGen.addDefinition(code)) {
code.add(' '); code.add(' ');
......
...@@ -12,29 +12,46 @@ import jadx.core.dex.nodes.InsnNode; ...@@ -12,29 +12,46 @@ import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.DecodeException;
import java.io.EOFException;
import com.android.dx.io.Code; import com.android.dx.io.Code;
import com.android.dx.io.OpcodeInfo; import com.android.dx.io.OpcodeInfo;
import com.android.dx.io.Opcodes; import com.android.dx.io.Opcodes;
import com.android.dx.io.instructions.DecodedInstruction; import com.android.dx.io.instructions.DecodedInstruction;
import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction; import com.android.dx.io.instructions.FillArrayDataPayloadDecodedInstruction;
import com.android.dx.io.instructions.PackedSwitchPayloadDecodedInstruction; import com.android.dx.io.instructions.PackedSwitchPayloadDecodedInstruction;
import com.android.dx.io.instructions.ShortArrayCodeInput;
import com.android.dx.io.instructions.SparseSwitchPayloadDecodedInstruction; import com.android.dx.io.instructions.SparseSwitchPayloadDecodedInstruction;
public class InsnDecoder { public class InsnDecoder {
private final MethodNode method; private final MethodNode method;
private final DecodedInstruction[] insnArr;
private final DexNode dex; private final DexNode dex;
private DecodedInstruction[] insnArr;
public InsnDecoder(MethodNode mthNode, Code mthCode) { public InsnDecoder(MethodNode mthNode) throws DecodeException {
this.method = mthNode; this.method = mthNode;
this.dex = method.dex(); this.dex = method.dex();
this.insnArr = DecodedInstruction.decodeAll(mthCode.getInstructions());
} }
public InsnNode[] run() throws DecodeException { public void decodeInsns(Code mthCode) throws DecodeException {
InsnNode[] instructions = new InsnNode[insnArr.length]; 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++) { for (int i = 0; i < insnArr.length; i++) {
DecodedInstruction rawInsn = insnArr[i]; DecodedInstruction rawInsn = insnArr[i];
if (rawInsn != null) { if (rawInsn != null) {
...@@ -48,6 +65,7 @@ public class InsnDecoder { ...@@ -48,6 +65,7 @@ public class InsnDecoder {
instructions[i] = null; instructions[i] = null;
} }
} }
insnArr = null;
return instructions; return instructions;
} }
......
...@@ -95,7 +95,7 @@ public class RegisterArg extends InsnArg { ...@@ -95,7 +95,7 @@ public class RegisterArg extends InsnArg {
InsnNode ai = getAssignInsn(); InsnNode ai = getAssignInsn();
if (ai != null && ai.getType() == InsnType.MOVE) { if (ai != null && ai.getType() == InsnType.MOVE) {
InsnArg arg = ai.getArg(0); InsnArg arg = ai.getArg(0);
if (arg != this && arg.isThis()) { if (arg != this && "this".equals(arg.getTypedVar().getName())) {
return true; return true;
} }
} }
......
...@@ -3,6 +3,7 @@ package jadx.core.dex.nodes; ...@@ -3,6 +3,7 @@ package jadx.core.dex.nodes;
import jadx.core.Consts; import jadx.core.Consts;
import jadx.core.codegen.CodeWriter; import jadx.core.codegen.CodeWriter;
import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.JadxErrorAttr;
import jadx.core.dex.attributes.LineAttrNode; import jadx.core.dex.attributes.LineAttrNode;
import jadx.core.dex.attributes.SourceFileAttr; import jadx.core.dex.attributes.SourceFileAttr;
import jadx.core.dex.attributes.annotations.Annotation; import jadx.core.dex.attributes.annotations.Annotation;
...@@ -206,7 +207,12 @@ public class ClassNode extends LineAttrNode implements ILoadable { ...@@ -206,7 +207,12 @@ public class ClassNode extends LineAttrNode implements ILoadable {
@Override @Override
public void load() throws DecodeException { public void load() throws DecodeException {
for (MethodNode mth : getMethods()) { 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()) { for (ClassNode innerCls : getInnerClasses()) {
innerCls.load(); innerCls.load();
......
...@@ -87,8 +87,9 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -87,8 +87,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
regsCount = mthCode.getRegistersSize(); regsCount = mthCode.getRegistersSize();
initMethodTypes(); initMethodTypes();
InsnDecoder decoder = new InsnDecoder(this, mthCode); InsnDecoder decoder = new InsnDecoder(this);
InsnNode[] insnByOffset = decoder.run(); decoder.decodeInsns(mthCode);
InsnNode[] insnByOffset = decoder.process();
instructions = new ArrayList<InsnNode>(); instructions = new ArrayList<InsnNode>();
for (InsnNode insn : insnByOffset) { for (InsnNode insn : insnByOffset) {
if (insn != null) { if (insn != null) {
...@@ -113,6 +114,11 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -113,6 +114,11 @@ public class MethodNode extends LineAttrNode implements ILoadable {
} }
} }
} catch (Exception e) { } catch (Exception e) {
if (!noCode) {
noCode = true;
// load without code
load();
}
throw new DecodeException(this, "Load method exception", e); throw new DecodeException(this, "Load method exception", e);
} }
} }
......
...@@ -34,7 +34,9 @@ public class BlockUtils { ...@@ -34,7 +34,9 @@ public class BlockUtils {
if (list.size() > 2) { if (list.size() > 2) {
list = cleanBlockList(list); 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); BlockNode first = list.get(0);
if (first != node) { if (first != node) {
return first; return first;
......
...@@ -66,9 +66,9 @@ public class ErrorsCounter { ...@@ -66,9 +66,9 @@ public class ErrorsCounter {
if (getErrorCount() > 0) { if (getErrorCount() > 0) {
LOG.error(getErrorCount() + " errors occured in following nodes:"); LOG.error(getErrorCount() + " errors occured in following nodes:");
for (Object node : ERROR_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");
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment