Skip to content

Classloader mixin

metall0id edited this page Nov 25, 2014 · 2 revisions

The ClassLoader Mixin allows you to write snippets of Java code to be run in the context of the drozer Agent. This allows you to write parts of your module avoiding the overhead of using the reflection interface.

Writing a Java Snippet

Compiling for Android

We use a Makefile to compile Java sources into APK files for drozer:

NATIVES = $(shell find . -name Android.mk)
SOURCES = $(shell find . -name *.java)

DX = dx
JAVAC = javac
NDKBUILD = ndk-build
PYTHON = python

apks: $(SOURCES:.java=.apk)
clean:
	rm -f $(SOURCES:.java=.class) $(SOURCES:.java=.apk)
native-libraries: $(NATIVES)

%.apk: %.class
	cd $(dir $^); $(DX) --dex --output=$(notdir $(^:.class=.apk) $(^:.class=*.class))
%.class: %.java
	cd $(dir $^); $(JAVAC) -cp $(SDK) $(notdir $^)
%.mk: force
	cd $(dir $@); $(NDKBUILD)

force: ;

Save this as Makefile in the root of your working module repository.

This provides two targets:

  • make apks: builds an APK files for every Java source file under the working directory; and
  • make native-libraries: builds native libraries (normally .so files) by building every Android.mk file under the working directory with ndk-build.

Before you can use the Makefile to compile a Java source, you need to ensure that a few executables are on your PATH:

  • dx: from the Android SDK
  • javac: the Java 1.6 compiler

and also that the following environment variables are set:

  • SDK as /path/to/android-sdk/platforms/android-17/android.jar

Then, simply run make apks in the root of your working module repository.

Using the Snippet in drozer

drozer automatically manages versions of your Java Snippet. It guarantees to use the latest APK file available, uploading it to the Agent at runtime if necessary.

To use the class loader, you must include the mixin in your module:

class MyModule(Module, common.ClassLoader):
    
    def execute(self, arguments):
        pass

In your execute() method, you can now load the class defined in your APK file:

  def execute(self, arguments):
      MyClass = self.context.loadClass("MyClass.apk", "MyClass", relative_to=__file__)

If successful, you will now have a Class<?> object reference in MyClass that you can use to instantiate your custom Java class:

      my_object = self.new(MyClass)

By default, drozer searches for APK files in the root of its internal module repository (so common/ZipUtil.apk will guarantee to give you the Zip-archive utility in all modules). By specifying relative_to=__file__, you instruct drozer to treat the APK path relative to the current Python module.

Clone this wiki locally