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 oldArg = parent.getArg(i);
|
||||
if (arg.getType() == ArgType.UNKNOWN) {
|
||||
@@ -141,6 +142,8 @@ public abstract class InsnArg extends Typed {
|
||||
InsnRemover.unbindArgUsage(mth, oldArg);
|
||||
if (unbind) {
|
||||
InsnRemover.unbindArgUsage(mth, this);
|
||||
}
|
||||
if (resArg != null && !insn.contains(AFlag.FORCE_ASSIGN_INLINE)) {
|
||||
// result not needed in wrapped insn
|
||||
InsnRemover.unbindResult(mth, insn);
|
||||
insn.setResult(null);
|
||||
@@ -323,9 +326,7 @@ public abstract class InsnArg extends Typed {
|
||||
return copy;
|
||||
}
|
||||
|
||||
public InsnArg duplicate() {
|
||||
return this;
|
||||
}
|
||||
public abstract InsnArg duplicate();
|
||||
|
||||
public String toShortString() {
|
||||
return this.toString();
|
||||
|
||||
@@ -41,7 +41,14 @@ public final class InsnWrapArg extends InsnArg {
|
||||
|
||||
@Override
|
||||
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);
|
||||
return copyCommonParams(copy);
|
||||
}
|
||||
|
||||
@@ -114,8 +114,7 @@ public class SimplifyVisitor extends AbstractVisitor {
|
||||
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
|
||||
InsnNode replaceInsn = simplifyInsn(mth, wrapInsn, insn);
|
||||
if (replaceInsn != null) {
|
||||
arg.wrapInstruction(mth, replaceInsn, false);
|
||||
InsnRemover.unbindInsn(mth, wrapInsn);
|
||||
arg.wrapInstruction(mth, replaceInsn);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,8 +200,7 @@ public class CodeShrinkVisitor extends AbstractVisitor {
|
||||
if (!InsnRemover.removeWithoutUnbind(mth, assignBlock, assignInsn)) {
|
||||
return false;
|
||||
}
|
||||
InsnArg replaceArg = InsnArg.wrapInsnIntoArg(assignInsn);
|
||||
useInsn.replaceArg(useArg, replaceArg);
|
||||
useArg.wrapInstruction(mth, assignInsn);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@ public class DebugChecks {
|
||||
&& !mth.contains(AFlag.DONT_GENERATE)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class InsnRemover {
|
||||
}
|
||||
// check if all usage only in not generated instructions
|
||||
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()) {
|
||||
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