fix(java-input): use correct registers for dup2_x* opcodes
This commit is contained in:
@@ -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
|
||||
+8
-1
@@ -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) {
|
||||
|
||||
+1
-2
@@ -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);
|
||||
|
||||
+40
-15
@@ -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());
|
||||
|
||||
+8
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user