ImmutableMethod meth = new ImmutableMethod(classType, sm.getName(), parameters, returnType, accessFlags, buildMethodAnnotations(sm), impl); methods.add(meth);
@Nonnull private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name, @Nonnull String params, @Nonnull String returnType) { ImmutableList<ImmutableMethodParameter> paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params)); return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null); }
@Nonnull private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name, @Nonnull String params, @Nonnull String returnType) { ImmutableList<ImmutableMethodParameter> paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params)); return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null); }
@Nonnull private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name, @Nonnull String params, @Nonnull String returnType) { ImmutableList<ImmutableMethodParameter> paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params)); return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null); }
return new ImmutableMethod(className, methodName, methodParams, methodRet, accessFlags, null, null);
return new ImmutableMethod(className, methodName, methodParams, methodRet, accessFlags, null, null);
private static List<Method> reDexMethods(@Nonnull ClassDef classDef) { List<Method> taintedMethods = Lists.newArrayList(); for (Method method : classDef.getMethods()) { MethodImplementation implementation = method.getImplementation(); MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation); taintedMethods.add(new ImmutableMethod( method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), mutableImplementation)); } return taintedMethods; }
public static ImmutableMethod of(Method method) { if (method instanceof ImmutableMethod) { return (ImmutableMethod)method; } return new ImmutableMethod( method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), method.getImplementation()); }
public static ImmutableMethod of(Method method) { if (method instanceof ImmutableMethod) { return (ImmutableMethod)method; } return new ImmutableMethod( method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), method.getImplementation()); }
public static ImmutableMethod of(Method method) { if (method instanceof ImmutableMethod) { return (ImmutableMethod)method; } return new ImmutableMethod( method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), method.getImplementation()); }
@Test public void testCustomMethodInlineTable_Virtual() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PUBLIC.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, null, ImmutableList.of(method)); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_VIRTUAL, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); }
@Test public void testCustomMethodInlineTable_Static() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.STATIC.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_STATIC, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); }
@Test public void testCustomMethodInlineTable_Direct() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PRIVATE.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_DIRECT, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); } }
@Test public void should_remove_final_modifier_from_the_given_method() throws IOException { ImmutableMethod method = new ImmutableMethod("Lfoo/Bar;", "f", null, "V", AccessFlags.FINAL.getValue(), null, null); ImmutableClassDef def = new ImmutableClassDef("Lfoo/Bar;", 0, "Ljava/lang/Object;", null, null, null, null, Collections.singleton(method)); byte[] bytecode = DexPoolUtils.toBytecode(new ImmutableDexFile(Opcodes.getDefault(), Collections.singleton(def))); DexRewriter rewriter = new DexRewriter(new FinalModifierRemoverModule()); Method out = rewriter.getMethodRewriter() .rewrite(new DexBackedDexFile(null, bytecode) .getClasses() .iterator() .next() .getVirtualMethods() .iterator() .next()); assertFalse(AccessFlags.FINAL.isSet(out.getAccessFlags())); }
@Test public void testPoolCallSite() throws IOException { ClassDef class1 = new ImmutableClassDef("Lcls1;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Lists.<Method>newArrayList( new ImmutableMethod("Lcls1", "method1", ImmutableList.of(), "V", AccessFlags.PUBLIC.getValue(), null, new ImmutableMethodImplementation(10, ImmutableList.of( new ImmutableInstruction35c(Opcode.INVOKE_CUSTOM, 0, 0, 0, 0, 0, 0, new ImmutableCallSiteReference("call_site_1", new ImmutableMethodHandleReference(MethodHandleType.INVOKE_STATIC, new ImmutableMethodReference("Lcls1", "loader", ImmutableList.of("Ljava/lang/invoke/Lookup;", "Ljava/lang/String;", "Ljava/lang/invoke/MethodType;"), "Ljava/lang/invoke/CallSite;")), "someMethod", new ImmutableMethodProtoReference(ImmutableList.of(), "V"), ImmutableList.of())) ), null, null)))); File tempFile = File.createTempFile("dex", ".dex"); DexFileFactory.writeDexFile(tempFile.getPath(), new ImmutableDexFile(Opcodes.forArtVersion(111), ImmutableList.of(class1))); verifyDexFile(DexFileFactory.loadDexFile(tempFile, Opcodes.forArtVersion(111))); }
@Test public void testInstanceOfNarrowingEqz_art() throws IOException { MethodImplementationBuilder builder = new MethodImplementationBuilder(2); builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;"))); builder.addInstruction(new BuilderInstruction21t(Opcode.IF_EQZ, 0, builder.getLabel("not_instance_of"))); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); builder.addLabel("not_instance_of"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation methodImplementation = builder.getMethodImplementation(); Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, methodImplementation); ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method)); DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef)); ClassPath classPath = new ClassPath(Lists.newArrayList(new DexClassProvider(dexFile)), true, 56); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false); List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions(); Assert.assertEquals("Lmain;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType()); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType()); }
@Test public void testInstanceOfNarrowingNez_art() throws IOException { MethodImplementationBuilder builder = new MethodImplementationBuilder(2); builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;"))); builder.addInstruction(new BuilderInstruction21t(Opcode.IF_NEZ, 0, builder.getLabel("instance_of"))); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); builder.addLabel("instance_of"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation methodImplementation = builder.getMethodImplementation(); Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, methodImplementation); ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method)); DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef)); ClassPath classPath = new ClassPath(Lists.newArrayList(new DexClassProvider(dexFile)), true, 56); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false); List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions(); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType()); Assert.assertEquals("Lmain;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType()); }
@Test public void testInstanceOfNarrowingAfterMove_art() throws IOException { MethodImplementationBuilder builder = new MethodImplementationBuilder(3); builder.addInstruction(new BuilderInstruction12x(Opcode.MOVE_OBJECT, 1, 2)); builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;"))); builder.addInstruction(new BuilderInstruction21t(Opcode.IF_EQZ, 0, builder.getLabel("not_instance_of"))); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); builder.addLabel("not_instance_of"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation methodImplementation = builder.getMethodImplementation(); Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, methodImplementation); ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method)); DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef)); ClassPath classPath = new ClassPath(Lists.newArrayList(new DexClassProvider(dexFile)), true, 56); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false); List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions(); Assert.assertEquals("Lmain;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType()); Assert.assertEquals("Lmain;", analyzedInstructions.get(3).getPreInstructionRegisterType(2).type.getType()); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(4).getPreInstructionRegisterType(1).type.getType()); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(4).getPreInstructionRegisterType(2).type.getType()); }
@Test public void testInstanceOfNarrowingEqz_dalvik() throws IOException { MethodImplementationBuilder builder = new MethodImplementationBuilder(2); builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;"))); builder.addInstruction(new BuilderInstruction21t(Opcode.IF_EQZ, 0, builder.getLabel("not_instance_of"))); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); builder.addLabel("not_instance_of"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation methodImplementation = builder.getMethodImplementation(); Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, methodImplementation); ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method)); DexFile dexFile = new ImmutableDexFile(Opcodes.forApi(19), Collections.singletonList(classDef)); ClassPath classPath = new ClassPath(new DexClassProvider(dexFile)); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false); List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions(); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType()); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType()); }
@Test public void testInstanceOfNarrowingNez_dalvik() throws IOException { MethodImplementationBuilder builder = new MethodImplementationBuilder(2); builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;"))); builder.addInstruction(new BuilderInstruction21t(Opcode.IF_NEZ, 0, builder.getLabel("instance_of"))); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); builder.addLabel("instance_of"); builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID)); MethodImplementation methodImplementation = builder.getMethodImplementation(); Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, methodImplementation); ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method)); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), Collections.singletonList(classDef)); ClassPath classPath = new ClassPath(new DexClassProvider(dexFile)); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false); List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions(); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType()); Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType()); }