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 9eb457859..5e20b84a5 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 @@ -24,10 +24,6 @@ public class InsnNode extends LineAttrNode { protected int offset; protected int insnHashCode = super.hashCode(); - protected InsnNode(InsnType type) { - this(type, 1); - } - public InsnNode(InsnType type, int argsCount) { this.insnType = type; this.offset = -1; @@ -155,8 +151,10 @@ public class InsnNode extends LineAttrNode { case STR_CONCAT: case MOVE_EXCEPTION: return true; + + default: + return false; } - return false; } @Override diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java b/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java index ba8bd1644..3611aaaff 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java @@ -16,6 +16,11 @@ import jadx.core.utils.exceptions.JadxException; import java.util.Iterator; import java.util.List; +/** + * Prepare instructions for code generation pass, + * most of this modification breaks register dependencies, + * so this pass must be just before CodeGen. + */ public class PrepareForCodeGen extends AbstractVisitor { @Override @@ -26,7 +31,8 @@ public class PrepareForCodeGen extends AbstractVisitor { } for (BlockNode block : blocks) { removeInstructions(block); - removeBrackets(block); + checkInline(block); + removeParenthesis(block); modifyArith(block); } } @@ -52,12 +58,31 @@ public class PrepareForCodeGen extends AbstractVisitor { } } - private static void removeBrackets(BlockNode block) { + private static void checkInline(BlockNode block) { + List list = block.getInstructions(); + for (int i = 0; i < list.size(); i++) { + InsnNode insn = list.get(i); + // replace 'move' with inner wrapped instruction + if (insn.getType() == InsnType.MOVE + && insn.getArg(0).isInsnWrap() + && !insn.getAttributes().contains(AttributeFlag.DECLARE_VAR)) { + InsnNode wrapInsn = ((InsnWrapArg)insn.getArg(0)).getWrapInsn(); + wrapInsn.setResult(insn.getResult()); + list.set(i, wrapInsn); + } + } + } + + private static void removeParenthesis(BlockNode block) { for (InsnNode insn : block.getInstructions()) { checkInsn(insn); } } + /** + * Remove parenthesis for wrapped insn in arith '+' or '-' + * ('(a + b) +c' => 'a + b + c') + */ private static void checkInsn(InsnNode insn) { if (insn.getType() == InsnType.ARITH) { ArithNode arith = (ArithNode) insn; @@ -82,6 +107,10 @@ public class PrepareForCodeGen extends AbstractVisitor { } } + /** + * Replace arithmetic operation with short form + * ('a = a + 2' => 'a += 2') + */ private static void modifyArith(BlockNode block) { List list = block.getInstructions(); for (int i = 0; i < list.size(); i++) { diff --git a/jadx-core/src/test/java/jadx/tests/internal/TestArgInline.java b/jadx-core/src/test/java/jadx/tests/internal/TestArgInline.java index 6e1ef4920..9e077c191 100644 --- a/jadx-core/src/test/java/jadx/tests/internal/TestArgInline.java +++ b/jadx-core/src/test/java/jadx/tests/internal/TestArgInline.java @@ -3,6 +3,8 @@ package jadx.tests.internal; import jadx.api.InternalJadxTest; import jadx.core.dex.nodes.ClassNode; +import org.junit.Test; + import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; @@ -19,12 +21,13 @@ public class TestArgInline extends InternalJadxTest { } } - //@Test + @Test public void test() { ClassNode cls = getClassNode(TestCls.class); String code = cls.getCode().toString(); System.out.println(code); - assertThat(code, not(containsString("a = a + 1;"))); + assertThat(code, containsString("a++;")); + assertThat(code, not(containsString("a = a + 1;"))); } }