use of jadx.core.dex.nodes.DexNode in project jadx by skylot.
the class ConstInlineVisitor method fixTypes.
/**
* This is method similar to PostTypeInference.process method,
* but contains some expensive operations needed only after constant inline
*/
private static void fixTypes(MethodNode mth, InsnNode insn, LiteralArg litArg) {
DexNode dex = mth.dex();
PostTypeInference.process(mth, insn);
switch(insn.getType()) {
case CONST:
insn.getArg(0).merge(dex, insn.getResult());
break;
case MOVE:
insn.getResult().merge(dex, insn.getArg(0));
insn.getArg(0).merge(dex, insn.getResult());
break;
case IPUT:
case SPUT:
IndexInsnNode node = (IndexInsnNode) insn;
insn.getArg(0).merge(dex, ((FieldInfo) node.getIndex()).getType());
break;
case IF:
{
InsnArg arg0 = insn.getArg(0);
InsnArg arg1 = insn.getArg(1);
if (arg0 == litArg) {
arg0.merge(dex, arg1);
} else {
arg1.merge(dex, arg0);
}
break;
}
case CMP_G:
case CMP_L:
InsnArg arg0 = insn.getArg(0);
InsnArg arg1 = insn.getArg(1);
if (arg0 == litArg) {
arg0.merge(dex, arg1);
} else {
arg1.merge(dex, arg0);
}
break;
case RETURN:
if (insn.getArgsCount() != 0) {
insn.getArg(0).merge(dex, mth.getReturnType());
}
break;
case INVOKE:
InvokeNode inv = (InvokeNode) insn;
List<ArgType> types = inv.getCallMth().getArgumentsTypes();
int count = insn.getArgsCount();
int k = types.size() == count ? 0 : -1;
for (int i = 0; i < count; i++) {
InsnArg arg = insn.getArg(i);
if (!arg.getType().isTypeKnown()) {
ArgType type;
if (k >= 0) {
type = types.get(k);
} else {
type = mth.getParentClass().getClassInfo().getType();
}
arg.merge(dex, type);
}
k++;
}
break;
case ARITH:
litArg.merge(dex, insn.getResult());
break;
case APUT:
case AGET:
if (litArg == insn.getArg(1)) {
litArg.merge(dex, ArgType.INT);
}
break;
case NEW_ARRAY:
if (litArg == insn.getArg(0)) {
litArg.merge(dex, ArgType.INT);
}
break;
default:
break;
}
}
use of jadx.core.dex.nodes.DexNode in project jadx by skylot.
the class DependencyCollector method visit.
@Override
public boolean visit(ClassNode cls) throws JadxException {
DexNode dex = cls.dex();
Set<ClassNode> depList = cls.getDependencies();
processClass(cls, dex, depList);
for (ClassNode inner : cls.getInnerClasses()) {
processClass(inner, dex, depList);
}
depList.remove(cls);
return false;
}
use of jadx.core.dex.nodes.DexNode in project jadx by skylot.
the class ConstStorage method getConstField.
@Nullable
public FieldNode getConstField(ClassNode cls, Object value, boolean searchGlobal) {
DexNode dex = cls.dex();
if (value instanceof Integer) {
String str = resourcesNames.get(value);
if (str != null) {
return new ResRefField(dex, str.replace('/', '.'));
}
}
if (!replaceEnabled) {
return null;
}
boolean foundInGlobal = globalValues.contains(value);
if (foundInGlobal && !searchGlobal) {
return null;
}
ClassNode current = cls;
while (current != null) {
Values classValues = classes.get(current);
if (classValues != null) {
FieldNode field = classValues.get(value);
if (field != null) {
if (foundInGlobal) {
return null;
}
return field;
}
}
ClassInfo parentClass = current.getClassInfo().getParentClass();
if (parentClass == null) {
break;
}
current = dex.resolveClass(parentClass);
}
if (searchGlobal) {
return globalValues.get(value);
}
return null;
}
use of jadx.core.dex.nodes.DexNode in project jadx by skylot.
the class PostTypeInference method process.
public static boolean process(MethodNode mth, InsnNode insn) {
DexNode dex = mth.dex();
switch(insn.getType()) {
case CONST:
RegisterArg res = insn.getResult();
LiteralArg litArg = (LiteralArg) insn.getArg(0);
if (res.getType().isObject()) {
long lit = litArg.getLiteral();
if (lit != 0) {
// incorrect literal value for object
ArgType type = lit == 1 ? ArgType.BOOLEAN : ArgType.INT;
// can't merge with object -> force it
litArg.setType(type);
res.getSVar().setType(type);
return true;
}
}
return litArg.merge(dex, res);
case MOVE:
{
boolean change = false;
if (insn.getResult().merge(dex, insn.getArg(0))) {
change = true;
}
if (insn.getArg(0).merge(dex, insn.getResult())) {
change = true;
}
return change;
}
case AGET:
return fixArrayTypes(dex, insn.getArg(0), insn.getResult());
case APUT:
return fixArrayTypes(dex, insn.getArg(0), insn.getArg(2));
case IF:
{
boolean change = false;
if (insn.getArg(1).merge(dex, insn.getArg(0))) {
change = true;
}
if (insn.getArg(0).merge(dex, insn.getArg(1))) {
change = true;
}
return change;
}
// check argument types for overloaded methods
case INVOKE:
{
boolean change = false;
InvokeNode inv = (InvokeNode) insn;
MethodInfo callMth = inv.getCallMth();
MethodNode node = mth.dex().resolveMethod(callMth);
if (node != null && node.isArgsOverload()) {
List<ArgType> args = callMth.getArgumentsTypes();
int j = inv.getArgsCount() - 1;
for (int i = args.size() - 1; i >= 0; i--) {
ArgType argType = args.get(i);
InsnArg insnArg = inv.getArg(j--);
if (insnArg.isRegister() && !argType.equals(insnArg.getType())) {
insnArg.setType(argType);
change = true;
}
}
}
return change;
}
case CHECK_CAST:
{
ArgType castType = (ArgType) ((IndexInsnNode) insn).getIndex();
RegisterArg result = insn.getResult();
ArgType resultType = result.getType();
// don't override generic types of same base class
boolean skip = castType.isObject() && resultType.isObject() && castType.getObject().equals(resultType.getObject());
if (!skip) {
// workaround for compiler bug (see TestDuplicateCast)
result.getSVar().setType(castType);
}
return true;
}
case PHI:
case MERGE:
{
ArgType type = insn.getResult().getType();
if (!type.isTypeKnown()) {
for (InsnArg arg : insn.getArguments()) {
if (arg.getType().isTypeKnown()) {
type = arg.getType();
break;
}
}
}
boolean changed = false;
if (updateType(insn.getResult(), type)) {
changed = true;
}
for (int i = 0; i < insn.getArgsCount(); i++) {
RegisterArg arg = (RegisterArg) insn.getArg(i);
if (updateType(arg, type)) {
changed = true;
}
}
return changed;
}
default:
break;
}
return false;
}
use of jadx.core.dex.nodes.DexNode in project jadx by skylot.
the class AndroidResourcesUtils method makeClass.
private static ClassNode makeClass(RootNode root, String clsName) {
DexNode firstDex = root.getDexNodes().get(0);
ClassInfo r = ClassInfo.fromName(firstDex, clsName);
return new ClassNode(firstDex, r);
}
Aggregations