use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.
the class ReSugarCode method processNewArray.
/**
* Replace new array and sequence of array-put to new filled-array instruction.
*/
private static InsnNode processNewArray(MethodNode mth, List<InsnNode> instructions, int i, InstructionRemover remover) {
NewArrayNode newArrayInsn = (NewArrayNode) instructions.get(i);
InsnArg arg = newArrayInsn.getArg(0);
if (!arg.isLiteral()) {
return null;
}
int len = (int) ((LiteralArg) arg).getLiteral();
int size = instructions.size();
if (len <= 0 || i + len >= size || instructions.get(i + len).getType() != InsnType.APUT) {
return null;
}
ArgType arrType = newArrayInsn.getArrayType();
InsnNode filledArr = new FilledNewArrayNode(arrType.getArrayElement(), len);
filledArr.setResult(newArrayInsn.getResult());
for (int j = 0; j < len; j++) {
InsnNode put = instructions.get(i + 1 + j);
if (put.getType() != InsnType.APUT) {
LOG.debug("Not a APUT in expected new filled array: {}, method: {}", put, mth);
return null;
}
filledArr.addArg(put.getArg(2));
remover.add(put);
}
return filledArr;
}
use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.
the class ModVisitor method makeFilledArrayInsn.
private static InsnNode makeFilledArrayInsn(MethodNode mth, NewArrayNode newArrayNode, FillArrayInsn insn) {
ArgType insnArrayType = newArrayNode.getArrayType();
ArgType insnElementType = insnArrayType.getArrayElement();
ArgType elType = insn.getElementType();
if (!elType.isTypeKnown() && insnElementType.isPrimitive() && elType.contains(insnElementType.getPrimitiveType())) {
elType = insnElementType;
}
if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
mth.addWarn("Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset()) + ", element type: " + elType + ", insn element type: " + insnElementType);
}
if (!elType.isTypeKnown()) {
LOG.warn("Unknown array element type: {} in mth: {}", elType, mth);
elType = insnElementType.isTypeKnown() ? insnElementType : elType.selectFirst();
if (elType == null) {
throw new JadxRuntimeException("Null array element type");
}
}
List<LiteralArg> list = insn.getLiteralArgs(elType);
InsnNode filledArr = new FilledNewArrayNode(elType, list.size());
filledArr.setResult(newArrayNode.getResult());
for (LiteralArg arg : list) {
FieldNode f = mth.getParentClass().getConstFieldByLiteralArg(arg);
if (f != null) {
InsnNode fGet = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
filledArr.addArg(InsnArg.wrapArg(fGet));
f.addUseIn(mth);
} else {
filledArr.addArg(arg);
}
}
return filledArr;
}
use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.
the class ModVisitor method makeFilledArrayInsn.
private static InsnNode makeFilledArrayInsn(MethodNode mth, FillArrayNode insn) {
ArgType insnArrayType = insn.getResult().getType();
ArgType insnElementType = insnArrayType.getArrayElement();
ArgType elType = insn.getElementType();
if (!elType.isTypeKnown() && insnElementType.isPrimitive()) {
if (elType.contains(insnElementType.getPrimitiveType())) {
elType = insnElementType;
}
}
if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
ErrorsCounter.methodError(mth, "Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset()) + ", element type: " + elType + ", insn element type: " + insnElementType);
}
if (!elType.isTypeKnown()) {
LOG.warn("Unknown array element type: {} in mth: {}", elType, mth);
elType = insnElementType.isTypeKnown() ? insnElementType : elType.selectFirst();
if (elType == null) {
throw new JadxRuntimeException("Null array element type");
}
}
insn.mergeElementType(mth.dex(), elType);
elType = insn.getElementType();
List<LiteralArg> list = insn.getLiteralArgs();
InsnNode filledArr = new FilledNewArrayNode(elType, list.size());
filledArr.setResult(insn.getResult());
for (LiteralArg arg : list) {
FieldNode f = mth.getParentClass().getConstFieldByLiteralArg(arg);
if (f != null) {
InsnNode fGet = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
filledArr.addArg(InsnArg.wrapArg(fGet));
} else {
filledArr.addArg(arg);
}
}
return filledArr;
}
use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.
the class SimplifyVisitor method simplifyStringConstructor.
private InsnNode simplifyStringConstructor(MethodNode mth, ConstructorInsn insn) {
if (insn.getCallMth().getDeclClass().getType().equals(ArgType.STRING) && insn.getArgsCount() != 0 && insn.getArg(0).isInsnWrap()) {
InsnNode arrInsn = ((InsnWrapArg) insn.getArg(0)).getWrapInsn();
if (arrInsn.getType() == InsnType.FILLED_NEW_ARRAY && arrInsn.getArgsCount() != 0) {
ArgType elemType = ((FilledNewArrayNode) arrInsn).getElemType();
if (elemType == ArgType.BYTE || elemType == ArgType.CHAR) {
int printable = 0;
byte[] arr = new byte[arrInsn.getArgsCount()];
for (int i = 0; i < arr.length; i++) {
InsnArg arrArg = arrInsn.getArg(i);
if (!arrArg.isLiteral()) {
return null;
}
arr[i] = (byte) ((LiteralArg) arrArg).getLiteral();
if (NameMapper.isPrintableChar((char) arr[i])) {
printable++;
}
}
if (printable >= arr.length - printable) {
InsnNode constStr = new ConstStringNode(new String(arr));
if (insn.getArgsCount() == 1) {
constStr.setResult(insn.getResult());
constStr.copyAttributesFrom(insn);
InsnRemover.unbindArgUsage(mth, insn.getArg(0));
return constStr;
} else {
InvokeNode in = new InvokeNode(stringGetBytesMth, InvokeType.VIRTUAL, 1);
in.addArg(InsnArg.wrapArg(constStr));
InsnArg bytesArg = InsnArg.wrapArg(in);
bytesArg.setType(stringGetBytesMth.getReturnType());
insn.setArg(0, bytesArg);
return null;
}
}
}
}
}
return null;
}
use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.
the class ProcessInstructionsVisitor method initJumps.
private static void initJumps(MethodNode mth, InsnNode[] insnByOffset) {
for (int offset = 0; offset < insnByOffset.length; offset++) {
InsnNode insn = insnByOffset[offset];
if (insn == null) {
continue;
}
switch(insn.getType()) {
case SWITCH:
SwitchInsn sw = (SwitchInsn) insn;
if (sw.needData()) {
attachSwitchData(insnByOffset, offset, sw);
}
int defCaseOffset = sw.getDefaultCaseOffset();
if (defCaseOffset != -1) {
addJump(mth, insnByOffset, offset, defCaseOffset);
}
for (int target : sw.getTargets()) {
addJump(mth, insnByOffset, offset, target);
}
break;
case IF:
int next = getNextInsnOffset(insnByOffset, offset);
if (next != -1) {
addJump(mth, insnByOffset, offset, next);
}
addJump(mth, insnByOffset, offset, ((IfNode) insn).getTarget());
break;
case GOTO:
addJump(mth, insnByOffset, offset, ((GotoNode) insn).getTarget());
break;
case INVOKE:
if (insn.getResult() == null) {
ArgType retType = ((BaseInvokeNode) insn).getCallMth().getReturnType();
mergeMoveResult(insnByOffset, offset, insn, retType);
}
break;
case STR_CONCAT:
// invoke-custom with string concatenation translated directly to STR_CONCAT, merge next move-result
if (insn.getResult() == null) {
mergeMoveResult(insnByOffset, offset, insn, ArgType.STRING);
}
break;
case FILLED_NEW_ARRAY:
ArgType arrType = ((FilledNewArrayNode) insn).getArrayType();
mergeMoveResult(insnByOffset, offset, insn, arrType);
break;
case FILL_ARRAY:
FillArrayInsn fillArrayInsn = (FillArrayInsn) insn;
int target = fillArrayInsn.getTarget();
InsnNode arrDataInsn = getInsnAtOffset(insnByOffset, target);
if (arrDataInsn != null && arrDataInsn.getType() == InsnType.FILL_ARRAY_DATA) {
fillArrayInsn.setArrayData((FillArrayData) arrDataInsn);
removeInsn(insnByOffset, arrDataInsn);
} else {
throw new JadxRuntimeException("Payload for fill-array not found at " + InsnUtils.formatOffset(target));
}
break;
default:
break;
}
}
}
Aggregations