fix(java-input): use correct registers for dup2_x* opcodes

This commit is contained in:
Skylot
2024-01-15 18:33:51 +00:00
parent 2805770510
commit fdc3fe1a8d
6 changed files with 98 additions and 18 deletions
@@ -0,0 +1,17 @@
package jadx.tests.integration.others;
import org.junit.jupiter.api.Test;
import jadx.tests.api.RaungTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestJavaDup2x2 extends RaungTest {
@Test
public void test() {
assertThat(getClassNodeFromRaung())
.code()
.containsOne("dArr[0] = 127.5d;");
}
}
@@ -0,0 +1,24 @@
.version 45.3
.class others/TestJavaDup2x2
.auto frames
.method public static test([D)V
aload 0
iconst_0
aload 0
iconst_1
aload 0
iconst_2
aload 0
iconst_3
ldc2_w 127.5
dup2_x2
dastore
dup2_x2
dastore
dup2_x2
dastore
dastore
return
.end method
@@ -9,6 +9,7 @@ import jadx.plugins.input.java.data.DataReader;
import jadx.plugins.input.java.data.JavaClassData;
import jadx.plugins.input.java.data.code.StackState.SVType;
@SuppressWarnings("UnusedReturnValue")
public class CodeDecodeState {
private final JavaClassData clsData;
private final DataReader reader;
@@ -35,6 +36,7 @@ public class CodeDecodeState {
this.stack = stackState;
}
if (excHandlers.contains(offset)) {
clear();
stack.push(SVType.NARROW); // push exception
excHandler = true;
} else {
@@ -112,6 +114,10 @@ public class CodeDecodeState {
return this;
}
public int insert(int pos, SVType type) {
return stack.insert(pos, type);
}
public void discard() {
stack.pop();
}
@@ -124,8 +130,9 @@ public class CodeDecodeState {
}
}
public void clear() {
public CodeDecodeState clear() {
stack.clear();
return this;
}
public int push(String type) {
@@ -70,12 +70,11 @@ public class JavaCodeReader implements ICodeReader {
if (insnInfo == null) {
throw new JavaClassParseException("Unknown opcode: 0x" + Integer.toHexString(opcode));
}
insn.setInsnInfo(insnInfo);
insn.setOpcodeUnit(opcode);
insn.setInsnInfo(insnInfo);
insn.setRegsCount(insnInfo.getRegsCount());
insn.setOpcode(insnInfo.getApiOpcode());
insn.setPayloadSize(insnInfo.getPayloadSize());
insn.setOpcodeUnit(opcode);
insn.setPayload(null);
state.onInsn(offset);
@@ -158,21 +158,8 @@ public class JavaInsnsRegister {
s.peek(1).push(0, s.peekType(1));
}
});
register(arr, 0x5d, "dup2_x1", 0, 10, Opcode.MOVE_MULTI,
s -> {
if (s.peekType(0) == NARROW) {
s.push(0, NARROW).peekFrom(2, 1)
.push(2, NARROW).peekFrom(2, 3)
.peekFrom(2, 4).peekFrom(4, 5)
.peekFrom(3, 6).peekFrom(0, 7)
.peekFrom(4, 8).peekFrom(1, 9);
} else {
s.insn().setRegsCount(6);
s.push(0, WIDE).peekFrom(1, 1)
.peekFrom(1, 2).peekFrom(2, 3)
.peekFrom(2, 4).peekFrom(0, 5);
}
});
register(arr, 0x5d, "dup2_x1", 0, 10, Opcode.MOVE_MULTI, JavaInsnsRegister::dup2x1);
register(arr, 0x5e, "dup2_x2", 0, 12, Opcode.MOVE_MULTI, JavaInsnsRegister::dup2x2);
register(arr, 0x5f, "swap", 0, 6, Opcode.MOVE_MULTI,
s -> s.peekFrom(-1, 0).peekFrom(1, 1)
.peekFrom(1, 2).peekFrom(0, 3)
@@ -309,6 +296,44 @@ public class JavaInsnsRegister {
register(arr, 0xc8, "goto_w", 4, 0, Opcode.GOTO, s -> s.jump(s.reader().readS4()));
}
private static void dup2x1(CodeDecodeState s) {
if (s.peekType(0) == NARROW) {
s.insert(2, NARROW);
s.insert(2, NARROW);
s.peekFrom(0, 0).peekFrom(2, 1);
s.peekFrom(1, 2).peekFrom(3, 3);
s.peekFrom(2, 4).peekFrom(4, 5);
s.peekFrom(3, 6).peekFrom(0, 7);
s.peekFrom(4, 8).peekFrom(1, 9);
} else {
s.insn().setRegsCount(6);
s.insert(2, WIDE);
s.peekFrom(0, 0).peekFrom(1, 1);
s.peekFrom(1, 2).peekFrom(2, 3);
s.peekFrom(2, 4).peekFrom(0, 5);
}
}
private static void dup2x2(CodeDecodeState s) {
if (s.peekType(0) == NARROW) {
s.insert(2, NARROW);
s.insert(2, NARROW);
s.peekFrom(0, 0).peekFrom(2, 1);
s.peekFrom(1, 2).peekFrom(3, 3);
s.peekFrom(2, 4).peekFrom(4, 5);
s.peekFrom(3, 6).peekFrom(5, 7);
s.peekFrom(4, 8).peekFrom(0, 9);
s.peekFrom(5, 10).peekFrom(1, 11);
} else {
s.insn().setRegsCount(8);
s.insert(2, WIDE);
s.peekFrom(0, 0).peekFrom(1, 1);
s.peekFrom(1, 2).peekFrom(2, 3);
s.peekFrom(2, 4).peekFrom(3, 5);
s.peekFrom(3, 6).peekFrom(0, 7);
}
}
private static IJavaInsnDecoder newArrayMulti() {
return s -> {
s.idx(s.u2());
@@ -44,6 +44,14 @@ public class StackState {
return SVType.NARROW;
}
public int insert(int at, SVType type) {
int p = pos - at;
System.arraycopy(stack, p, stack, p + 1, at);
stack[p] = type;
pos++;
return p;
}
public int push(SVType type) {
int p = ++pos;
if (checkStackIndex(p)) {