use of jadx.core.dex.instructions.args.InsnWrapArg in project jadx by skylot.
the class CodeShrinker method simplifyMoveInsns.
private static void simplifyMoveInsns(BlockNode block) {
List<InsnNode> insns = block.getInstructions();
int size = insns.size();
for (int i = 0; i < size; i++) {
InsnNode insn = insns.get(i);
if (insn.getType() == InsnType.MOVE) {
// replace 'move' with wrapped insn
InsnArg arg = insn.getArg(0);
if (arg.isInsnWrap()) {
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
wrapInsn.setResult(insn.getResult());
wrapInsn.copyAttributesFrom(insn);
wrapInsn.setOffset(insn.getOffset());
wrapInsn.remove(AFlag.WRAPPED);
block.getInstructions().set(i, wrapInsn);
}
}
}
}
use of jadx.core.dex.instructions.args.InsnWrapArg in project jadx by skylot.
the class SimplifyVisitor method simplifyArith.
private static InsnNode simplifyArith(InsnNode insn) {
ArithNode arith = (ArithNode) insn;
if (arith.getArgsCount() != 2) {
return null;
}
InsnArg litArg = null;
InsnArg secondArg = arith.getArg(1);
if (secondArg.isInsnWrap()) {
InsnNode wr = ((InsnWrapArg) secondArg).getWrapInsn();
if (wr.getType() == InsnType.CONST) {
litArg = wr.getArg(0);
}
} else if (secondArg.isLiteral()) {
litArg = secondArg;
}
if (litArg != null) {
long lit = ((LiteralArg) litArg).getLiteral();
// fix 'c + (-1)' => 'c - (1)'
if (arith.getOp() == ArithOp.ADD && lit < 0) {
return new ArithNode(ArithOp.SUB, arith.getResult(), insn.getArg(0), InsnArg.lit(-lit, litArg.getType()));
}
}
return null;
}
use of jadx.core.dex.instructions.args.InsnWrapArg in project jadx by skylot.
the class SimplifyVisitor method convertInvoke.
private static InsnNode convertInvoke(MethodNode mth, InsnNode insn) {
MethodInfo callMth = ((InvokeNode) insn).getCallMth();
// convert it to STRING_CONCAT pseudo instruction.
if (callMth.getDeclClass().getFullName().equals(Consts.CLASS_STRING_BUILDER) && callMth.getShortId().equals(Consts.MTH_TOSTRING_SIGNATURE) && insn.getArg(0).isInsnWrap()) {
try {
List<InsnNode> chain = flattenInsnChain(insn);
//RAF
int constrIndex = -1;
// string is created using .append() calls:
if (chain.size() > 1 && chain.get(0).getType() == InsnType.CONSTRUCTOR) {
constrIndex = 0;
} else if (chain.size() > 2 && chain.get(1).getType() == InsnType.CONSTRUCTOR) {
//RAF Case where the first string element is String arg to the
// new StringBuilder("xxx") constructor
constrIndex = 1;
} else if (chain.size() > 3 && chain.get(2).getType() == InsnType.CONSTRUCTOR) {
//RAF Case where the first string element is String.valueOf() arg
// to the new StringBuilder(String.valueOf(zzz)) constructor
constrIndex = 2;
}
if (constrIndex != -1) {
// If we found a CONSTRUCTOR, is it a StringBuilder?
ConstructorInsn constr = (ConstructorInsn) chain.get(constrIndex);
if (constr.getClassType().getFullName().equals(Consts.CLASS_STRING_BUILDER)) {
int len = chain.size(), argInd = 1;
InsnNode concatInsn = new InsnNode(InsnType.STR_CONCAT, len - 1);
InsnNode argInsn;
if (constrIndex > 0) {
// There was an arg to the StringBuilder constr
InsnWrapArg iwa;
if (constrIndex == 2 && (argInsn = chain.get(1)).getType() == InsnType.INVOKE && ((InvokeNode) argInsn).getCallMth().getName().compareTo("valueOf") == 0) {
// The argument of new StringBuilder() is a String.valueOf(chainElement0)
iwa = (InsnWrapArg) argInsn.getArg(0);
// Cause for loop below to skip to after the constructor
argInd = 3;
} else {
InsnNode firstNode = chain.get(0);
if (firstNode instanceof ConstStringNode) {
ConstStringNode csn = (ConstStringNode) firstNode;
iwa = new InsnWrapArg(csn);
// Cause for loop below to skip to after the constructor
argInd = 2;
} else {
return null;
}
}
concatInsn.addArg(iwa);
}
for (; argInd < len; argInd++) {
// Add the .append(xxx) arg string to concat
concatInsn.addArg(chain.get(argInd).getArg(1));
}
concatInsn.setResult(insn.getResult());
return concatInsn;
}
// end of if constructor is for StringBuilder
}
// end of if we found a constructor early in the chain
} catch (Throwable e) {
LOG.debug("Can't convert string concatenation: {} insn: {}", mth, insn, e);
}
}
return null;
}
use of jadx.core.dex.instructions.args.InsnWrapArg in project jadx by skylot.
the class PrepareForCodeGen method checkInsn.
/**
* Remove parenthesis for wrapped insn in arith '+' or '-'
* ('(a + b) +c' => 'a + b + c')
*/
private static void checkInsn(InsnNode insn) {
if (insn.getType() == InsnType.ARITH) {
ArithNode arith = (ArithNode) insn;
ArithOp op = arith.getOp();
if (op == ArithOp.ADD || op == ArithOp.SUB) {
for (int i = 0; i < 2; i++) {
InsnArg arg = arith.getArg(i);
if (arg.isInsnWrap()) {
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
wrapInsn.add(AFlag.DONT_WRAP);
checkInsn(wrapInsn);
}
}
}
} else {
for (InsnArg arg : insn.getArguments()) {
if (arg.isInsnWrap()) {
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
checkInsn(wrapInsn);
}
}
}
}
use of jadx.core.dex.instructions.args.InsnWrapArg in project jadx by skylot.
the class PrepareForCodeGen method checkInline.
private static void checkInline(BlockNode block) {
List<InsnNode> list = block.getInstructions();
for (int i = 0; i < list.size(); i++) {
InsnNode insn = list.get(i);
// replace 'move' with inner wrapped instruction
if (insn.getType() == InsnType.MOVE && insn.getArg(0).isInsnWrap()) {
InsnNode wrapInsn = ((InsnWrapArg) insn.getArg(0)).getWrapInsn();
wrapInsn.setResult(insn.getResult());
wrapInsn.copyAttributesFrom(insn);
list.set(i, wrapInsn);
}
}
}
Aggregations