I'm writing an instrumentation library that I'd like to work on both desktop and mobile (Android).
It functions by:
Like so:
// Expects args[0] to contain the name of the INNER main
public static void main(String[] args) throws Throwable {
String className = args[0];
String [] newArgs = new String[0];
if(args.length > 1) {
newArgs = Arrays.copyOfRange(args, 1, args.length-1);
}
System.out.println("Bootstrapping " + className);
Loader s = new Loader(ClassLoader.getSystemClassLoader().getParent());
Class<?> c = s.loadClass(className);
c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(
null, new Object[] { newArgs });
}
The question is this:
How can I do roughly the same thing for an android app?
One idea is to modify the android manifest to replace the existing activities with "wrapper" activities, that then install class loaders and call into the original underlying activity. Is there a better way?
To create a custom class loader, we will create a class that will extend ClassLoader. There is a method findClass() that must be overridden. Create a method that will load your given class from the class path. In our case we have created the method loadClassData() that will return byte[].
Java uses ClassLoader implicitly when you use new , import keyword, the jvm will use the current class's classloader to load the dependent classes, so you can use the custom classloader to load a bootstrap class explicitly by using classloader.
A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class.
We will create our own ClassLoader by extending the ClassLoader class and overriding the loadClass(String name) method. If the class name will start from com. journaldev then we will load it using our custom class loader or else we will invoke the parent ClassLoader loadClass() method to load the class.
There is a project called droidbox to detect android malware. There is a code that can help you a lot.
package com.loader;
import dalvik.system.DexClassLoader;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class LoaderActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DexClassLoader dLoader = new DexClassLoader("/sdcard/DroidBoxTests.apk","/sdcard/", null, ClassLoader.getSystemClassLoader().getParent());
Class calledClass = null;
try {
calledClass = dLoader.loadClass("droidbox.tests.DroidBoxTests");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent it=new Intent(this, calledClass);
it.setClassName("droidbox.tests", "droidbox.tests.DroidBoxTests");
startActivity(it);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With