Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Breaking the Android ClassLoader

Breaking the Android ClassLoader

ClassLoaders are not new. They've existed since Java 1.0 and are a core part of how the JVM works. Things work a bit different under the hood in Android, but the core principles are the same and we, as Android developers, largely take it for granted. This talk will be a deep dive into how class loading works in Android and later explore the implications of trying to manipulate the application's ClassLoader at runtime (for better or worse 🔥) in the context of logging, hot fixing, adding features, and interacting with 3rd party code.

Sample project: https://github.com/hzsweers/blackmirror

85a1166e93654865b4dcafdafe2b2dfd?s=128

Zac Sweers

August 28, 2018
Tweet

More Decks by Zac Sweers

Other Decks in Programming

Transcript

  1. Breaking the Android ClassLoader Zac Sweers @pandanomic Photo by Vitalis

    Hirschmann on Unsplash
  2. ClassLoader

  3. class ClassLoader

  4. class ClassLoader {a Class<?> loadClass(String name); Class<?> findClass(String name); Class<?>

    defineClass(...); URL getResource(String name); // A few others }a
  5. class ClassLoader {a Class<?> loadClass(String name); Class<?> findClass(String name); Class<?>

    defineClass(...); URL getResource(String name); // A few others }a
  6. class URLClassLoader {a Class<?> loadClass(String name) { // Go fetch

    them from a jar }a }a
  7. class URLClassLoader {a Class<?> loadClass(String name) { // Go fetch

    them from a jar }a }a
  8. class URLClassLoader {a Class<?> loadClass(String name) { // Go fetch

    them from a jar }a }a
  9. class URLClassLoader {a // ClassLoader parent Class<?> loadClass(String name) }a

  10. class URLClassLoader {a // ClassLoader parent Class<?> loadClass(String name) }a

  11. Class<?> loadClass(String name)

  12. package example; class Foo { private Bar bar; }a

  13. package example; class Foo { private Bar bar; }a loadClass("example.Foo")

  14. package example; class Foo { private Bar bar; }a loadClass("example.Foo")

    Foo.class.getClassLoader().loadClass("example.Bar")
  15. None
  16. class PathClassLoader

  17. class PathClassLoader class DexClassLoader

  18. class PathClassLoader extends BaseDexClassLoader class DexClassLoader extends BaseDexClassLoader

  19. class BaseDexClassLoader {a DexPathList pathList }a

  20. class BaseDexClassLoader {a DexPathList pathList // --> DexFile, etc }a

  21. class BaseDexClassLoader {a DexPathList pathList // --> DexFile, etc }a

  22. Story time!

  23. None
  24. None
  25. None
  26. PathClassLoader classLoader = new PathClassLoader( context.getApplicationInfo().sourceDir, /* parent */ null

    );
  27. class CustomClassLoader extends PathClassLoader

  28. class CustomClassLoader extends PathClassLoader { @Override public Class<?> loadClass(String name)

    { Log.d("ClLoading", "Loading " + name); return super.loadClass(name); } }
  29. CustomClassLoader cl = new CustomClassLoader(...);

  30. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader

  31. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader Thread.currentThread().setContextClassLoader(cl)

  32. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader Thread.currentThread().setContextClassLoader(cl) ContextImpl

  33. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader Thread.currentThread().setContextClassLoader(cl) ContextImpl.mClassLoader

  34. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader Thread.currentThread().setContextClassLoader(cl) ContextImpl

  35. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader Thread.currentThread().setContextClassLoader(cl) ContextImpl.mPackageInfo

  36. CustomClassLoader cl = new CustomClassLoader(...); // set java.lang.ClassLoader$SystemClassLoader.loader Thread.currentThread().setContextClassLoader(cl) ContextImpl.mPackageInfo.mClassLoader

  37. None
  38. BlackM irro r

  39. Demo time!

  40. github.com/hzsweers/ blackmirror

  41. Final notes

  42. Harder in Pie g.co/dev/appcompat

  43. Be mindful

  44. github.com/hzsweers/ blackmirror Zac Sweers @pandanomic