From 69494c92129e9543f9e5e1541828ee1a4a2ae1bd Mon Sep 17 00:00:00 2001 From: Skylot Date: Sat, 27 Jun 2015 18:27:38 +0300 Subject: [PATCH] core: add method for copy instruction nodes --- jadx-core/build.gradle | 1 + .../dex/attributes/nodes/LineAttrNode.java | 5 +++ .../core/dex/instructions/ConstClassNode.java | 5 +++ .../dex/instructions/ConstStringNode.java | 5 +++ .../core/dex/instructions/IndexInsnNode.java | 5 +++ .../core/dex/instructions/InvokeNode.java | 11 ++++++ .../java/jadx/core/dex/nodes/InsnNode.java | 38 +++++++++++++++++++ 7 files changed, 70 insertions(+) diff --git a/jadx-core/build.gradle b/jadx-core/build.gradle index 4fc7d67e6..dfdd2c08f 100644 --- a/jadx-core/build.gradle +++ b/jadx-core/build.gradle @@ -9,6 +9,7 @@ dependencies { compile 'commons-io:commons-io:2.4' compile 'org.ow2.asm:asm:5.0.3' compile 'com.intellij:annotations:12.0' + compile 'uk.com.robust-it:cloning:1.9.2' testCompile 'org.smali:smali:2.0.3' } diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/LineAttrNode.java b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/LineAttrNode.java index a88db0002..ae4adc492 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/LineAttrNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/LineAttrNode.java @@ -23,4 +23,9 @@ public abstract class LineAttrNode extends AttrNode { public void setDecompiledLine(int decompiledLine) { this.decompiledLine = decompiledLine; } + + public void copyLines(LineAttrNode lineAttrNode) { + setSourceLine(lineAttrNode.getSourceLine()); + setDecompiledLine(lineAttrNode.getDecompiledLine()); + } } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassNode.java index b918e5ac6..c6ee7c1e9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassNode.java @@ -16,6 +16,11 @@ public final class ConstClassNode extends InsnNode { return clsType; } + @Override + public InsnNode copy() { + return copyCommonParams(new ConstClassNode(clsType)); + } + @Override public boolean isSame(InsnNode obj) { if (this == obj) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringNode.java index 200534d74..9fd2d9366 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringNode.java @@ -15,6 +15,11 @@ public final class ConstStringNode extends InsnNode { return str; } + @Override + public InsnNode copy() { + return copyCommonParams(new ConstStringNode(str)); + } + @Override public boolean isSame(InsnNode obj) { if (this == obj) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/IndexInsnNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/IndexInsnNode.java index 9c76c4fe4..7bcbbcb2c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/IndexInsnNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/IndexInsnNode.java @@ -16,6 +16,11 @@ public class IndexInsnNode extends InsnNode { return index; } + @Override + public IndexInsnNode copy() { + return copyCommonParams(new IndexInsnNode(insnType, index, getArgsCount())); + } + @Override public boolean isSame(InsnNode obj) { if (this == obj) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java index d05bfaf6a..4d7ce136a 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java @@ -36,6 +36,12 @@ public class InvokeNode extends InsnNode { } } + private InvokeNode(MethodInfo mth, InvokeType invokeType, int argsCount) { + super(InsnType.INVOKE, argsCount); + this.mth = mth; + this.type = invokeType; + } + public InvokeType getInvokeType() { return type; } @@ -44,6 +50,11 @@ public class InvokeNode extends InsnNode { return mth; } + @Override + public InsnNode copy() { + return copyCommonParams(new InvokeNode(mth, type, getArgsCount())); + } + @Override public boolean isSame(InsnNode obj) { if (this == obj) { 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 af4d0752d..46c3f4416 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 @@ -5,7 +5,10 @@ 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.InsnUtils; import jadx.core.utils.Utils; @@ -14,9 +17,17 @@ import java.util.Collections; import java.util.List; import com.android.dx.io.instructions.DecodedInstruction; +import com.rits.cloning.Cloner; 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; @@ -228,4 +239,31 @@ public class InsnNode extends LineAttrNode { && arguments.size() == other.arguments.size(); } + protected T copyCommonParams(T copy) { + copy.setResult(result); + if (copy.getArgsCount() == 0) { + for (InsnArg arg : this.getArguments()) { + if (arg.isInsnWrap()) { + InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn(); + copy.addArg(InsnArg.wrapArg(wrapInsn.copy())); + } else { + copy.addArg(arg); + } + } + } + copy.copyAttributesFrom(this); + copy.copyLines(this); + copy.setOffset(this.getOffset()); + return copy; + } + + /** + * Make copy of InsnNode object. + */ + public InsnNode copy() { + if (this.getClass() == InsnNode.class) { + return copyCommonParams(new InsnNode(insnType, getArgsCount())); + } + return INSN_CLONER.deepClone(this); + } }