use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class DebugController method markNextToBeUpdated.
// when single stepping we can detect which reg need to be updated.
private void markNextToBeUpdated(long codeOffset) {
if (codeOffset != -1) {
Object rst = cur.smali.getResultRegOrField(cur.mthFullID, codeOffset);
toBeUpdatedTreeNode = null;
if (cur.frame != null) {
if (rst instanceof Integer) {
int regNum = (int) rst;
if (cur.frame.getRegNodes().size() > regNum) {
toBeUpdatedTreeNode = cur.frame.getRegNodes().get(regNum);
}
return;
}
if (rst instanceof FieldInfo) {
FieldInfo info = (FieldInfo) rst;
toBeUpdatedTreeNode = cur.frame.getFieldNodes().stream().filter(f -> f.getName().equals(info.getName())).findFirst().orElse(null);
}
}
}
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class ExtractFieldInit method filterFieldsInit.
private static void filterFieldsInit(List<FieldInitInfo> inits) {
// exclude fields initialized several times
Set<FieldInfo> excludedFields = inits.stream().collect(Collectors.toMap(fi -> fi.fieldNode, fi -> 1, Integer::sum)).entrySet().stream().filter(v -> v.getValue() > 1).map(v -> v.getKey().getFieldInfo()).collect(Collectors.toSet());
for (FieldInitInfo initInfo : inits) {
if (!checkInsn(initInfo)) {
excludedFields.add(initInfo.fieldNode.getFieldInfo());
}
}
if (!excludedFields.isEmpty()) {
boolean changed;
do {
changed = false;
for (FieldInitInfo initInfo : inits) {
FieldInfo fieldInfo = initInfo.fieldNode.getFieldInfo();
if (excludedFields.contains(fieldInfo)) {
continue;
}
if (insnUseExcludedField(initInfo, excludedFields)) {
excludedFields.add(fieldInfo);
changed = true;
}
}
} while (changed);
}
// apply
if (!excludedFields.isEmpty()) {
inits.removeIf(fi -> excludedFields.contains(fi.fieldNode.getFieldInfo()));
}
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class ExtractFieldInit method collectFieldsInit.
private static List<FieldInitInfo> collectFieldsInit(ClassNode cls, MethodNode mth, InsnType putType) {
List<FieldInitInfo> fieldsInit = new ArrayList<>();
Set<BlockNode> singlePathBlocks = new HashSet<>();
BlockUtils.visitSinglePath(mth.getEnterBlock(), singlePathBlocks::add);
for (BlockNode block : mth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == putType) {
IndexInsnNode putInsn = (IndexInsnNode) insn;
FieldInfo field = (FieldInfo) putInsn.getIndex();
if (field.getDeclClass().equals(cls.getClassInfo())) {
FieldNode fn = cls.searchField(field);
if (fn != null) {
boolean singlePath = singlePathBlocks.contains(block);
fieldsInit.add(new FieldInitInfo(fn, putInsn, singlePath));
}
}
}
}
}
return fieldsInit;
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class InlineMethods method updateUsageInfo.
private void updateUsageInfo(MethodNode mth, MethodNode inlinedMth, InsnNode insn) {
inlinedMth.getUseIn().remove(mth);
insn.visitInsns(innerInsn -> {
// TODO: share code with UsageInfoVisitor
switch(innerInsn.getType()) {
case INVOKE:
case CONSTRUCTOR:
MethodInfo callMth = ((BaseInvokeNode) innerInsn).getCallMth();
MethodNode callMthNode = mth.root().resolveMethod(callMth);
if (callMthNode != null) {
callMthNode.setUseIn(ListUtils.safeReplace(callMthNode.getUseIn(), inlinedMth, mth));
replaceClsUsage(mth, inlinedMth, callMthNode.getParentClass());
}
break;
case IGET:
case IPUT:
case SPUT:
case SGET:
FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) innerInsn).getIndex();
FieldNode fieldNode = mth.root().resolveField(fieldInfo);
if (fieldNode != null) {
fieldNode.setUseIn(ListUtils.safeReplace(fieldNode.getUseIn(), inlinedMth, mth));
replaceClsUsage(mth, inlinedMth, fieldNode.getParentClass());
}
break;
}
});
}
use of jadx.core.dex.info.FieldInfo in project jadx by skylot.
the class MarkMethodsForInline method fixVisibilityOfInlineCode.
private static boolean fixVisibilityOfInlineCode(MethodNode mth, InsnNode insn) {
// TODO: calculate more precisely
int newVisFlag = AccessFlags.PUBLIC;
InsnType insnType = insn.getType();
if (insnType == InsnType.INVOKE) {
InvokeNode invoke = (InvokeNode) insn;
MethodNode callMthNode = mth.root().resolveMethod(invoke.getCallMth());
if (callMthNode != null) {
FixAccessModifiers.changeVisibility(callMthNode, newVisFlag);
}
return true;
}
if (insnType == InsnType.ONE_ARG) {
InsnArg arg = insn.getArg(0);
if (!arg.isInsnWrap()) {
return false;
}
return fixVisibilityOfInlineCode(mth, ((InsnWrapArg) arg).getWrapInsn());
}
if (insn instanceof IndexInsnNode) {
Object indexObj = ((IndexInsnNode) insn).getIndex();
if (indexObj instanceof FieldInfo) {
// field access must be already fixed in ModVisitor.fixFieldUsage method
return true;
}
}
if (Consts.DEBUG) {
mth.addDebugComment("can't inline method, not implemented redirect type: " + insn);
}
return false;
}
Aggregations