diff --git a/jadx-core/build.gradle b/jadx-core/build.gradle index e052606f3aa1bc48b41b5a9bdcaf8ce7cb9ad9a7..f6ccd13894568e21132b601104013fccae7c55ab 100644 --- a/jadx-core/build.gradle +++ b/jadx-core/build.gradle @@ -7,7 +7,6 @@ dependencies { compile 'org.ow2.asm:asm:7.1' compile 'org.jetbrains:annotations:17.0.0' - compile 'uk.com.robust-it:cloning:1.9.12' compile 'com.google.code.gson:gson:2.8.5' compile 'org.smali:baksmali:2.2.7' diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/ArithNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/ArithNode.java index 17277a9af1e4e3e09377f83ec80093d20faeee46..35070e241590ac00f62cc65f67354e198b2f08bb 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/ArithNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/ArithNode.java @@ -71,6 +71,11 @@ public class ArithNode extends InsnNode { return op == other.op; } + @Override + public InsnNode copy() { + return copyCommonParams(new ArithNode(op, getResult(), getArg(0), getArg(1))); + } + @Override public String toString() { return InsnUtils.formatOffset(offset) + ": " diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java index 422a6470025d4e2c9a2a1cd568e44476f0695f7c..3cc11f5662e989a0a23c2577d2bacbd5d4bbbca5 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java @@ -25,13 +25,15 @@ public final class FillArrayNode extends InsnNode { private ArgType elemType; public FillArrayNode(int resReg, FillArrayDataPayloadDecodedInstruction payload) { - super(InsnType.FILL_ARRAY, 1); - ArgType elType = getElementType(payload.getElementWidthUnit()); - addArg(InsnArg.reg(resReg, ArgType.array(elType))); + this(payload.getData(), payload.getSize(), getElementType(payload.getElementWidthUnit())); + addArg(InsnArg.reg(resReg, ArgType.array(elemType))); + } - this.data = payload.getData(); - this.size = payload.getSize(); - this.elemType = elType; + private FillArrayNode(Object data, int size, ArgType elemType) { + super(InsnType.FILL_ARRAY, 1); + this.data = data; + this.size = size; + this.elemType = elemType; } private static ArgType getElementType(short elementWidthUnit) { @@ -98,6 +100,11 @@ public final class FillArrayNode extends InsnNode { return elemType.equals(other.elemType) && data == other.data; } + @Override + public InsnNode copy() { + return copyCommonParams(new FillArrayNode(data, size, elemType)); + } + public String dataToString() { if (data instanceof int[]) { return Arrays.toString((int[]) data); diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java index 95d0e4aec0ba83ce6c833b77f8b5946c68d1df39..7b1288c82990e5b377c645f8da05647eb01e6294 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java @@ -34,6 +34,11 @@ public class FilledNewArrayNode extends InsnNode { return elemType == other.elemType; } + @Override + public InsnNode copy() { + return copyCommonParams(new FilledNewArrayNode(elemType, getArgsCount())); + } + @Override public String toString() { return super.toString() + " elemType: " + elemType; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/GotoNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/GotoNode.java index bddfb062b4502926f200ded29da756dcd530f4fc..f3483f5b059210cfc8e8aa9aedff4848c56a4afb 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/GotoNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/GotoNode.java @@ -1,5 +1,6 @@ package jadx.core.dex.instructions; +import jadx.core.dex.nodes.InsnNode; import jadx.core.utils.InsnUtils; public class GotoNode extends TargetInsnNode { @@ -19,6 +20,11 @@ public class GotoNode extends TargetInsnNode { return target; } + @Override + public InsnNode copy() { + return copyCommonParams(new GotoNode(target)); + } + @Override public String toString() { return super.toString() + "-> " + InsnUtils.formatOffset(target); diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java index 98feb10196adb6f58c536dbd437b93d2bd8c0cfd..d137b913a8ad4cd2933a977a4fed051a5414e383 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java @@ -34,12 +34,16 @@ public class IfNode extends GotoNode { } public IfNode(IfOp op, int targetOffset, InsnArg arg1, InsnArg arg2) { - super(InsnType.IF, targetOffset, 2); - this.op = op; + this(op, targetOffset); addArg(arg1); addArg(arg2); } + private IfNode(IfOp op, int targetOffset) { + super(InsnType.IF, targetOffset, 2); + this.op = op; + } + // change default types priority private static final ArgType WIDE_TYPE = ArgType.unknown( PrimitiveType.INT, PrimitiveType.BOOLEAN, @@ -123,6 +127,14 @@ public class IfNode extends GotoNode { return op == other.op; } + @Override + public InsnNode copy() { + IfNode copy = new IfNode(op, target); + copy.thenBlock = thenBlock; + copy.elseBlock = elseBlock; + return copyCommonParams(copy); + } + @Override public String toString() { return InsnUtils.formatOffset(offset) + ": " diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java index 80364976ee879e614918b519ff3b3992682f4f03..a52cc9aa0af40fd1bdee8873b4e743c688a8fcca 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java @@ -12,12 +12,16 @@ public class NewArrayNode extends InsnNode { private final ArgType arrType; public NewArrayNode(@NotNull ArgType arrType, RegisterArg res, InsnArg size) { - super(InsnType.NEW_ARRAY, 1); - this.arrType = arrType; + this(arrType); setResult(res); addArg(size); } + private NewArrayNode(ArgType arrType) { + super(InsnType.NEW_ARRAY, 1); + this.arrType = arrType; + } + public ArgType getArrayType() { return arrType; } @@ -34,6 +38,11 @@ public class NewArrayNode extends InsnNode { return arrType == other.arrType; } + @Override + public InsnNode copy() { + return copyCommonParams(new NewArrayNode(arrType)); + } + @Override public String toString() { return super.toString() + " type: " + arrType; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java index 36a7f836492422f39bc4491584f54e97bfc7dac3..07ab017d278c18b0e760bf5e4fe40b21bfd0064d 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java @@ -21,13 +21,17 @@ public final class PhiInsn extends InsnNode { private final List blockBinds; public PhiInsn(int regNum, int predecessors) { - super(InsnType.PHI, predecessors); - this.blockBinds = new ArrayList<>(predecessors); + this(predecessors); setResult(InsnArg.reg(regNum, ArgType.UNKNOWN)); add(AFlag.DONT_INLINE); add(AFlag.DONT_GENERATE); } + private PhiInsn(int argsCount) { + super(InsnType.PHI, argsCount); + this.blockBinds = new ArrayList<>(argsCount); + } + public RegisterArg bindArg(BlockNode pred) { RegisterArg arg = InsnArg.reg(getResult().getRegNum(), getResult().getInitType()); bindArg(arg, pred); @@ -111,6 +115,11 @@ public final class PhiInsn extends InsnNode { throw new JadxRuntimeException("Direct setArg is forbidden for PHI insn, bindArg must be used"); } + @Override + public InsnNode copy() { + return copyCommonParams(new PhiInsn(getArgsCount())); + } + @Override public String toString() { return "PHI: " + getResult() + " = " + Utils.listToString(getArguments()) diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java index 9400bbb658fc22c1a8f7d9e8a9a728173372b88c..fc6249d2f02eb5e1db523c116866e1427c0d813e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java @@ -20,11 +20,15 @@ public class SwitchNode extends TargetInsnNode { private BlockNode defTargetBlock; public SwitchNode(InsnArg arg, Object[] keys, int[] targets, int def) { + this(keys, targets, def); + addArg(arg); + } + + private SwitchNode(Object[] keys, int[] targets, int def) { super(InsnType.SWITCH, 1); this.keys = keys; this.targets = targets; this.def = def; - addArg(arg); } public int getCasesCount() { @@ -96,6 +100,14 @@ public class SwitchNode extends TargetInsnNode { && Arrays.equals(targets, other.targets); } + @Override + public InsnNode copy() { + SwitchNode copy = new SwitchNode(keys, targets, def); + copy.targetBlocks = targetBlocks; + copy.defTargetBlock = defTargetBlock; + return copyCommonParams(copy); + } + @Override public String toString() { StringBuilder targ = new StringBuilder(); diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java index 21eb17b976c3db3896e742a6fa57399fe8b56727..cfdfea86f9db68a6e36bdb2191be5b1161d9924a 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java @@ -104,6 +104,11 @@ public class ConstructorInsn extends InsnNode implements CallMthInterface { && callType == other.callType; } + @Override + public InsnNode copy() { + return copyCommonParams(new ConstructorInsn(callMth, callType, instanceArg)); + } + @Override public String toString() { return super.toString() + ' ' + callMth + ' ' + callType; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/mods/TernaryInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/mods/TernaryInsn.java index f1b98ecb816eee6b748d3ff1fbc7699d8fa2edac..4bf55f9427fa4661abc7605b206f027eaeb12c9f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/mods/TernaryInsn.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/mods/TernaryInsn.java @@ -16,7 +16,7 @@ public final class TernaryInsn extends InsnNode { private IfCondition condition; public TernaryInsn(IfCondition condition, RegisterArg result, InsnArg th, InsnArg els) { - super(InsnType.TERNARY, 2); + this(); setResult(result); if (th.equals(LiteralArg.FALSE) && els.equals(LiteralArg.TRUE)) { @@ -31,6 +31,10 @@ public final class TernaryInsn extends InsnNode { } } + private TernaryInsn() { + super(InsnType.TERNARY, 2); + } + public IfCondition getCondition() { return condition; } @@ -67,6 +71,13 @@ public final class TernaryInsn extends InsnNode { return condition.equals(that.condition); } + @Override + public InsnNode copy() { + TernaryInsn copy = new TernaryInsn(); + copy.condition = condition; + return copyCommonParams(copy); + } + @Override public String toString() { return InsnUtils.formatOffset(offset) + ": TERNARY" diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java index 7ee148d3c0688c0c49e1542f2d8c7836d35ab393..d21bc53ae6aed14a9ffc36700cdaef268fd15742 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java @@ -9,7 +9,6 @@ import java.util.Objects; import org.jetbrains.annotations.Nullable; import com.android.dx.io.instructions.DecodedInstruction; -import com.rits.cloning.Cloner; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.nodes.LineAttrNode; @@ -17,23 +16,14 @@ import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnWrapArg; -import jadx.core.dex.instructions.args.LiteralArg; -import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.SSAVar; import jadx.core.utils.InsnRemover; import jadx.core.utils.InsnUtils; import jadx.core.utils.Utils; +import jadx.core.utils.exceptions.JadxRuntimeException; public class InsnNode extends LineAttrNode { - - private static final Cloner INSN_CLONER = new Cloner(); - - static { - INSN_CLONER.dontClone(ArgType.class, SSAVar.class, LiteralArg.class, NamedArg.class); - INSN_CLONER.dontCloneInstanceOf(RegisterArg.class); - } - protected final InsnType insnType; private RegisterArg result; @@ -324,7 +314,7 @@ public class InsnNode extends LineAttrNode { && Objects.equals(arguments, other.arguments); } - protected T copyCommonParams(T copy) { + protected final T copyCommonParams(T copy) { copy.setResult(result); if (copy.getArgsCount() == 0) { for (InsnArg arg : this.getArguments()) { @@ -346,10 +336,10 @@ public class InsnNode extends LineAttrNode { * Make copy of InsnNode object. */ public InsnNode copy() { - if (this.getClass() == InsnNode.class) { - return copyCommonParams(new InsnNode(insnType, getArgsCount())); + if (this.getClass() != InsnNode.class) { + throw new JadxRuntimeException("Copy method not implemented in insn class " + this.getClass().getSimpleName()); } - return INSN_CLONER.deepClone(this); + return copyCommonParams(new InsnNode(insnType, getArgsCount())); } public boolean canThrowException() {