Skip to content

Using Reflection

metall0id edited this page Nov 26, 2014 · 5 revisions

The Module execute() method has seamless access to the Dalvik VM on the Android device, through reflection. This allows the module to instantiate and interact with Java objects as if they were available locally.

To instantiate an object, use the new() method:

my_object = self.new("some.package.MyClass")

You will have a handle for the instantiated object in my_object, which you can use like the Java object:

my_object.some_field                #=> returns the value in some_field
my_object.aMethod()                 #=> invokes the aMethod() method, and returns the return value
my_object.aMethod("with arguments") #=> invokes the overloaded version of aMethod() that accepts a String
                                    #   argument

You may pass arguments to the constructor by appending them to the invocation of new():

my_object = self.new("some.package.MyClass", "with string")

You can also get a handle on a class to interact with static methods and fields, or to instantiate it manually:

my_klass = self.klass("some.package.MyClass")
my_object = self.new(my_klass)

If you want to instantiate a static class, you must use its fully-qualified Java name. For instance, consider the following:

package com.myapp.somepackage

class MyClass {

  public static class MyOtherClass { }

}

You must use com.my.app.somepackage.MyClass$MyOtherClass to resolve the static class.

All class and object handles that your module collects are invalidated when the execute() method returns.

Dealing with Returned Types

When a reflected method or property returns a value, drozer tries to handle it seamlessly as both a reflected and a native type.

Objects

An Object can be used exactly as an object instantiated through reflection: its properties and methods can be accessed and invoked.

Primitives

A primitive will be encapsulated as a ReflectedPrimitive in your module. This should behave exactly as the native type.

However, this feature is not perfect yet. If you have difficulty interacting with the ReflectedPrimitive type, you can access its _native property to get the raw Python datatype.

Arrays

An array will be encapsulated as a ReflectedArray. This mirrors the interface of a native Python list, and allows you to iterate through the elements and use indices to access individual elements.

Handling Exceptions

If the executed Java throws an exception, it will be propogated back into your module as a ReflectionException (from the package pydiesel.reflection.reflection).

If uncaught, the drozer runtime will intercept this exception, print it to screen and terminate your module’s execution.

When developing a module, it helps to pass the --debug option to the console as you launch it, this will give you a full stack trace detailing where the exception was triggered.

Loading an entire Java Class from file

See the Classloader mixin