InvokeMethodsTest passing

This commit is contained in:
caheckman 2020-07-29 14:02:36 -04:00
parent f4d25ccebb
commit 2d690404fe
2 changed files with 125 additions and 83 deletions

View file

@ -34,16 +34,16 @@ public class LdcMethods {
}
/**
* Generates a String of pcode modeling an ldc, ldc_w, or ldc2_w bytecode ops, which refer to constants
* Generates pcode modeling an ldc, ldc_w, or ldc2_w bytecode ops, which refer to constants
* in the constant pool.
*
*
* @param pCode is the pcode accumulator
* @param constantPoolIndex - the index of item in the constant pool.
* @param constantPool - the constant pool
* @return - String of pcode.
*/
public static String getPcodeForLdc(int constantPoolIndex, AbstractConstantPoolInfoJava[] constantPool){
public static void getPcodeForLdc(PcodeOpEmitter pCode, int constantPoolIndex,
AbstractConstantPoolInfoJava[] constantPool) {
byte tag = constantPool[constantPoolIndex].getTag();
StringBuilder pCode = new StringBuilder();
switch (tag){
case ConstantPoolTagsJava.CONSTANT_Class:
case ConstantPoolTagsJava.CONSTANT_Float:
@ -51,18 +51,19 @@ public class LdcMethods {
case ConstantPoolTagsJava.CONSTANT_MethodHandle:
case ConstantPoolTagsJava.CONSTANT_MethodType:
case ConstantPoolTagsJava.CONSTANT_String:
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(pCode, VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", Integer.toString(constantPoolIndex),ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(pCode,VALUE);
pCode.emitAssignVarnodeFromPcodeOpCall(VALUE, 4, ConstantPoolJava.CPOOL_OP, "0",
Integer.toString(constantPoolIndex), ConstantPoolJava.CPOOL_LDC);
pCode.emitPushCat1Value(VALUE);
break;
case ConstantPoolTagsJava.CONSTANT_Double:
case ConstantPoolTagsJava.CONSTANT_Long:
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(pCode, VALUE, 8, ConstantPoolJava.CPOOL_OP, "0", Integer.toString(constantPoolIndex),ConstantPoolJava.CPOOL_LDC2_W);
PcodeTextEmitter.emitPushCat2Value(pCode,VALUE);
pCode.emitAssignVarnodeFromPcodeOpCall(VALUE, 8, ConstantPoolJava.CPOOL_OP, "0",
Integer.toString(constantPoolIndex), ConstantPoolJava.CPOOL_LDC2_W);
pCode.emitPushCat2Value(VALUE);
break;
default:
throw new IllegalArgumentException("Invalid load from constant pool: tag " + tag);
}
return pCode.toString();
}
}

View file

@ -19,9 +19,15 @@ import static org.junit.Assert.*;
import java.io.IOException;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.javaclass.format.constantpool.AbstractConstantPoolInfoJava;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.LanguageID;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
/**
*
@ -39,9 +45,18 @@ import ghidra.javaclass.format.constantpool.AbstractConstantPoolInfoJava;
*/
public class LdcMethodsTest {
public class LdcMethodsTest extends AbstractGhidraHeadlessIntegrationTest {
private static final int COUNT_LOW_BYTE = 9;
private SleighLanguage language;
private Address opAddress;
@Before
public void setUp() throws Exception {
language =
(SleighLanguage) getLanguageService().getLanguage(new LanguageID("JVM:BE:32:default"));
opAddress = language.getAddressFactory().getDefaultAddressSpace().getAddress(0x10000);
}
@Test
public void testLdcInteger() throws IOException{
@ -52,22 +67,26 @@ public class LdcMethodsTest {
TestClassFileCreator.appendInteger(classFile, 0x12345678);
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0","1", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append an additional integer to the end of the constant pool and generate a reference to it
classFile.set(COUNT_LOW_BYTE, (byte) 3);
TestClassFileCreator.appendInteger(classFile, 0x11111111);
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(2, constantPool);
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0","2", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 2, constantPool);
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "2", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}
@Test
@ -80,12 +99,14 @@ public class LdcMethodsTest {
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
//+1 to skip over the tag
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append an additional float to the end of the constant pool and generate a reference to it
classFile.set(COUNT_LOW_BYTE, (byte) 3);
@ -93,12 +114,14 @@ public class LdcMethodsTest {
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(2, constantPool);
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 2, constantPool);
//+1 for tag of first float, +4 for data of first float, +1 for tag of 2nd float
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "2", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "2", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}
@Test
@ -110,12 +133,14 @@ public class LdcMethodsTest {
TestClassFileCreator.appendDouble(classFile, 2.0);
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
//+1 to skip over the tag
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 8, ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC2_W);
PcodeTextEmitter.emitPushCat2Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 8,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC2_W);
expectedPcode.emitPushCat2Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append an additional double to the end of the constant pool and generate a reference to it
//doubles count as two elements in the constant pool!
@ -123,11 +148,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendDouble(classFile, 4.0);
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(3, constantPool);
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 8, ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC2_W);
PcodeTextEmitter.emitPushCat2Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 3, constantPool);
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 8,
ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC2_W);
expectedPcode.emitPushCat2Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}
@Test
@ -139,11 +166,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendLong(classFile, 0x123456789l);
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 8, ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC2_W);
PcodeTextEmitter.emitPushCat2Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 8,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC2_W);
expectedPcode.emitPushCat2Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append an additional long to the end of the constant pool and generate a reference to it
//longs count as two elements in the constant pool!
@ -151,11 +180,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendLong(classFile, 0x1111111111l);
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(3, constantPool);
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 8, ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC2_W);
PcodeTextEmitter.emitPushCat2Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 3, constantPool);
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 8,
ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC2_W);
expectedPcode.emitPushCat2Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}
@Test
@ -168,11 +199,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendUtf8(classFile, "input1");
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append additional string, utf8 element to the end of the constant pool and generate a reference
//character string
@ -181,11 +214,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendUtf8(classFile, "input2");
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(3, constantPool);
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 3, constantPool);
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}
@Test
@ -198,12 +233,14 @@ public class LdcMethodsTest {
TestClassFileCreator.appendUtf8(classFile, "Ljava/lang/Integer;");
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append additional class, utf8 element to the end of the constant pool and generate a reference
//character string
@ -212,13 +249,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendUtf8(classFile, "Ljava/lang/String;");
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(3, constantPool);
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 3, constantPool);
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}
@Test
@ -231,15 +268,17 @@ public class LdcMethodsTest {
TestClassFileCreator.appendUtf8(classFile, "(I)Ljava/lang/Integer;");
byte[] classFileBytes = TestClassFileCreator.getByteArray(classFile);
AbstractConstantPoolInfoJava[] constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
String pCode = LdcMethods.getPcodeForLdc(1, constantPool);
PcodeOpEmitter pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 1, constantPool);
//+1 to skip over the tag of the MethodType element
//+2 to skip over data of MethodType element (2-byte ref to utf8 element)
//+1 to skip over tag of utf8 element
//+2 to skip over length of utf8 element
StringBuilder expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
PcodeOpEmitter expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "1", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
//append additional MethodType, utf8 element to the end of the constant pool and generate a reference
//character string
@ -248,11 +287,13 @@ public class LdcMethodsTest {
TestClassFileCreator.appendUtf8(classFile, "(I)Ljava/lang/Integer;");
classFileBytes = TestClassFileCreator.getByteArray(classFile);
constantPool = TestClassFileCreator.getConstantPoolFromBytes(classFileBytes);
pCode = LdcMethods.getPcodeForLdc(3, constantPool);
expectedPcode = new StringBuilder();
PcodeTextEmitter.emitAssignVarnodeFromPcodeOpCall(expectedPcode, LdcMethods.VALUE, 4, ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC);
PcodeTextEmitter.emitPushCat1Value(expectedPcode, LdcMethods.VALUE);
assertTrue(pCode.equals(expectedPcode.toString()));
pCode = new PcodeOpEmitter(language, opAddress);
LdcMethods.getPcodeForLdc(pCode, 3, constantPool);
expectedPcode = new PcodeOpEmitter(language, opAddress);
expectedPcode.emitAssignVarnodeFromPcodeOpCall(LdcMethods.VALUE, 4,
ConstantPoolJava.CPOOL_OP, "0", "3", ConstantPoolJava.CPOOL_LDC);
expectedPcode.emitPushCat1Value(LdcMethods.VALUE);
assertEquals(pCode, expectedPcode);
}