diff --git a/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/Collider.java b/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/Collider.java index d9eb741..6ea1d42 100644 --- a/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/Collider.java +++ b/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/Collider.java @@ -1,7 +1,62 @@ package com.example.theseus.dynandref; -public class Collider { +public class Collider extends PCollider implements ICollider { public static String getColliderId() { return "A"; } + public String virtTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return getColliderId() + ":" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } + public static String staticTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return getColliderId() + ":" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } + + public String interTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return getColliderId() + ":" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } } diff --git a/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/ICollider.java b/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/ICollider.java new file mode 100644 index 0000000..d4a832e --- /dev/null +++ b/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/ICollider.java @@ -0,0 +1,35 @@ +package com.example.theseus.dynandref; + +public interface ICollider { + public String interTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ); + + default public String staticInterfaceTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return "MainAPK:" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } +} diff --git a/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/PCollider.java b/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/PCollider.java new file mode 100644 index 0000000..3f8ab2d --- /dev/null +++ b/test_apks/dyn_and_ref/java/a/com/example/theseus/dynandref/PCollider.java @@ -0,0 +1,22 @@ +package com.example.theseus.dynandref; + +public class PCollider { + public String extendedTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return "A:" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } +} diff --git a/test_apks/dyn_and_ref/java/classes/com/example/theseus/Utils.java b/test_apks/dyn_and_ref/java/classes/com/example/theseus/Utils.java index 09006b6..737bade 100644 --- a/test_apks/dyn_and_ref/java/classes/com/example/theseus/Utils.java +++ b/test_apks/dyn_and_ref/java/classes/com/example/theseus/Utils.java @@ -12,9 +12,6 @@ public class Utils { public static String source() { return "Secret"; } - public static String source(String tag) { - return "[" + tag + "] Secret"; - } public static void popup(Activity ac, String title, String msg) { Log.e("THESEUS", "POPUP, title: " + title + ", msg: " + msg); diff --git a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Collider.java b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Collider.java index 4772963..c601885 100644 --- a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Collider.java +++ b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Collider.java @@ -1,7 +1,62 @@ package com.example.theseus.dynandref; -public class Collider { +public class Collider extends PCollider implements ICollider { public static String getColliderId() { return "MainAPK"; } + public String virtTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return getColliderId() + ":" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } + public static String staticTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return getColliderId() + ":" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } + + public String interTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return getColliderId() + ":" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } } diff --git a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/ICollider.java b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/ICollider.java new file mode 100644 index 0000000..d4a832e --- /dev/null +++ b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/ICollider.java @@ -0,0 +1,35 @@ +package com.example.theseus.dynandref; + +public interface ICollider { + public String interTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ); + + default public String staticInterfaceTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return "MainAPK:" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } +} diff --git a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Main.java b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Main.java new file mode 100644 index 0000000..ffdfc85 --- /dev/null +++ b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/Main.java @@ -0,0 +1,101 @@ +package com.example.theseus.dynandref; + +import android.app.Activity; +import android.util.Log; +import java.lang.ClassLoader; +import dalvik.system.PathClassLoader; +import dalvik.system.InMemoryDexClassLoader; +import dalvik.system.DexClassLoader; +import dalvik.system.DelegateLastClassLoader; +import java.io.File; +import java.io.FileInputStream; +import java.nio.ByteBuffer; +import java.lang.reflect.Method; +import com.example.theseus.Utils; + +public class Main { + + public static String getdexfile(Activity ac, String name) throws Exception { + File dexfile = new File(ac.getCacheDir(), name); + dexfile.setReadOnly(); + Log.e("DEBUG", dexfile.getPath()); + return dexfile.getPath(); + } + + public static ByteBuffer getdexbuffer(Activity ac, String name) throws Exception { + File dexfile = new File(ac.getCacheDir(), name); + FileInputStream in = new FileInputStream(dexfile); + byte[] data = in.readAllBytes(); + return ByteBuffer.wrap(data); + } + + public static void run(Activity ac, String clname, boolean isDirect, boolean hasParent, String methodType) { + try { + ClassLoader cl; + ClassLoader parent; + if (hasParent) { + parent = Main.class.getClassLoader(); + } else { + parent = null; + } + if (clname.equals("DelegateLastClassLoader")) { + cl = new DelegateLastClassLoader(getdexfile(ac, "a.dex"), parent); + } else if (clname.equals("DexClassLoader")) { + cl = new DexClassLoader(getdexfile(ac, "a.dex"), null, null, parent); + } else if (clname.equals("InMemoryDexClassLoader")) { + cl = new InMemoryDexClassLoader(getdexbuffer(ac, "a.dex"), parent); + } else if (clname.equals("PathClassLoader")) { + cl = new PathClassLoader(getdexfile(ac, "a.dex"), parent); + } else { + cl = Main.class.getClassLoader(); + } + + Class clz = cl.loadClass("com.example.theseus.dynandref.Collider"); + Object[] args = { + true, + (byte)42, + (short)666, + '*', + 0xDEAD_BEEF, + 0xD1AB011C_5EAF00DL, + 0.99f, + 3.1415926535897932384626433d, + "", + new String[] {"some", "strings"} + }; + + if (methodType.equals("Virtual")) { + Method mth = clz.getMethod("virtTransfer", boolean.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, String.class, String[].class); + Object instance = clz.getDeclaredConstructor().newInstance(); + invoke(ac, instance, mth, args); + } else if (methodType.equals("Static")) { + Method mth = clz.getMethod("staticTransfer", boolean.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, String.class, String[].class); + invoke(ac, null, mth, args); + } else if (methodType.equals("Extended")) { + Method mth = clz.getMethod("extendedTransfer", boolean.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, String.class, String[].class); + Object instance = clz.getDeclaredConstructor().newInstance(); + invoke(ac, instance, mth, args); + } else if (methodType.equals("Interface")) { + Method mth = clz.getMethod("interTransfer", boolean.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, String.class, String[].class); + Object instance = clz.getDeclaredConstructor().newInstance(); + invoke(ac, instance, mth, args); + } else if (methodType.equals("Interface Static")) { + clz = cl.loadClass("com.example.theseus.dynandref.ICollider$-CC"); + Method mth = clz.getMethod("staticInterfaceTransfer", boolean.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, String.class, String[].class); + invoke(ac, null, mth, args); + } else if (methodType.equals("Factory Pattern")) { + return; + } else { + return; + }; + } catch (Exception e) { + Log.e("THESEUS", "error:", e); + } + } + + public static void invoke(Activity ac, Object instance, Method mth, Object[] args) throws Exception { + args[8] = Utils.source(); + String res = (String)mth.invoke(instance, args); + Utils.sink(ac, res); + } +} diff --git a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/MethodActivity.java b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/MethodActivity.java index 3bd39f4..463ebb2 100644 --- a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/MethodActivity.java +++ b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/MethodActivity.java @@ -111,7 +111,7 @@ public class MethodActivity extends Activity { b1.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.setBackgroundTintList(buttonColor); - Utils.popup(ac, "MSG", classLoaderName + ", has parent:" + hasParent + ", direct: "+ isDirect + ", method: Virtual"); + Main.run(ac, classLoaderName, isDirect, hasParent, "Virtual"); } }); @@ -119,7 +119,7 @@ public class MethodActivity extends Activity { b2.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.setBackgroundTintList(buttonColor); - Utils.popup(ac, "MSG", classLoaderName + ", has parent:" + hasParent + ", direct: "+ isDirect + ", method: Static"); + Main.run(ac, classLoaderName, isDirect, hasParent, "Static"); } }); @@ -127,7 +127,7 @@ public class MethodActivity extends Activity { b3.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.setBackgroundTintList(buttonColor); - Utils.popup(ac, "MSG", classLoaderName + ", has parent:" + hasParent + ", direct: "+ isDirect + ", method: Extended"); + Main.run(ac, classLoaderName, isDirect, hasParent, "Extended"); } }); @@ -135,7 +135,7 @@ public class MethodActivity extends Activity { b4.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.setBackgroundTintList(buttonColor); - Utils.popup(ac, "MSG", classLoaderName + ", has parent:" + hasParent + ", direct: "+ isDirect + ", method: Interface"); + Main.run(ac, classLoaderName, isDirect, hasParent, "Interface"); } }); @@ -143,7 +143,7 @@ public class MethodActivity extends Activity { b5.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.setBackgroundTintList(buttonColor); - Utils.popup(ac, "MSG", classLoaderName + ", has parent:" + hasParent + ", direct: "+ isDirect + ", method: Interface Static"); + Main.run(ac, classLoaderName, isDirect, hasParent, "Interface Static"); } }); @@ -151,7 +151,7 @@ public class MethodActivity extends Activity { b6.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.setBackgroundTintList(buttonColor); - Utils.popup(ac, "MSG", classLoaderName + ", has parent:" + hasParent + ", direct: "+ isDirect + ", method: Factory Pattern"); + Main.run(ac, classLoaderName, isDirect, hasParent, "Factory Pattern"); } }); } diff --git a/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/PCollider.java b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/PCollider.java new file mode 100644 index 0000000..16a6116 --- /dev/null +++ b/test_apks/dyn_and_ref/java/classes/com/example/theseus/dynandref/PCollider.java @@ -0,0 +1,22 @@ +package com.example.theseus.dynandref; + +public class PCollider { + public String extendedTransfer( + boolean bool, + byte by, + short sh, + char ch, + int in, + long lo, + float fl, + double dou, + String str, + String... args + ) { + String val = ""; + for (String v : args) { + val += " " + v; + } + return "MainAPK:" + val + "(" + bool + " " + by + " " + sh + " " + ch + " " + in + " " + lo + " " + fl + " " + dou + " " + str + ")"; + } +}