use of jadx.core.dex.nodes.InsnNode 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.nodes.InsnNode in project jadx by skylot.
the class BlockProcessor method splitReturn.
/**
* Splice return block if several predecessors presents
*/
private static boolean splitReturn(MethodNode mth) {
if (mth.getExitBlocks().size() != 1) {
return false;
}
BlockNode exitBlock = mth.getExitBlocks().get(0);
if (exitBlock.getInstructions().size() != 1 || exitBlock.contains(AFlag.SYNTHETIC)) {
return false;
}
List<BlockNode> preds = exitBlock.getPredecessors();
if (preds.size() < 2) {
return false;
}
preds = BlockUtils.filterPredecessors(exitBlock);
if (preds.size() < 2) {
return false;
}
InsnNode returnInsn = exitBlock.getInstructions().get(0);
if (returnInsn.getArgsCount() != 0 && !isReturnArgAssignInPred(preds, returnInsn)) {
return false;
}
boolean first = true;
for (BlockNode pred : preds) {
BlockNode newRetBlock = BlockSplitter.startNewBlock(mth, exitBlock.getStartOffset());
newRetBlock.add(AFlag.SYNTHETIC);
InsnNode newRetInsn;
if (first) {
newRetInsn = returnInsn;
newRetBlock.add(AFlag.ORIG_RETURN);
first = false;
} else {
newRetInsn = duplicateReturnInsn(returnInsn);
}
newRetBlock.getInstructions().add(newRetInsn);
removeConnection(pred, exitBlock);
connect(pred, newRetBlock);
}
cleanExitNodes(mth);
return true;
}
use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.
the class BlockProcessor method duplicateReturnInsn.
private static InsnNode duplicateReturnInsn(InsnNode returnInsn) {
InsnNode insn = new InsnNode(returnInsn.getType(), returnInsn.getArgsCount());
if (returnInsn.getArgsCount() == 1) {
RegisterArg arg = (RegisterArg) returnInsn.getArg(0);
insn.addArg(InsnArg.reg(arg.getRegNum(), arg.getType()));
}
insn.copyAttributesFrom(returnInsn);
insn.setOffset(returnInsn.getOffset());
insn.setSourceLine(returnInsn.getSourceLine());
return insn;
}
use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.
the class BlockProcessor method isReturnArgAssignInPred.
private static boolean isReturnArgAssignInPred(List<BlockNode> preds, InsnNode returnInsn) {
RegisterArg arg = (RegisterArg) returnInsn.getArg(0);
int regNum = arg.getRegNum();
for (BlockNode pred : preds) {
for (InsnNode insnNode : pred.getInstructions()) {
RegisterArg result = insnNode.getResult();
if (result != null && result.getRegNum() == regNum) {
return true;
}
}
}
return false;
}
use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.
the class BlockSplitter method setupConnections.
private static void setupConnections(MethodNode mth, Map<Integer, BlockNode> blocksMap) {
for (BlockNode block : mth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
List<JumpInfo> jumps = insn.getAll(AType.JUMP);
for (JumpInfo jump : jumps) {
BlockNode srcBlock = getBlock(jump.getSrc(), blocksMap);
BlockNode thisBlock = getBlock(jump.getDest(), blocksMap);
connect(srcBlock, thisBlock);
}
connectExceptionHandlers(blocksMap, block, insn);
}
}
}
Aggregations