Skip to content

Commit

Permalink
fix(java-input): use correct registers for dup2_x* opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Jan 15, 2024
1 parent 2805770 commit fdc3fe1
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -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;");
}
}
24 changes: 24 additions & 0 deletions jadx-core/src/test/raung/others/TestJavaDup2x2.raung
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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;
Expand All @@ -35,6 +36,7 @@ public void onInsn(int offset) {
this.stack = stackState;
}
if (excHandlers.contains(offset)) {
clear();
stack.push(SVType.NARROW); // push exception
excHandler = true;
} else {
Expand Down Expand Up @@ -112,6 +114,10 @@ public CodeDecodeState pushWide(int arg) {
return this;
}

public int insert(int pos, SVType type) {
return stack.insert(pos, type);
}

public void discard() {
stack.pop();
}
Expand All @@ -124,8 +130,9 @@ public void discardWord() {
}
}

public void clear() {
public CodeDecodeState clear() {
stack.clear();
return this;
}

public int push(String type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,11 @@ public void visitInstructions(Consumer<InsnData> insnConsumer) {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public SVType peekTypeAt(int at) {
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)) {
Expand Down

0 comments on commit fdc3fe1

Please sign in to comment.