use of soot.jimple.NumericConstant in project soot by Sable.
the class FillArrayDataInstruction method jimplify.
@Override
public void jimplify(DexBody body) {
if (!(instruction instanceof Instruction31t))
throw new IllegalArgumentException("Expected Instruction31t but got: " + instruction.getClass());
Instruction31t fillArrayInstr = (Instruction31t) instruction;
int destRegister = fillArrayInstr.getRegisterA();
int offset = fillArrayInstr.getCodeOffset();
int targetAddress = codeAddress + offset;
Instruction referenceTable = body.instructionAtAddress(targetAddress).instruction;
if (!(referenceTable instanceof ArrayPayload)) {
throw new RuntimeException("Address " + targetAddress + "refers to an invalid PseudoInstruction.");
}
ArrayPayload arrayTable = (ArrayPayload) referenceTable;
// NopStmt nopStmtBeginning = Jimple.v().newNopStmt();
// body.add(nopStmtBeginning);
Local arrayReference = body.getRegisterLocal(destRegister);
List<Number> elements = arrayTable.getArrayElements();
int numElements = elements.size();
Stmt firstAssign = null;
for (int i = 0; i < numElements; i++) {
ArrayRef arrayRef = Jimple.v().newArrayRef(arrayReference, IntConstant.v(i));
NumericConstant element = getArrayElement(elements.get(i), body, destRegister);
if (// array was not defined -> element type can not be found (obfuscated bytecode?)
element == null)
break;
AssignStmt assign = Jimple.v().newAssignStmt(arrayRef, element);
addTags(assign);
body.add(assign);
if (i == 0) {
firstAssign = assign;
}
}
if (firstAssign == null) {
// if numElements == 0. Is it possible?
firstAssign = Jimple.v().newNopStmt();
body.add(firstAssign);
}
// NopStmt nopStmtEnd = Jimple.v().newNopStmt();
// body.add(nopStmtEnd);
// defineBlock(nopStmtBeginning, nopStmtEnd);
setUnit(firstAssign);
}
use of soot.jimple.NumericConstant in project soot by Sable.
the class FillArrayDataInstruction method getArrayElement.
private NumericConstant getArrayElement(Number element, DexBody body, int arrayRegister) {
List<DexlibAbstractInstruction> instructions = body.instructionsBefore(this);
Set<Integer> usedRegisters = new HashSet<Integer>();
usedRegisters.add(arrayRegister);
Type elementType = null;
Outer: for (DexlibAbstractInstruction i : instructions) {
if (usedRegisters.isEmpty())
break;
for (int reg : usedRegisters) if (i instanceof NewArrayInstruction) {
NewArrayInstruction newArrayInstruction = (NewArrayInstruction) i;
Instruction22c instruction22c = (Instruction22c) newArrayInstruction.instruction;
if (instruction22c.getRegisterA() == reg) {
ArrayType arrayType = (ArrayType) DexType.toSoot((TypeReference) instruction22c.getReference());
elementType = arrayType.getElementType();
break Outer;
}
}
// look for new registers
for (int reg : usedRegisters) {
int newRegister = i.movesToRegister(reg);
if (newRegister != -1) {
usedRegisters.add(newRegister);
usedRegisters.remove(reg);
// there can't be more than one new
break;
}
}
}
if (elementType == null) {
// throw new InternalError("Unable to find array type to type array elements!");
logger.warn("Unable to find array type to type array elements! Array was not defined! (obfuscated bytecode?)");
return null;
}
NumericConstant value;
if (elementType instanceof BooleanType) {
value = IntConstant.v(element.intValue());
IntConstant ic = (IntConstant) value;
if (ic.value != 0) {
value = IntConstant.v(1);
}
} else if (elementType instanceof ByteType) {
value = IntConstant.v(element.byteValue());
} else if (elementType instanceof CharType || elementType instanceof ShortType) {
value = IntConstant.v(element.shortValue());
} else if (elementType instanceof DoubleType) {
value = DoubleConstant.v(Double.longBitsToDouble(element.longValue()));
} else if (elementType instanceof FloatType) {
value = FloatConstant.v(Float.intBitsToFloat(element.intValue()));
} else if (elementType instanceof IntType) {
value = IntConstant.v(element.intValue());
} else if (elementType instanceof LongType) {
value = LongConstant.v(element.longValue());
} else {
throw new RuntimeException("Invalid Array Type occured in FillArrayDataInstruction: " + elementType);
}
return value;
}
Aggregations