Search in sources :

Example 11 with MethodNode

use of jadx.core.dex.nodes.MethodNode in project jadx by skylot.

the class ModVisitor method processAnonymousConstructor.

private static void processAnonymousConstructor(MethodNode mth, ConstructorInsn co) {
    MethodInfo callMth = co.getCallMth();
    MethodNode callMthNode = mth.dex().resolveMethod(callMth);
    if (callMthNode == null) {
        return;
    }
    ClassNode classNode = callMthNode.getParentClass();
    ClassInfo classInfo = classNode.getClassInfo();
    ClassNode parentClass = mth.getParentClass();
    if (!classInfo.isInner() || !Character.isDigit(classInfo.getShortName().charAt(0)) || !parentClass.getInnerClasses().contains(classNode)) {
        return;
    }
    if (!classNode.getAccessFlags().isStatic() && (callMth.getArgsCount() == 0 || !callMth.getArgumentsTypes().get(0).equals(parentClass.getClassInfo().getType()))) {
        return;
    }
    // TODO: calculate this constructor and other constructor usage
    Map<InsnArg, FieldNode> argsMap = getArgsToFieldsMapping(callMthNode, co);
    if (argsMap.isEmpty()) {
        return;
    }
    // all checks passed
    classNode.add(AFlag.ANONYMOUS_CLASS);
    callMthNode.add(AFlag.DONT_GENERATE);
    for (Map.Entry<InsnArg, FieldNode> entry : argsMap.entrySet()) {
        FieldNode field = entry.getValue();
        if (field == null) {
            continue;
        }
        InsnArg arg = entry.getKey();
        field.addAttr(new FieldReplaceAttr(arg));
        field.add(AFlag.DONT_GENERATE);
        if (arg.isRegister()) {
            RegisterArg reg = (RegisterArg) arg;
            SSAVar sVar = reg.getSVar();
            if (sVar != null) {
                sVar.add(AFlag.FINAL);
                sVar.add(AFlag.DONT_INLINE);
            }
            reg.add(AFlag.SKIP_ARG);
        }
    }
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) MethodNode(jadx.core.dex.nodes.MethodNode) FieldNode(jadx.core.dex.nodes.FieldNode) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) FieldReplaceAttr(jadx.core.dex.attributes.nodes.FieldReplaceAttr) MethodInfo(jadx.core.dex.info.MethodInfo) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 12 with MethodNode

use of jadx.core.dex.nodes.MethodNode in project jadx by skylot.

the class CheckRegions method visit.

@Override
public void visit(MethodNode mth) throws JadxException {
    if (mth.isNoCode() || mth.getBasicBlocks().isEmpty() || mth.contains(AType.JADX_ERROR)) {
        return;
    }
    // check if all blocks included in regions
    final Set<BlockNode> blocksInRegions = new HashSet<BlockNode>();
    DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {

        @Override
        public void processBlock(MethodNode mth, IBlock container) {
            if (!(container instanceof BlockNode)) {
                return;
            }
            BlockNode block = (BlockNode) container;
            if (blocksInRegions.add(block)) {
                return;
            }
            if (!block.contains(AFlag.RETURN) && !block.contains(AFlag.SKIP) && !block.contains(AFlag.SYNTHETIC) && !block.getInstructions().isEmpty()) {
                // TODO
                // mth.add(AFlag.INCONSISTENT_CODE);
                LOG.debug(" Duplicated block: {} in {}", block, mth);
            }
        }
    });
    if (mth.getBasicBlocks().size() != blocksInRegions.size()) {
        for (BlockNode block : mth.getBasicBlocks()) {
            if (!blocksInRegions.contains(block) && !block.getInstructions().isEmpty() && !block.contains(AFlag.SKIP)) {
                mth.add(AFlag.INCONSISTENT_CODE);
                LOG.debug(" Missing block: {} in {}", block, mth);
            }
        }
    }
    // check loop conditions
    DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {

        @Override
        public boolean enterRegion(MethodNode mth, IRegion region) {
            if (region instanceof LoopRegion) {
                BlockNode loopHeader = ((LoopRegion) region).getHeader();
                if (loopHeader != null && loopHeader.getInstructions().size() != 1) {
                    ErrorsCounter.methodError(mth, "Incorrect condition in loop: " + loopHeader);
                }
            }
            return true;
        }
    });
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IBlock(jadx.core.dex.nodes.IBlock) MethodNode(jadx.core.dex.nodes.MethodNode) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IRegion(jadx.core.dex.nodes.IRegion) HashSet(java.util.HashSet)

Example 13 with MethodNode

use of jadx.core.dex.nodes.MethodNode in project jadx by skylot.

the class TestLineNumbers method test.

@Test
public void test() {
    ClassNode cls = getClassNode(TestCls.class);
    String code = cls.getCode().toString();
    FieldNode field = cls.searchFieldByName("field");
    MethodNode func = cls.searchMethodByName("func()V");
    ClassNode inner = cls.getInnerClasses().get(0);
    MethodNode innerFunc = inner.searchMethodByName("innerFunc()V");
    MethodNode innerFunc2 = inner.searchMethodByName("innerFunc2()V");
    MethodNode innerFunc3 = inner.searchMethodByName("innerFunc3()V");
    FieldNode innerField = inner.searchFieldByName("innerField");
    // check source lines (available only for instructions and methods)
    int testClassLine = 18;
    assertEquals(testClassLine + 3, func.getSourceLine());
    assertEquals(testClassLine + 9, innerFunc.getSourceLine());
    assertEquals(testClassLine + 12, innerFunc2.getSourceLine());
    assertEquals(testClassLine + 20, innerFunc3.getSourceLine());
    // check decompiled lines
    String[] lines = code.split(CodeWriter.NL);
    checkLine(lines, field, "int field;");
    checkLine(lines, func, "public void func() {");
    checkLine(lines, inner, "public static class Inner {");
    checkLine(lines, innerField, "int innerField;");
    checkLine(lines, innerFunc, "public void innerFunc() {");
    checkLine(lines, innerFunc2, "public void innerFunc2() {");
    checkLine(lines, innerFunc3, "public void innerFunc3() {");
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) FieldNode(jadx.core.dex.nodes.FieldNode) MethodNode(jadx.core.dex.nodes.MethodNode) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) IntegrationTest(jadx.tests.api.IntegrationTest) Test(org.junit.Test)

Example 14 with MethodNode

use of jadx.core.dex.nodes.MethodNode in project jadx by skylot.

the class TestReturnSourceLine method test.

@Test
public void test() {
    ClassNode cls = getClassNode(TestCls.class);
    CodeWriter codeWriter = cls.getCode();
    String code = codeWriter.toString();
    String[] lines = code.split(CodeWriter.NL);
    MethodNode test1 = cls.searchMethodByName("test1(Z)I");
    checkLine(lines, codeWriter, test1, 3, "return 1;");
    MethodNode test2 = cls.searchMethodByName("test2(I)I");
    checkLine(lines, codeWriter, test2, 3, "return v - 1;");
//		TODO:
//		MethodNode test3 = cls.searchMethodByName("test3(I)I");
//		checkLine(lines, codeWriter, test3, 3, "return v;");
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) MethodNode(jadx.core.dex.nodes.MethodNode) CodeWriter(jadx.core.codegen.CodeWriter) IntegrationTest(jadx.tests.api.IntegrationTest) Test(org.junit.Test)

Example 15 with MethodNode

use of jadx.core.dex.nodes.MethodNode in project jadx by skylot.

the class TestDuplicateCast method test.

@Test
public void test() {
    dontUnloadClass();
    ClassNode cls = getClassNode(TestCls.class);
    MethodNode mth = getMethod(cls, "method");
    String code = cls.getCode().toString();
    assertThat(code, containsString("return (int[]) o;"));
    List<InsnNode> insns = mth.getBasicBlocks().get(1).getInstructions();
    assertEquals(insns.size(), 1);
    InsnNode insnNode = insns.get(0);
    assertEquals(InsnType.RETURN, insnNode.getType());
    assertTrue(insnNode.getArg(0).isInsnWrap());
    InsnNode wrapInsn = ((InsnWrapArg) insnNode.getArg(0)).getWrapInsn();
    assertEquals(InsnType.CHECK_CAST, wrapInsn.getType());
    assertFalse(wrapInsn.getArg(0).isInsnWrap());
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) InsnNode(jadx.core.dex.nodes.InsnNode) MethodNode(jadx.core.dex.nodes.MethodNode) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Test(org.junit.Test) IntegrationTest(jadx.tests.api.IntegrationTest)

Aggregations

MethodNode (jadx.core.dex.nodes.MethodNode)27 ClassNode (jadx.core.dex.nodes.ClassNode)12 FieldNode (jadx.core.dex.nodes.FieldNode)9 MethodInfo (jadx.core.dex.info.MethodInfo)7 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)7 InsnNode (jadx.core.dex.nodes.InsnNode)7 ClassInfo (jadx.core.dex.info.ClassInfo)5 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)5 BlockNode (jadx.core.dex.nodes.BlockNode)5 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)4 ArgType (jadx.core.dex.instructions.args.ArgType)4 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)4 ArrayList (java.util.ArrayList)4 FieldInfo (jadx.core.dex.info.FieldInfo)3 InsnArg (jadx.core.dex.instructions.args.InsnArg)3 IRegion (jadx.core.dex.nodes.IRegion)3 IntegrationTest (jadx.tests.api.IntegrationTest)3 HashSet (java.util.HashSet)3 Test (org.junit.Test)3 EnumClassAttr (jadx.core.dex.attributes.nodes.EnumClassAttr)2