use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class ClassModifier method getArgsToFieldsMapping.
private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode mth, List<InsnNode> usedInsns) {
MethodInfo callMth = mth.getMethodInfo();
ClassNode cls = mth.getParentClass();
List<RegisterArg> argList = mth.getArgRegs();
ClassNode outerCls = mth.getUseIn().get(0).getParentClass();
int startArg = 0;
if (callMth.getArgsCount() != 0 && callMth.getArgumentsTypes().get(0).equals(outerCls.getClassInfo().getType())) {
startArg = 1;
}
Map<InsnArg, FieldNode> map = new LinkedHashMap<>();
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();
}
switch(useInsn.getType()) {
case IPUT:
FieldNode fieldNode = cls.searchField((FieldInfo) ((IndexInsnNode) useInsn).getIndex());
if (fieldNode == null || !fieldNode.getAccessFlags().isSynthetic()) {
return Collections.emptyMap();
}
map.put(arg, fieldNode);
usedInsns.add(useInsn);
break;
case CONSTRUCTOR:
ConstructorInsn superConstr = (ConstructorInsn) useInsn;
if (!superConstr.isSuper()) {
return Collections.emptyMap();
}
usedInsns.add(useInsn);
break;
default:
return Collections.emptyMap();
}
}
return map;
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class ClassModifier method checkSyntheticWrapper.
private static boolean checkSyntheticWrapper(MethodNode mth, InsnNode insn) {
InsnType insnType = insn.getType();
if (insnType != InsnType.INVOKE) {
return false;
}
InvokeNode invokeInsn = (InvokeNode) insn;
if (invokeInsn.getInvokeType() == InvokeType.SUPER) {
return false;
}
MethodInfo callMth = invokeInsn.getCallMth();
MethodNode wrappedMth = mth.root().resolveMethod(callMth);
if (wrappedMth == null) {
return false;
}
AccessInfo wrappedAccFlags = wrappedMth.getAccessFlags();
if (wrappedAccFlags.isStatic()) {
return false;
}
if (callMth.getArgsCount() != mth.getMethodInfo().getArgsCount()) {
return false;
}
// rename method only from current class
if (!mth.getParentClass().equals(wrappedMth.getParentClass())) {
return false;
}
// all args must be registers passed from method args (allow only casts insns)
for (InsnArg arg : insn.getArguments()) {
if (!registersAndCastsOnly(arg)) {
return false;
}
}
// remove confirmed, change visibility and name if needed
if (!wrappedAccFlags.isPublic()) {
// must be public
FixAccessModifiers.changeVisibility(wrappedMth, AccessFlags.PUBLIC);
}
String alias = mth.getAlias();
if (!Objects.equals(wrappedMth.getAlias(), alias)) {
wrappedMth.getMethodInfo().setAlias(alias);
}
return true;
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class LoopRegionVisitor method checkInvoke.
/**
* Check if instruction is a interface invoke with corresponding parameters.
*/
private static boolean checkInvoke(InsnNode insn, String declClsFullName, String mthId) {
if (insn == null) {
return false;
}
if (insn.getType() == InsnType.INVOKE) {
InvokeNode inv = (InvokeNode) insn;
MethodInfo callMth = inv.getCallMth();
if (inv.getInvokeType() == InvokeType.INTERFACE && callMth.getShortId().equals(mthId)) {
if (declClsFullName == null) {
return true;
}
return callMth.getDeclClass().getFullName().equals(declClsFullName);
}
}
return false;
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class ModVisitor method processInvoke.
private static void processInvoke(MethodNode mth, BlockNode block, int insnNumber, InstructionRemover remover) {
ClassNode parentClass = mth.getParentClass();
InsnNode insn = block.getInstructions().get(insnNumber);
InvokeNode inv = (InvokeNode) insn;
MethodInfo callMth = inv.getCallMth();
if (!callMth.isConstructor()) {
return;
}
InsnNode instArgAssignInsn = ((RegisterArg) inv.getArg(0)).getAssignInsn();
ConstructorInsn co = new ConstructorInsn(mth, inv);
boolean remove = false;
if (co.isSuper() && (co.getArgsCount() == 0 || parentClass.isEnum())) {
remove = true;
} else if (co.isThis() && co.getArgsCount() == 0) {
MethodNode defCo = parentClass.searchMethodByName(callMth.getShortId());
if (defCo == null || defCo.isNoCode()) {
// default constructor not implemented
remove = true;
}
}
// remove super() call in instance initializer
if (parentClass.isAnonymous() && mth.isDefaultConstructor() && co.isSuper()) {
remove = true;
}
if (remove) {
remover.add(insn);
return;
}
if (co.isNewInstance()) {
InsnNode newInstInsn = removeAssignChain(instArgAssignInsn, remover, InsnType.NEW_INSTANCE);
if (newInstInsn != null) {
RegisterArg instArg = newInstInsn.getResult();
RegisterArg resultArg = co.getResult();
if (!resultArg.equals(instArg)) {
// replace all usages of 'instArg' with result of this constructor instruction
for (RegisterArg useArg : new ArrayList<RegisterArg>(instArg.getSVar().getUseList())) {
RegisterArg dup = resultArg.duplicate();
InsnNode parentInsn = useArg.getParentInsn();
parentInsn.replaceArg(useArg, dup);
dup.setParentInsn(parentInsn);
resultArg.getSVar().use(dup);
}
}
}
}
ConstructorInsn replace = processConstructor(mth, co);
if (replace != null) {
co = replace;
}
replaceInsn(block, insnNumber, co);
processAnonymousConstructor(mth, co);
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class MethodNode method isArgsOverload.
/**
* Return true if exists method with same name and arguments count
*/
public boolean isArgsOverload() {
int argsCount = mthInfo.getArgumentsTypes().size();
if (argsCount == 0) {
return false;
}
String name = getName();
for (MethodNode method : parentClass.getMethods()) {
MethodInfo otherMthInfo = method.mthInfo;
if (this != method && otherMthInfo.getArgumentsTypes().size() == argsCount && otherMthInfo.getName().equals(name)) {
return true;
}
}
return false;
}
Aggregations