From 555c1e72fb7f910773fe9a49821766343aed8ed2 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Wed, 2 Apr 2025 16:31:27 +0200 Subject: [PATCH] add DelegateLast class loaders --- .../theseus/dynloading/MainActivity.java | 176 +++++++++++++++++- 1 file changed, 175 insertions(+), 1 deletion(-) diff --git a/test_apks/dynloading/java/classes/com/example/theseus/dynloading/MainActivity.java b/test_apks/dynloading/java/classes/com/example/theseus/dynloading/MainActivity.java index ef1480b..78dc981 100644 --- a/test_apks/dynloading/java/classes/com/example/theseus/dynloading/MainActivity.java +++ b/test_apks/dynloading/java/classes/com/example/theseus/dynloading/MainActivity.java @@ -27,6 +27,7 @@ import java.io.FileOutputStream; import java.lang.reflect.InvocationTargetException; import android.content.Context; import dalvik.system.PathClassLoader; +import dalvik.system.DelegateLastClassLoader; import java.lang.reflect.Method; import com.example.theseus.Utils; @@ -105,6 +106,22 @@ public class MainActivity extends Activity { b4.generateViewId(); linLayout.addView(b4); + Button b5 = new Button(this); + b5.generateViewId(); + linLayout.addView(b5); + + Button b6 = new Button(this); + b6.generateViewId(); + linLayout.addView(b6); + + Button b7 = new Button(this); + b7.generateViewId(); + linLayout.addView(b7); + + Button b8 = new Button(this); + b8.generateViewId(); + linLayout.addView(b8); + scrollView.addView(linLayout); relLayout.addView(scrollView); @@ -159,8 +176,57 @@ public class MainActivity extends Activity { } } }); + b5.setText("Direct DelegateLastClassLoader With Parent"); + b5.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + v.setBackgroundTintList(buttonColor); + try { + directWithParentDelegateLast (); + } catch(Exception e) { + Log.e("THESEUS", "Error: ", e); + } + } + }); + + b6.setText("Direct DelegateLastClassLoader Without Parent"); + b6.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + v.setBackgroundTintList(buttonColor); + try { + directWithoutParentDelegateLast (); + } catch(Exception e) { + Log.e("THESEUS", "Error: ", e); + } + } + }); + + b7.setText("Indirect DelegateLastClassLoader With Parent"); + b7.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + v.setBackgroundTintList(buttonColor); + try { + indirectWithParentDelegateLast (); + } catch(Exception e) { + Log.e("THESEUS", "Error: ", e); + } + } + }); + + b8.setText("Indirect DelegateLastClassLoader Without Parent"); + b8.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + v.setBackgroundTintList(buttonColor); + try { + indirectWithoutParentDelegateLast (); + } catch(Exception e) { + Log.e("THESEUS", "Error: ", e); + } + } + }); } + // ------ PATH CLASS LOADER ------ + public void directWithParent() { try { PathClassLoader cl = new PathClassLoader(getdexfile("a.dex"), MainActivity.class.getClassLoader()); @@ -195,7 +261,6 @@ public class MainActivity extends Activity { Method mth = clz.getMethod("getColliderId"); String id = (String)mth.invoke(null); //Utils.popup(this, "Result", id); - Utils.popup(this, "TEST", clz.descriptorString()); String expectedId = "A"; if (id.equals(expectedId)) { Utils.popup(this, "OK", "The right class was loaded: " + id); @@ -269,4 +334,113 @@ public class MainActivity extends Activity { Log.e("DEBUG", "ERROR: ", e); } } + + // ------ DELEGATE LAST CLASSlOADER ------ + public void directWithParentDelegateLast() { + try { + DelegateLastClassLoader cl = new DelegateLastClassLoader(getdexfile("a.dex"), MainActivity.class.getClassLoader()); + Class clz = cl.loadClass("com.example.theseus.dynloading.Collider"); + Method mth = clz.getMethod("getColliderId"); + String id = (String)mth.invoke(null); + //Utils.popup(this, "Result", id); + String expectedId = "A"; + if (id.equals(expectedId)) { + Utils.popup(this, "OK", "The right class was loaded: " + id); + } else { + Utils.popup(this, "BAD", "The wrong class was loaded: id = " + id + " expected id = " + expectedId); + } + } catch (ClassNotFoundException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (NoSuchMethodException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (IllegalAccessException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (InvocationTargetException e) { + Log.e("DEBUG", "ERROR: ", e); + } + } + + public void directWithoutParentDelegateLast() { + try { + DelegateLastClassLoader cl = new DelegateLastClassLoader(getdexfile("a.dex"), null); + Class clz = cl.loadClass("com.example.theseus.dynloading.Collider"); + Method mth = clz.getMethod("getColliderId"); + String id = (String)mth.invoke(null); + //Utils.popup(this, "Result", id); + String expectedId = "A"; + if (id.equals(expectedId)) { + Utils.popup(this, "OK", "The right class was loaded: " + id); + } else { + Utils.popup(this, "BAD", "The wrong class was loaded: id = " + id + " expected id = " + expectedId); + } + } catch (ClassNotFoundException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (NoSuchMethodException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (IllegalAccessException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (InvocationTargetException e) { + Log.e("DEBUG", "ERROR: ", e); + } + } + + public void indirectWithParentDelegateLast() { + try { + DelegateLastClassLoader cl = new DelegateLastClassLoader(getdexfile("a.dex"), MainActivity.class.getClassLoader()); + Class clz = cl.loadClass("com.example.theseus.dynloading.AMain"); + Method mth = clz.getMethod("getColliderId"); + String id = (String)mth.invoke(null); + //Utils.popup(this, "Result", id); + String expectedId = "A"; + if (id.equals(expectedId)) { + Utils.popup(this, "OK", "The right class was loaded: " + id); + } else { + Utils.popup(this, "BAD", "The wrong class was loaded: id = " + id + " expected id = " + expectedId); + } + } catch (ClassNotFoundException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (NoSuchMethodException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (IllegalAccessException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (InvocationTargetException e) { + Log.e("DEBUG", "ERROR: ", e); + } + } + + public void indirectWithoutParentDelegateLast() { + try { + DelegateLastClassLoader cl = new DelegateLastClassLoader(getdexfile("a.dex"), null); + Class clz = cl.loadClass("com.example.theseus.dynloading.AMain"); + Method mth = clz.getMethod("getColliderId"); + String id = (String)mth.invoke(null); + //Utils.popup(this, "Result", id); + String expectedId = "A"; + if (id.equals(expectedId)) { + Utils.popup(this, "OK", "The right class was loaded: " + id); + } else { + Utils.popup(this, "BAD", "The wrong class was loaded: id = " + id + " expected id = " + expectedId); + } + } catch (ClassNotFoundException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (NoSuchMethodException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (IllegalAccessException e) { + Log.e("DEBUG", "ERROR: ", e); + } + catch (InvocationTargetException e) { + Log.e("DEBUG", "ERROR: ", e); + } + } }