fix: remove result in wrapped insntructions (#2835)
This commit is contained in:
@@ -131,6 +131,7 @@ public abstract class InsnArg extends Typed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RegisterArg resArg = insn.getResult();
|
||||||
InsnArg arg = wrapInsnIntoArg(insn);
|
InsnArg arg = wrapInsnIntoArg(insn);
|
||||||
InsnArg oldArg = parent.getArg(i);
|
InsnArg oldArg = parent.getArg(i);
|
||||||
if (arg.getType() == ArgType.UNKNOWN) {
|
if (arg.getType() == ArgType.UNKNOWN) {
|
||||||
@@ -141,6 +142,8 @@ public abstract class InsnArg extends Typed {
|
|||||||
InsnRemover.unbindArgUsage(mth, oldArg);
|
InsnRemover.unbindArgUsage(mth, oldArg);
|
||||||
if (unbind) {
|
if (unbind) {
|
||||||
InsnRemover.unbindArgUsage(mth, this);
|
InsnRemover.unbindArgUsage(mth, this);
|
||||||
|
}
|
||||||
|
if (resArg != null && !insn.contains(AFlag.FORCE_ASSIGN_INLINE)) {
|
||||||
// result not needed in wrapped insn
|
// result not needed in wrapped insn
|
||||||
InsnRemover.unbindResult(mth, insn);
|
InsnRemover.unbindResult(mth, insn);
|
||||||
insn.setResult(null);
|
insn.setResult(null);
|
||||||
@@ -323,9 +326,7 @@ public abstract class InsnArg extends Typed {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsnArg duplicate() {
|
public abstract InsnArg duplicate();
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return this.toString();
|
return this.toString();
|
||||||
|
|||||||
@@ -41,7 +41,14 @@ public final class InsnWrapArg extends InsnArg {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InsnArg duplicate() {
|
public InsnArg duplicate() {
|
||||||
InsnWrapArg copy = new InsnWrapArg(wrappedInsn.copyWithoutResult());
|
InsnNode wrapInsn = wrappedInsn;
|
||||||
|
InsnNode wrapInsnCopy = wrapInsn.copyWithoutResult();
|
||||||
|
if (wrapInsn.getResult() != null && wrapInsn.contains(AFlag.FORCE_ASSIGN_INLINE)) {
|
||||||
|
// keep same SSA var in result arg, this will break previous version, mark it for removal
|
||||||
|
wrapInsnCopy.setResult(wrapInsn.getResult().duplicate());
|
||||||
|
wrapInsn.add(AFlag.DONT_GENERATE);
|
||||||
|
}
|
||||||
|
InsnWrapArg copy = new InsnWrapArg(wrapInsnCopy);
|
||||||
copy.setType(type);
|
copy.setType(type);
|
||||||
return copyCommonParams(copy);
|
return copyCommonParams(copy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ public class SimplifyVisitor extends AbstractVisitor {
|
|||||||
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
|
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
|
||||||
InsnNode replaceInsn = simplifyInsn(mth, wrapInsn, insn);
|
InsnNode replaceInsn = simplifyInsn(mth, wrapInsn, insn);
|
||||||
if (replaceInsn != null) {
|
if (replaceInsn != null) {
|
||||||
arg.wrapInstruction(mth, replaceInsn, false);
|
arg.wrapInstruction(mth, replaceInsn);
|
||||||
InsnRemover.unbindInsn(mth, wrapInsn);
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,8 +200,7 @@ public class CodeShrinkVisitor extends AbstractVisitor {
|
|||||||
if (!InsnRemover.removeWithoutUnbind(mth, assignBlock, assignInsn)) {
|
if (!InsnRemover.removeWithoutUnbind(mth, assignBlock, assignInsn)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
InsnArg replaceArg = InsnArg.wrapInsnIntoArg(assignInsn);
|
useArg.wrapInstruction(mth, assignInsn);
|
||||||
useInsn.replaceArg(useArg, replaceArg);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ public class DebugChecks {
|
|||||||
&& !mth.contains(AFlag.DONT_GENERATE)) {
|
&& !mth.contains(AFlag.DONT_GENERATE)) {
|
||||||
throw new JadxRuntimeException("Not generated wrapped insn: \n " + wrapInsn + ",\nouter insn:\n " + insn);
|
throw new JadxRuntimeException("Not generated wrapped insn: \n " + wrapInsn + ",\nouter insn:\n " + insn);
|
||||||
}
|
}
|
||||||
|
if (wrapInsn.getResult() != null && !wrapInsn.contains(AFlag.FORCE_ASSIGN_INLINE)) {
|
||||||
|
throw new JadxRuntimeException("Wrapped insn result should be removed: \n " + wrapInsn + ",\nouter insn:\n " + insn);
|
||||||
|
}
|
||||||
checkInsn(mth, block, wrapInsn);
|
checkInsn(mth, block, wrapInsn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public class InsnRemover {
|
|||||||
}
|
}
|
||||||
// check if all usage only in not generated instructions
|
// check if all usage only in not generated instructions
|
||||||
if (allMatch(ssaVar.getUseList(),
|
if (allMatch(ssaVar.getUseList(),
|
||||||
arg -> arg.contains(AFlag.DONT_GENERATE) || (InsnUtils.contains(arg.getParentInsn(), AFlag.DONT_GENERATE)))) {
|
arg -> arg.contains(AFlag.DONT_GENERATE) || InsnUtils.contains(arg.getParentInsn(), AFlag.DONT_GENERATE))) {
|
||||||
for (RegisterArg arg : ssaVar.getUseList()) {
|
for (RegisterArg arg : ssaVar.getUseList()) {
|
||||||
arg.resetSSAVar();
|
arg.resetSSAVar();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package jadx.tests.integration.variables;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jadx.tests.api.SmaliTest;
|
||||||
|
|
||||||
|
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||||
|
|
||||||
|
public class TestVariables8 extends SmaliTest {
|
||||||
|
@Test
|
||||||
|
public void testNoDebug() {
|
||||||
|
getArgs().setDebugInfo(false);
|
||||||
|
assertThat(getClassNodeFromSmali())
|
||||||
|
.code()
|
||||||
|
.doesNotContain("r0");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
.class Lvariables/TestVariables8;
|
||||||
|
.super Ljava/lang/Object;
|
||||||
|
|
||||||
|
.method private static test(III)J
|
||||||
|
.registers 13
|
||||||
|
.param p0, "k" # I
|
||||||
|
.param p1, "j" # I
|
||||||
|
.param p2, "i" # I
|
||||||
|
|
||||||
|
.prologue
|
||||||
|
const-wide/16 v4, -0x1
|
||||||
|
const/4 v8, 0x1
|
||||||
|
|
||||||
|
.line 614
|
||||||
|
shl-int/lit8 v6, p0, 0x6
|
||||||
|
xor-int/lit8 v7, p1, -0x1
|
||||||
|
and-int/lit8 v7, v7, 0x3f
|
||||||
|
or-int v0, v6, v7
|
||||||
|
|
||||||
|
.local v0, "e":I
|
||||||
|
const/4 v1, 0x6
|
||||||
|
|
||||||
|
.line 616
|
||||||
|
.local v1, "l":I
|
||||||
|
:goto_c
|
||||||
|
if-ltz v1, :cond_13
|
||||||
|
|
||||||
|
shl-int v6, v8, v1
|
||||||
|
and-int/2addr v6, v0
|
||||||
|
|
||||||
|
if-eqz v6, :cond_16
|
||||||
|
|
||||||
|
.line 619
|
||||||
|
:cond_13
|
||||||
|
if-ge v1, v8, :cond_19
|
||||||
|
|
||||||
|
.line 633
|
||||||
|
:cond_15
|
||||||
|
return-wide v4
|
||||||
|
|
||||||
|
.line 617
|
||||||
|
:cond_16
|
||||||
|
add-int/lit8 v1, v1, -0x1
|
||||||
|
goto :goto_c
|
||||||
|
|
||||||
|
.line 620
|
||||||
|
:cond_19
|
||||||
|
shl-int v0, v8, v1
|
||||||
|
.line 621
|
||||||
|
add-int/lit8 v1, v0, -0x1
|
||||||
|
.line 622
|
||||||
|
and-int/2addr p1, v1
|
||||||
|
.line 623
|
||||||
|
if-eq p1, v1, :cond_15
|
||||||
|
|
||||||
|
.line 624
|
||||||
|
and-int/2addr p2, v1
|
||||||
|
.line 625
|
||||||
|
add-int/lit8 v6, p1, 0x1
|
||||||
|
rsub-int/lit8 v6, v6, 0x40
|
||||||
|
ushr-long v2, v4, v6
|
||||||
|
|
||||||
|
.line 626
|
||||||
|
.local v2, "m":J
|
||||||
|
ushr-long v6, v2, p2
|
||||||
|
sub-int v8, v0, p2
|
||||||
|
shl-long v8, v2, v8
|
||||||
|
or-long v2, v6, v8
|
||||||
|
|
||||||
|
.line 627
|
||||||
|
move-wide v4, v2
|
||||||
|
.line 628
|
||||||
|
.local v4, "r":J
|
||||||
|
move p2, v0
|
||||||
|
.line 629
|
||||||
|
:goto_31
|
||||||
|
const/16 v6, 0x40
|
||||||
|
if-ge p2, v6, :cond_15
|
||||||
|
|
||||||
|
.line 630
|
||||||
|
shl-long v6, v2, p2
|
||||||
|
or-long/2addr v4, v6
|
||||||
|
.line 631
|
||||||
|
add-int/2addr p2, v0
|
||||||
|
goto :goto_31
|
||||||
|
.end method
|
||||||
Reference in New Issue
Block a user