use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class ExtractFieldInit method processStaticFieldAssign.
/**
* Remove final field in place initialization if it assign in class init method
*/
private static void processStaticFieldAssign(ClassNode cls, IndexInsnNode insn) {
FieldInfo field = (FieldInfo) insn.getIndex();
String thisClass = cls.getClassInfo().getFullName();
if (field.getDeclClass().getFullName().equals(thisClass)) {
FieldNode fn = cls.searchField(field);
if (fn != null && fn.getAccessFlags().isFinal()) {
fn.remove(AType.FIELD_INIT);
}
}
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class ModVisitor method getArgsToFieldsMapping.
private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode callMthNode, ConstructorInsn co) {
Map<InsnArg, FieldNode> map = new LinkedHashMap<InsnArg, FieldNode>();
ClassNode parentClass = callMthNode.getParentClass();
List<RegisterArg> argList = callMthNode.getArguments(false);
int startArg = parentClass.getAccessFlags().isStatic() ? 0 : 1;
int argsCount = argList.size();
for (int i = startArg; i < argsCount; i++) {
RegisterArg arg = argList.get(i);
InsnNode useInsn = getParentInsnSkipMove(arg);
if (useInsn == null) {
return Collections.emptyMap();
}
FieldNode fieldNode = null;
if (useInsn.getType() == InsnType.IPUT) {
FieldInfo field = (FieldInfo) ((IndexInsnNode) useInsn).getIndex();
fieldNode = parentClass.searchField(field);
if (fieldNode == null || !fieldNode.getAccessFlags().isSynthetic()) {
return Collections.emptyMap();
}
} else if (useInsn.getType() == InsnType.CONSTRUCTOR) {
ConstructorInsn superConstr = (ConstructorInsn) useInsn;
if (!superConstr.isSuper()) {
return Collections.emptyMap();
}
} else {
return Collections.emptyMap();
}
map.put(co.getArg(i), fieldNode);
}
return map;
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class DeobfPresets method dumpMapping.
/**
* Saves DefaultDeobfuscator presets
*/
private void dumpMapping() throws IOException {
List<String> list = new ArrayList<String>();
// packages
for (PackageNode p : deobfuscator.getRootPackage().getInnerPackages()) {
for (PackageNode pp : p.getInnerPackages()) {
dfsPackageName(list, p.getName(), pp);
}
if (p.hasAlias()) {
list.add(String.format("p %s = %s", p.getName(), p.getAlias()));
}
}
// classes
for (DeobfClsInfo deobfClsInfo : deobfuscator.getClsMap().values()) {
if (deobfClsInfo.getAlias() != null) {
list.add(String.format("c %s = %s", deobfClsInfo.getCls().getClassInfo().getFullName(), deobfClsInfo.getAlias()));
}
}
for (FieldInfo fld : deobfuscator.getFldMap().keySet()) {
list.add(String.format("f %s = %s", fld.getFullId(), fld.getAlias()));
}
for (MethodInfo mth : deobfuscator.getMthMap().keySet()) {
list.add(String.format("m %s = %s", mth.getFullId(), mth.getAlias()));
}
Collections.sort(list);
FileUtils.writeLines(deobfMapFile, MAP_FILE_CHARSET, list);
list.clear();
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class AnnotationGen method encodeValue.
// TODO: refactor this boilerplate code
public void encodeValue(CodeWriter code, Object val) {
if (val == null) {
code.add("null");
return;
}
if (val instanceof String) {
code.add(getStringUtils().unescapeString((String) val));
} else if (val instanceof Integer) {
code.add(TypeGen.formatInteger((Integer) val));
} else if (val instanceof Character) {
code.add(getStringUtils().unescapeChar((Character) val));
} else if (val instanceof Boolean) {
code.add(Boolean.TRUE.equals(val) ? "true" : "false");
} else if (val instanceof Float) {
code.add(TypeGen.formatFloat((Float) val));
} else if (val instanceof Double) {
code.add(TypeGen.formatDouble((Double) val));
} else if (val instanceof Long) {
code.add(TypeGen.formatLong((Long) val));
} else if (val instanceof Short) {
code.add(TypeGen.formatShort((Short) val));
} else if (val instanceof Byte) {
code.add(TypeGen.formatByte((Byte) val));
} else if (val instanceof ArgType) {
classGen.useType(code, (ArgType) val);
code.add(".class");
} else if (val instanceof FieldInfo) {
// must be a static field
FieldInfo field = (FieldInfo) val;
InsnGen.makeStaticFieldAccess(code, field, classGen);
} else if (val instanceof Iterable) {
code.add('{');
Iterator<?> it = ((Iterable) val).iterator();
while (it.hasNext()) {
Object obj = it.next();
encodeValue(code, obj);
if (it.hasNext()) {
code.add(", ");
}
}
code.add('}');
} else if (val instanceof Annotation) {
formatAnnotation(code, (Annotation) val);
} else {
// TODO: also can be method values
throw new JadxRuntimeException("Can't decode value: " + val + " (" + val.getClass() + ")");
}
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class InsnDecoder method decode.
@NotNull
protected InsnNode decode(InsnData insn) throws DecodeException {
switch(insn.getOpcode()) {
case NOP:
return new InsnNode(InsnType.NOP, 0);
// move-result will be process in invoke and filled-new-array instructions
case MOVE_RESULT:
return insn(InsnType.MOVE_RESULT, InsnArg.reg(insn, 0, ArgType.UNKNOWN));
case CONST:
LiteralArg narrowLitArg = InsnArg.lit(insn, ArgType.NARROW);
return insn(InsnType.CONST, InsnArg.reg(insn, 0, narrowLitArg.getType()), narrowLitArg);
case CONST_WIDE:
LiteralArg wideLitArg = InsnArg.lit(insn, ArgType.WIDE);
return insn(InsnType.CONST, InsnArg.reg(insn, 0, wideLitArg.getType()), wideLitArg);
case CONST_STRING:
InsnNode constStrInsn = new ConstStringNode(insn.getIndexAsString());
constStrInsn.setResult(InsnArg.reg(insn, 0, ArgType.STRING));
return constStrInsn;
case CONST_CLASS:
{
ArgType clsType = ArgType.parse(insn.getIndexAsType());
InsnNode constClsInsn = new ConstClassNode(clsType);
constClsInsn.setResult(InsnArg.reg(insn, 0, ArgType.generic(Consts.CLASS_CLASS, clsType)));
return constClsInsn;
}
case MOVE:
return insn(InsnType.MOVE, InsnArg.reg(insn, 0, ArgType.NARROW), InsnArg.reg(insn, 1, ArgType.NARROW));
case MOVE_MULTI:
int len = insn.getRegsCount();
InsnNode mmv = new InsnNode(InsnType.MOVE_MULTI, len);
for (int i = 0; i < len; i++) {
mmv.addArg(InsnArg.reg(insn, i, ArgType.UNKNOWN));
}
return mmv;
case MOVE_WIDE:
return insn(InsnType.MOVE, InsnArg.reg(insn, 0, ArgType.WIDE), InsnArg.reg(insn, 1, ArgType.WIDE));
case MOVE_OBJECT:
return insn(InsnType.MOVE, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT), InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT));
case ADD_INT:
return arith(insn, ArithOp.ADD, ArgType.INT);
case ADD_DOUBLE:
return arith(insn, ArithOp.ADD, ArgType.DOUBLE);
case ADD_FLOAT:
return arith(insn, ArithOp.ADD, ArgType.FLOAT);
case ADD_LONG:
return arith(insn, ArithOp.ADD, ArgType.LONG);
case ADD_INT_LIT:
return arithLit(insn, ArithOp.ADD, ArgType.INT);
case SUB_INT:
return arith(insn, ArithOp.SUB, ArgType.INT);
case RSUB_INT:
return new ArithNode(ArithOp.SUB, InsnArg.reg(insn, 0, ArgType.INT), InsnArg.lit(insn, ArgType.INT), InsnArg.reg(insn, 1, ArgType.INT));
case SUB_LONG:
return arith(insn, ArithOp.SUB, ArgType.LONG);
case SUB_FLOAT:
return arith(insn, ArithOp.SUB, ArgType.FLOAT);
case SUB_DOUBLE:
return arith(insn, ArithOp.SUB, ArgType.DOUBLE);
case MUL_INT:
return arith(insn, ArithOp.MUL, ArgType.INT);
case MUL_DOUBLE:
return arith(insn, ArithOp.MUL, ArgType.DOUBLE);
case MUL_FLOAT:
return arith(insn, ArithOp.MUL, ArgType.FLOAT);
case MUL_LONG:
return arith(insn, ArithOp.MUL, ArgType.LONG);
case MUL_INT_LIT:
return arithLit(insn, ArithOp.MUL, ArgType.INT);
case DIV_INT:
return arith(insn, ArithOp.DIV, ArgType.INT);
case REM_INT:
return arith(insn, ArithOp.REM, ArgType.INT);
case REM_LONG:
return arith(insn, ArithOp.REM, ArgType.LONG);
case REM_FLOAT:
return arith(insn, ArithOp.REM, ArgType.FLOAT);
case REM_DOUBLE:
return arith(insn, ArithOp.REM, ArgType.DOUBLE);
case DIV_DOUBLE:
return arith(insn, ArithOp.DIV, ArgType.DOUBLE);
case DIV_FLOAT:
return arith(insn, ArithOp.DIV, ArgType.FLOAT);
case DIV_LONG:
return arith(insn, ArithOp.DIV, ArgType.LONG);
case DIV_INT_LIT:
return arithLit(insn, ArithOp.DIV, ArgType.INT);
case REM_INT_LIT:
return arithLit(insn, ArithOp.REM, ArgType.INT);
case AND_INT:
return arith(insn, ArithOp.AND, ArgType.INT);
case AND_INT_LIT:
return arithLit(insn, ArithOp.AND, ArgType.INT);
case XOR_INT_LIT:
return arithLit(insn, ArithOp.XOR, ArgType.INT);
case AND_LONG:
return arith(insn, ArithOp.AND, ArgType.LONG);
case OR_INT:
return arith(insn, ArithOp.OR, ArgType.INT);
case OR_INT_LIT:
return arithLit(insn, ArithOp.OR, ArgType.INT);
case XOR_INT:
return arith(insn, ArithOp.XOR, ArgType.INT);
case OR_LONG:
return arith(insn, ArithOp.OR, ArgType.LONG);
case XOR_LONG:
return arith(insn, ArithOp.XOR, ArgType.LONG);
case USHR_INT:
return arith(insn, ArithOp.USHR, ArgType.INT);
case USHR_LONG:
return arith(insn, ArithOp.USHR, ArgType.LONG);
case SHL_INT:
return arith(insn, ArithOp.SHL, ArgType.INT);
case SHL_LONG:
return arith(insn, ArithOp.SHL, ArgType.LONG);
case SHR_INT:
return arith(insn, ArithOp.SHR, ArgType.INT);
case SHR_LONG:
return arith(insn, ArithOp.SHR, ArgType.LONG);
case SHL_INT_LIT:
return arithLit(insn, ArithOp.SHL, ArgType.INT);
case SHR_INT_LIT:
return arithLit(insn, ArithOp.SHR, ArgType.INT);
case USHR_INT_LIT:
return arithLit(insn, ArithOp.USHR, ArgType.INT);
case NEG_INT:
return neg(insn, ArgType.INT);
case NEG_LONG:
return neg(insn, ArgType.LONG);
case NEG_FLOAT:
return neg(insn, ArgType.FLOAT);
case NEG_DOUBLE:
return neg(insn, ArgType.DOUBLE);
case NOT_INT:
return not(insn, ArgType.INT);
case NOT_LONG:
return not(insn, ArgType.LONG);
case INT_TO_BYTE:
return cast(insn, ArgType.INT, ArgType.BYTE);
case INT_TO_CHAR:
return cast(insn, ArgType.INT, ArgType.CHAR);
case INT_TO_SHORT:
return cast(insn, ArgType.INT, ArgType.SHORT);
case INT_TO_FLOAT:
return cast(insn, ArgType.INT, ArgType.FLOAT);
case INT_TO_DOUBLE:
return cast(insn, ArgType.INT, ArgType.DOUBLE);
case INT_TO_LONG:
return cast(insn, ArgType.INT, ArgType.LONG);
case FLOAT_TO_INT:
return cast(insn, ArgType.FLOAT, ArgType.INT);
case FLOAT_TO_DOUBLE:
return cast(insn, ArgType.FLOAT, ArgType.DOUBLE);
case FLOAT_TO_LONG:
return cast(insn, ArgType.FLOAT, ArgType.LONG);
case DOUBLE_TO_INT:
return cast(insn, ArgType.DOUBLE, ArgType.INT);
case DOUBLE_TO_FLOAT:
return cast(insn, ArgType.DOUBLE, ArgType.FLOAT);
case DOUBLE_TO_LONG:
return cast(insn, ArgType.DOUBLE, ArgType.LONG);
case LONG_TO_INT:
return cast(insn, ArgType.LONG, ArgType.INT);
case LONG_TO_FLOAT:
return cast(insn, ArgType.LONG, ArgType.FLOAT);
case LONG_TO_DOUBLE:
return cast(insn, ArgType.LONG, ArgType.DOUBLE);
case IF_EQ:
case IF_EQZ:
return new IfNode(insn, IfOp.EQ);
case IF_NE:
case IF_NEZ:
return new IfNode(insn, IfOp.NE);
case IF_GT:
case IF_GTZ:
return new IfNode(insn, IfOp.GT);
case IF_GE:
case IF_GEZ:
return new IfNode(insn, IfOp.GE);
case IF_LT:
case IF_LTZ:
return new IfNode(insn, IfOp.LT);
case IF_LE:
case IF_LEZ:
return new IfNode(insn, IfOp.LE);
case CMP_LONG:
return cmp(insn, InsnType.CMP_L, ArgType.LONG);
case CMPL_FLOAT:
return cmp(insn, InsnType.CMP_L, ArgType.FLOAT);
case CMPL_DOUBLE:
return cmp(insn, InsnType.CMP_L, ArgType.DOUBLE);
case CMPG_FLOAT:
return cmp(insn, InsnType.CMP_G, ArgType.FLOAT);
case CMPG_DOUBLE:
return cmp(insn, InsnType.CMP_G, ArgType.DOUBLE);
case GOTO:
return new GotoNode(insn.getTarget());
case THROW:
return insn(InsnType.THROW, null, InsnArg.reg(insn, 0, ArgType.THROWABLE));
case MOVE_EXCEPTION:
return insn(InsnType.MOVE_EXCEPTION, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT_NO_ARRAY));
case RETURN_VOID:
return new InsnNode(InsnType.RETURN, 0);
case RETURN:
return insn(InsnType.RETURN, null, InsnArg.reg(insn, 0, method.getReturnType()));
case INSTANCE_OF:
InsnNode instInsn = new IndexInsnNode(InsnType.INSTANCE_OF, ArgType.parse(insn.getIndexAsType()), 1);
instInsn.setResult(InsnArg.reg(insn, 0, ArgType.BOOLEAN));
instInsn.addArg(InsnArg.reg(insn, 1, ArgType.UNKNOWN_OBJECT));
return instInsn;
case CHECK_CAST:
ArgType castType = ArgType.parse(insn.getIndexAsType());
InsnNode checkCastInsn = new IndexInsnNode(InsnType.CHECK_CAST, castType, 1);
checkCastInsn.setResult(InsnArg.reg(insn, 0, castType));
checkCastInsn.addArg(InsnArg.reg(insn, insn.getRegsCount() == 2 ? 1 : 0, ArgType.UNKNOWN_OBJECT));
return checkCastInsn;
case IGET:
FieldInfo igetFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode igetInsn = new IndexInsnNode(InsnType.IGET, igetFld, 1);
igetInsn.setResult(InsnArg.reg(insn, 0, tryResolveFieldType(igetFld)));
igetInsn.addArg(InsnArg.reg(insn, 1, igetFld.getDeclClass().getType()));
return igetInsn;
case IPUT:
FieldInfo iputFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode iputInsn = new IndexInsnNode(InsnType.IPUT, iputFld, 2);
iputInsn.addArg(InsnArg.reg(insn, 0, tryResolveFieldType(iputFld)));
iputInsn.addArg(InsnArg.reg(insn, 1, iputFld.getDeclClass().getType()));
return iputInsn;
case SGET:
FieldInfo sgetFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode sgetInsn = new IndexInsnNode(InsnType.SGET, sgetFld, 0);
sgetInsn.setResult(InsnArg.reg(insn, 0, tryResolveFieldType(sgetFld)));
return sgetInsn;
case SPUT:
FieldInfo sputFld = FieldInfo.fromRef(root, insn.getIndexAsField());
InsnNode sputInsn = new IndexInsnNode(InsnType.SPUT, sputFld, 1);
sputInsn.addArg(InsnArg.reg(insn, 0, tryResolveFieldType(sputFld)));
return sputInsn;
case ARRAY_LENGTH:
InsnNode arrLenInsn = new InsnNode(InsnType.ARRAY_LENGTH, 1);
arrLenInsn.setResult(InsnArg.reg(insn, 0, ArgType.INT));
arrLenInsn.addArg(InsnArg.reg(insn, 1, ArgType.array(ArgType.UNKNOWN)));
return arrLenInsn;
case AGET:
return arrayGet(insn, ArgType.INT_FLOAT);
case AGET_BOOLEAN:
return arrayGet(insn, ArgType.BOOLEAN);
case AGET_BYTE:
return arrayGet(insn, ArgType.BYTE);
case AGET_BYTE_BOOLEAN:
return arrayGet(insn, ArgType.BYTE_BOOLEAN);
case AGET_CHAR:
return arrayGet(insn, ArgType.CHAR);
case AGET_SHORT:
return arrayGet(insn, ArgType.SHORT);
case AGET_WIDE:
return arrayGet(insn, ArgType.WIDE);
case AGET_OBJECT:
return arrayGet(insn, ArgType.UNKNOWN_OBJECT);
case APUT:
return arrayPut(insn, ArgType.INT_FLOAT);
case APUT_BOOLEAN:
return arrayPut(insn, ArgType.BOOLEAN);
case APUT_BYTE:
return arrayPut(insn, ArgType.BYTE);
case APUT_BYTE_BOOLEAN:
return arrayPut(insn, ArgType.BYTE_BOOLEAN);
case APUT_CHAR:
return arrayPut(insn, ArgType.CHAR);
case APUT_SHORT:
return arrayPut(insn, ArgType.SHORT);
case APUT_WIDE:
return arrayPut(insn, ArgType.WIDE);
case APUT_OBJECT:
return arrayPut(insn, ArgType.UNKNOWN_OBJECT);
case INVOKE_STATIC:
return invoke(insn, InvokeType.STATIC, false);
case INVOKE_STATIC_RANGE:
return invoke(insn, InvokeType.STATIC, true);
case INVOKE_DIRECT:
return invoke(insn, InvokeType.DIRECT, false);
case INVOKE_INTERFACE:
return invoke(insn, InvokeType.INTERFACE, false);
case INVOKE_SUPER:
return invoke(insn, InvokeType.SUPER, false);
case INVOKE_VIRTUAL:
return invoke(insn, InvokeType.VIRTUAL, false);
case INVOKE_CUSTOM:
return invokeCustom(insn, false);
case INVOKE_SPECIAL:
return invokeSpecial(insn);
case INVOKE_DIRECT_RANGE:
return invoke(insn, InvokeType.DIRECT, true);
case INVOKE_INTERFACE_RANGE:
return invoke(insn, InvokeType.INTERFACE, true);
case INVOKE_SUPER_RANGE:
return invoke(insn, InvokeType.SUPER, true);
case INVOKE_VIRTUAL_RANGE:
return invoke(insn, InvokeType.VIRTUAL, true);
case INVOKE_CUSTOM_RANGE:
return invokeCustom(insn, true);
case NEW_INSTANCE:
ArgType clsType = ArgType.parse(insn.getIndexAsType());
IndexInsnNode newInstInsn = new IndexInsnNode(InsnType.NEW_INSTANCE, clsType, 0);
newInstInsn.setResult(InsnArg.reg(insn, 0, clsType));
return newInstInsn;
case NEW_ARRAY:
return makeNewArray(insn);
case FILL_ARRAY_DATA:
return new FillArrayInsn(InsnArg.reg(insn, 0, ArgType.UNKNOWN_ARRAY), insn.getTarget());
case FILL_ARRAY_DATA_PAYLOAD:
return new FillArrayData(((IArrayPayload) Objects.requireNonNull(insn.getPayload())));
case FILLED_NEW_ARRAY:
return filledNewArray(insn, false);
case FILLED_NEW_ARRAY_RANGE:
return filledNewArray(insn, true);
case PACKED_SWITCH:
return makeSwitch(insn, true);
case SPARSE_SWITCH:
return makeSwitch(insn, false);
case PACKED_SWITCH_PAYLOAD:
case SPARSE_SWITCH_PAYLOAD:
return new SwitchData(((ISwitchPayload) insn.getPayload()));
case MONITOR_ENTER:
return insn(InsnType.MONITOR_ENTER, null, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
case MONITOR_EXIT:
return insn(InsnType.MONITOR_EXIT, null, InsnArg.reg(insn, 0, ArgType.UNKNOWN_OBJECT));
default:
throw new DecodeException("Unknown instruction: '" + insn + '\'');
}
}
Aggregations